aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/arcnet
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/arcnet
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/arcnet')
-rw-r--r--drivers/net/arcnet/Kconfig140
-rw-r--r--drivers/net/arcnet/Makefile14
-rw-r--r--drivers/net/arcnet/arc-rawmode.c204
-rw-r--r--drivers/net/arcnet/arc-rimi.c368
-rw-r--r--drivers/net/arcnet/arcnet.c1102
-rw-r--r--drivers/net/arcnet/capmode.c296
-rw-r--r--drivers/net/arcnet/com20020-isa.c219
-rw-r--r--drivers/net/arcnet/com20020-pci.c189
-rw-r--r--drivers/net/arcnet/com20020.c357
-rw-r--r--drivers/net/arcnet/com90io.c435
-rw-r--r--drivers/net/arcnet/com90xx.c646
-rw-r--r--drivers/net/arcnet/rfc1051.c253
-rw-r--r--drivers/net/arcnet/rfc1201.c549
13 files changed, 4772 insertions, 0 deletions
diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
new file mode 100644
index 000000000000..948de2532a1e
--- /dev/null
+++ b/drivers/net/arcnet/Kconfig
@@ -0,0 +1,140 @@
1#
2# Arcnet configuration
3#
4
5menu "ARCnet devices"
6 depends on NETDEVICES && (ISA || PCI)
7
8config ARCNET
9 tristate "ARCnet support"
10 ---help---
11 If you have a network card of this type, say Y and check out the
12 (arguably) beautiful poetry in
13 <file:Documentation/networking/arcnet.txt>.
14
15 You need both this driver, and the driver for the particular ARCnet
16 chipset of your card. If you don't know, then it's probably a
17 COM90xx type card, so say Y (or M) to "ARCnet COM90xx chipset
18 support" below.
19
20 You might also want to have a look at the Ethernet-HOWTO, available
21 from <http://www.tldp.org/docs.html#howto>(even though ARCnet
22 is not really Ethernet).
23
24 To compile this driver as a module, choose M here and read
25 <file:Documentation/networking/net-modules.txt>. The module will
26 be called arcnet.
27
28config ARCNET_1201
29 tristate "Enable standard ARCNet packet format (RFC 1201)"
30 depends on ARCNET
31 help
32 This allows you to use RFC1201 with your ARCnet card via the virtual
33 arc0 device. You need to say Y here to communicate with
34 industry-standard RFC1201 implementations, like the arcether.com
35 packet driver or most DOS/Windows ODI drivers. Please read the
36 ARCnet documentation in <file:Documentation/networking/arcnet.txt>
37 for more information about using arc0.
38
39config ARCNET_1051
40 tristate "Enable old ARCNet packet format (RFC 1051)"
41 depends on ARCNET
42 ---help---
43 This allows you to use RFC1051 with your ARCnet card via the virtual
44 arc0s device. You only need arc0s if you want to talk to ARCnet
45 software complying with the "old" standard, specifically, the DOS
46 arcnet.com packet driver, Amigas running AmiTCP, and some variants
47 of NetBSD. You do not need to say Y here to communicate with
48 industry-standard RFC1201 implementations, like the arcether.com
49 packet driver or most DOS/Windows ODI drivers. RFC1201 is included
50 automatically as the arc0 device. Please read the ARCnet
51 documentation in <file:Documentation/networking/arcnet.txt> for more
52 information about using arc0e and arc0s.
53
54config ARCNET_RAW
55 tristate "Enable raw mode packet interface"
56 depends on ARCNET
57 help
58 ARCnet "raw mode" packet encapsulation, no soft headers. Unlikely
59 to work unless talking to a copy of the same Linux arcnet driver,
60 but perhaps marginally faster in that case.
61
62config ARCNET_CAP
63 tristate "Enable CAP mode packet interface"
64 depends on ARCNET
65 help
66 ARCnet "cap mode" packet encapsulation. Used to get the hardware
67 acknowledge back to userspace. After the initial protocol byte every
68 packet is stuffed with an extra 4 byte "cookie" which doesn't
69 actually appear on the network. After transmit the driver will send
70 back a packet with protocol byte 0 containing the status of the
71 transmition:
72 0=no hardware acknowledge
73 1=excessive nak
74 2=transmition accepted by the reciever hardware
75
76 Received packets are also stuffed with the extra 4 bytes but it will
77 be random data.
78
79 Cap only listens to protocol 1-8.
80
81config ARCNET_COM90xx
82 tristate "ARCnet COM90xx (normal) chipset driver"
83 depends on ARCNET
84 help
85 This is the chipset driver for the standard COM90xx cards. If you
86 have always used the old ARCnet driver without knowing what type of
87 card you had, this is probably the one for you.
88
89 To compile this driver as a module, choose M here and read
90 <file:Documentation/networking/net-modules.txt>. The module will
91 be called com90xx.
92
93config ARCNET_COM90xxIO
94 tristate "ARCnet COM90xx (IO mapped) chipset driver"
95 depends on ARCNET
96 ---help---
97 This is the chipset driver for the COM90xx cards, using them in
98 IO-mapped mode instead of memory-mapped mode. This is slower than
99 the normal driver. Only use it if your card doesn't support shared
100 memory.
101
102 To compile this driver as a module, choose M here and read
103 <file:Documentation/networking/net-modules.txt>. The module will
104 be called com90io.
105
106config ARCNET_RIM_I
107 tristate "ARCnet COM90xx (RIM I) chipset driver"
108 depends on ARCNET
109 ---help---
110 This is yet another chipset driver for the COM90xx cards, but this
111 time only using memory-mapped mode, and no IO ports at all. This
112 driver is completely untested, so if you have one of these cards,
113 please mail <dwmw2@infradead.org>, especially if it works!
114
115 To compile this driver as a module, choose M here and read
116 <file:Documentation/networking/net-modules.txt>. The module will
117 be called arc-rimi.
118
119config ARCNET_COM20020
120 tristate "ARCnet COM20020 chipset driver"
121 depends on ARCNET
122 help
123 This is the driver for the new COM20020 chipset. It supports such
124 things as promiscuous mode, so packet sniffing is possible, and
125 extra diagnostic information.
126
127 To compile this driver as a module, choose M here and read
128 <file:Documentation/networking/net-modules.txt>. The module will
129 be called com20020.
130
131config ARCNET_COM20020_ISA
132 tristate "Support for COM20020 on ISA"
133 depends on ARCNET_COM20020 && ISA
134
135config ARCNET_COM20020_PCI
136 tristate "Support for COM20020 on PCI"
137 depends on ARCNET_COM20020 && PCI
138
139endmenu
140
diff --git a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile
new file mode 100644
index 000000000000..5861af543d42
--- /dev/null
+++ b/drivers/net/arcnet/Makefile
@@ -0,0 +1,14 @@
1# Makefile for linux/drivers/net/arcnet
2#
3
4obj-$(CONFIG_ARCNET) += arcnet.o
5obj-$(CONFIG_ARCNET_1201) += rfc1201.o
6obj-$(CONFIG_ARCNET_1051) += rfc1051.o
7obj-$(CONFIG_ARCNET_RAW) += arc-rawmode.o
8obj-$(CONFIG_ARCNET_CAP) += capmode.o
9obj-$(CONFIG_ARCNET_COM90xx) += com90xx.o
10obj-$(CONFIG_ARCNET_COM90xxIO) += com90io.o
11obj-$(CONFIG_ARCNET_RIM_I) += arc-rimi.o
12obj-$(CONFIG_ARCNET_COM20020) += com20020.o
13obj-$(CONFIG_ARCNET_COM20020_ISA) += com20020-isa.o
14obj-$(CONFIG_ARCNET_COM20020_PCI) += com20020-pci.o
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
new file mode 100644
index 000000000000..e1ea29b0cd14
--- /dev/null
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -0,0 +1,204 @@
1/*
2 * Linux ARCnet driver - "raw mode" packet encapsulation (no soft headers)
3 *
4 * Written 1994-1999 by Avery Pennarun.
5 * Derived from skeleton.c by Donald Becker.
6 *
7 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
8 * for sponsoring the further development of this driver.
9 *
10 * **********************
11 *
12 * The original copyright of skeleton.c was as follows:
13 *
14 * skeleton.c Written 1993 by Donald Becker.
15 * Copyright 1993 United States Government as represented by the
16 * Director, National Security Agency. This software may only be used
17 * and distributed according to the terms of the GNU General Public License as
18 * modified by SRC, incorporated herein by reference.
19 *
20 * **********************
21 *
22 * For more details, see drivers/net/arcnet.c
23 *
24 * **********************
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/if_arp.h>
30#include <net/arp.h>
31#include <linux/netdevice.h>
32#include <linux/skbuff.h>
33#include <linux/arcdevice.h>
34
35#define VERSION "arcnet: raw mode (`r') encapsulation support loaded.\n"
36
37
38static void rx(struct net_device *dev, int bufnum,
39 struct archdr *pkthdr, int length);
40static int build_header(struct sk_buff *skb, struct net_device *dev,
41 unsigned short type, uint8_t daddr);
42static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
43 int bufnum);
44
45struct ArcProto rawmode_proto =
46{
47 .suffix = 'r',
48 .mtu = XMTU,
49 .rx = rx,
50 .build_header = build_header,
51 .prepare_tx = prepare_tx,
52 .continue_tx = NULL,
53 .ack_tx = NULL
54};
55
56
57static int __init arcnet_raw_init(void)
58{
59 int count;
60
61 printk(VERSION);
62
63 for (count = 0; count < 256; count++)
64 if (arc_proto_map[count] == arc_proto_default)
65 arc_proto_map[count] = &rawmode_proto;
66
67 /* for raw mode, we only set the bcast proto if there's no better one */
68 if (arc_bcast_proto == arc_proto_default)
69 arc_bcast_proto = &rawmode_proto;
70
71 arc_proto_default = &rawmode_proto;
72 return 0;
73}
74
75static void __exit arcnet_raw_exit(void)
76{
77 arcnet_unregister_proto(&rawmode_proto);
78}
79
80module_init(arcnet_raw_init);
81module_exit(arcnet_raw_exit);
82
83MODULE_LICENSE("GPL");
84
85
86/* packet receiver */
87static void rx(struct net_device *dev, int bufnum,
88 struct archdr *pkthdr, int length)
89{
90 struct arcnet_local *lp = dev->priv;
91 struct sk_buff *skb;
92 struct archdr *pkt = pkthdr;
93 int ofs;
94
95 BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
96
97 if (length >= MinTU)
98 ofs = 512 - length;
99 else
100 ofs = 256 - length;
101
102 skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
103 if (skb == NULL) {
104 BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
105 lp->stats.rx_dropped++;
106 return;
107 }
108 skb_put(skb, length + ARC_HDR_SIZE);
109 skb->dev = dev;
110
111 pkt = (struct archdr *) skb->data;
112
113 skb->mac.raw = skb->data;
114 skb_pull(skb, ARC_HDR_SIZE);
115
116 /* up to sizeof(pkt->soft) has already been copied from the card */
117 memcpy(pkt, pkthdr, sizeof(struct archdr));
118 if (length > sizeof(pkt->soft))
119 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
120 pkt->soft.raw + sizeof(pkt->soft),
121 length - sizeof(pkt->soft));
122
123 BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
124
125 skb->protocol = __constant_htons(ETH_P_ARCNET);
126;
127 netif_rx(skb);
128 dev->last_rx = jiffies;
129}
130
131
132/*
133 * Create the ARCnet hard/soft headers for raw mode.
134 * There aren't any soft headers in raw mode - not even the protocol id.
135 */
136static int build_header(struct sk_buff *skb, struct net_device *dev,
137 unsigned short type, uint8_t daddr)
138{
139 int hdr_size = ARC_HDR_SIZE;
140 struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
141
142 /*
143 * Set the source hardware address.
144 *
145 * This is pretty pointless for most purposes, but it can help in
146 * debugging. ARCnet does not allow us to change the source address in
147 * the actual packet sent)
148 */
149 pkt->hard.source = *dev->dev_addr;
150
151 /* see linux/net/ethernet/eth.c to see where I got the following */
152
153 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
154 /*
155 * FIXME: fill in the last byte of the dest ipaddr here to better
156 * comply with RFC1051 in "noarp" mode.
157 */
158 pkt->hard.dest = 0;
159 return hdr_size;
160 }
161 /* otherwise, just fill it in and go! */
162 pkt->hard.dest = daddr;
163
164 return hdr_size; /* success */
165}
166
167
168static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
169 int bufnum)
170{
171 struct arcnet_local *lp = dev->priv;
172 struct arc_hardware *hard = &pkt->hard;
173 int ofs;
174
175 BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
176 lp->next_tx, lp->cur_tx, bufnum);
177
178 length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
179
180 if (length > XMTU) {
181 /* should never happen! other people already check for this. */
182 BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
183 length, XMTU);
184 length = XMTU;
185 }
186 if (length > MinTU) {
187 hard->offset[0] = 0;
188 hard->offset[1] = ofs = 512 - length;
189 } else if (length > MTU) {
190 hard->offset[0] = 0;
191 hard->offset[1] = ofs = 512 - length - 3;
192 } else
193 hard->offset[0] = ofs = 256 - length;
194
195 BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
196 length,ofs);
197
198 lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
199 lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
200
201 lp->lastload_dest = hard->dest;
202
203 return 1; /* done */
204}
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
new file mode 100644
index 000000000000..38c3f033f739
--- /dev/null
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -0,0 +1,368 @@
1/*
2 * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards
3 *
4 * Written 1994-1999 by Avery Pennarun.
5 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
6 * Derived from skeleton.c by Donald Becker.
7 *
8 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
9 * for sponsoring the further development of this driver.
10 *
11 * **********************
12 *
13 * The original copyright of skeleton.c was as follows:
14 *
15 * skeleton.c Written 1993 by Donald Becker.
16 * Copyright 1993 United States Government as represented by the
17 * Director, National Security Agency. This software may only be used
18 * and distributed according to the terms of the GNU General Public License as
19 * modified by SRC, incorporated herein by reference.
20 *
21 * **********************
22 *
23 * For more details, see drivers/net/arcnet.c
24 *
25 * **********************
26 */
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/ioport.h>
31#include <linux/slab.h>
32#include <linux/delay.h>
33#include <linux/netdevice.h>
34#include <linux/bootmem.h>
35#include <linux/init.h>
36#include <asm/io.h>
37#include <linux/arcdevice.h>
38
39
40#define VERSION "arcnet: RIM I (entirely mem-mapped) support\n"
41
42
43/* Internal function declarations */
44
45static int arcrimi_probe(struct net_device *dev);
46static int arcrimi_found(struct net_device *dev);
47static void arcrimi_command(struct net_device *dev, int command);
48static int arcrimi_status(struct net_device *dev);
49static void arcrimi_setmask(struct net_device *dev, int mask);
50static int arcrimi_reset(struct net_device *dev, int really_reset);
51static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
52 void *buf, int count);
53static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
54 void *buf, int count);
55
56/* Handy defines for ARCnet specific stuff */
57
58/* Amount of I/O memory used by the card */
59#define BUFFER_SIZE (512)
60#define MIRROR_SIZE (BUFFER_SIZE*4)
61
62/* COM 9026 controller chip --> ARCnet register addresses */
63#define _INTMASK (ioaddr+0) /* writable */
64#define _STATUS (ioaddr+0) /* readable */
65#define _COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
66#define _RESET (ioaddr+8) /* software reset (on read) */
67#define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */
68#define _ADDR_HI (ioaddr+15) /* Control registers for said */
69#define _ADDR_LO (ioaddr+14)
70#define _CONFIG (ioaddr+2) /* Configuration register */
71
72#undef ASTATUS
73#undef ACOMMAND
74#undef AINTMASK
75
76#define ASTATUS() readb(_STATUS)
77#define ACOMMAND(cmd) writeb((cmd),_COMMAND)
78#define AINTMASK(msk) writeb((msk),_INTMASK)
79#define SETCONF() writeb(lp->config,_CONFIG)
80
81
82/*
83 * We cannot probe for a RIM I card; one reason is I don't know how to reset
84 * them. In fact, we can't even get their node ID automatically. So, we
85 * need to be passed a specific shmem address, IRQ, and node ID.
86 */
87static int __init arcrimi_probe(struct net_device *dev)
88{
89 BUGLVL(D_NORMAL) printk(VERSION);
90 BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
91
92 BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n",
93 dev->dev_addr[0], dev->mem_start, dev->irq);
94
95 if (dev->mem_start <= 0 || dev->irq <= 0) {
96 BUGMSG(D_NORMAL, "No autoprobe for RIM I; you "
97 "must specify the shmem and irq!\n");
98 return -ENODEV;
99 }
100 /*
101 * Grab the memory region at mem_start for BUFFER_SIZE bytes.
102 * Later in arcrimi_found() the real size will be determined
103 * and this reserve will be released and the correct size
104 * will be taken.
105 */
106 if (!request_mem_region(dev->mem_start, BUFFER_SIZE, "arcnet (90xx)")) {
107 BUGMSG(D_NORMAL, "Card memory already allocated\n");
108 return -ENODEV;
109 }
110 if (dev->dev_addr[0] == 0) {
111 release_mem_region(dev->mem_start, BUFFER_SIZE);
112 BUGMSG(D_NORMAL, "You need to specify your card's station "
113 "ID!\n");
114 return -ENODEV;
115 }
116 return arcrimi_found(dev);
117}
118
119
120/*
121 * Set up the struct net_device associated with this card. Called after
122 * probing succeeds.
123 */
124static int __init arcrimi_found(struct net_device *dev)
125{
126 struct arcnet_local *lp;
127 unsigned long first_mirror, last_mirror, shmem;
128 int mirror_size;
129 int err;
130
131 /* reserve the irq */
132 if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
133 release_mem_region(dev->mem_start, BUFFER_SIZE);
134 BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
135 return -ENODEV;
136 }
137
138 shmem = dev->mem_start;
139 isa_writeb(TESTvalue, shmem);
140 isa_writeb(dev->dev_addr[0], shmem + 1); /* actually the node ID */
141
142 /* find the real shared memory start/end points, including mirrors */
143
144 /* guess the actual size of one "memory mirror" - the number of
145 * bytes between copies of the shared memory. On most cards, it's
146 * 2k (or there are no mirrors at all) but on some, it's 4k.
147 */
148 mirror_size = MIRROR_SIZE;
149 if (isa_readb(shmem) == TESTvalue
150 && isa_readb(shmem - mirror_size) != TESTvalue
151 && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
152 mirror_size *= 2;
153
154 first_mirror = last_mirror = shmem;
155 while (isa_readb(first_mirror) == TESTvalue)
156 first_mirror -= mirror_size;
157 first_mirror += mirror_size;
158
159 while (isa_readb(last_mirror) == TESTvalue)
160 last_mirror += mirror_size;
161 last_mirror -= mirror_size;
162
163 dev->mem_start = first_mirror;
164 dev->mem_end = last_mirror + MIRROR_SIZE - 1;
165
166 /* initialize the rest of the device structure. */
167
168 lp = dev->priv;
169 lp->card_name = "RIM I";
170 lp->hw.command = arcrimi_command;
171 lp->hw.status = arcrimi_status;
172 lp->hw.intmask = arcrimi_setmask;
173 lp->hw.reset = arcrimi_reset;
174 lp->hw.owner = THIS_MODULE;
175 lp->hw.copy_to_card = arcrimi_copy_to_card;
176 lp->hw.copy_from_card = arcrimi_copy_from_card;
177
178 /*
179 * re-reserve the memory region - arcrimi_probe() alloced this reqion
180 * but didn't know the real size. Free that region and then re-get
181 * with the correct size. There is a VERY slim chance this could
182 * fail.
183 */
184 release_mem_region(shmem, BUFFER_SIZE);
185 if (!request_mem_region(dev->mem_start,
186 dev->mem_end - dev->mem_start + 1,
187 "arcnet (90xx)")) {
188 BUGMSG(D_NORMAL, "Card memory already allocated\n");
189 goto err_free_irq;
190 }
191
192 lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
193 if (!lp->mem_start) {
194 BUGMSG(D_NORMAL, "Can't remap device memory!\n");
195 goto err_release_mem;
196 }
197
198 /* get and check the station ID from offset 1 in shmem */
199 dev->dev_addr[0] = readb(lp->mem_start + 1);
200
201 BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, "
202 "ShMem %lXh (%ld*%d bytes).\n",
203 dev->dev_addr[0],
204 dev->irq, dev->mem_start,
205 (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
206
207 err = register_netdev(dev);
208 if (err)
209 goto err_unmap;
210
211 return 0;
212
213err_unmap:
214 iounmap(lp->mem_start);
215err_release_mem:
216 release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
217err_free_irq:
218 free_irq(dev->irq, dev);
219 return -EIO;
220}
221
222
223/*
224 * Do a hardware reset on the card, and set up necessary registers.
225 *
226 * This should be called as little as possible, because it disrupts the
227 * token on the network (causes a RECON) and requires a significant delay.
228 *
229 * However, it does make sure the card is in a defined state.
230 */
231static int arcrimi_reset(struct net_device *dev, int really_reset)
232{
233 struct arcnet_local *lp = dev->priv;
234 void __iomem *ioaddr = lp->mem_start + 0x800;
235
236 BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
237
238 if (really_reset) {
239 writeb(TESTvalue, ioaddr - 0x800); /* fake reset */
240 return 0;
241 }
242 ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
243 ACOMMAND(CFLAGScmd | CONFIGclear);
244
245 /* enable extended (512-byte) packets */
246 ACOMMAND(CONFIGcmd | EXTconf);
247
248 /* done! return success. */
249 return 0;
250}
251
252static void arcrimi_setmask(struct net_device *dev, int mask)
253{
254 struct arcnet_local *lp = dev->priv;
255 void __iomem *ioaddr = lp->mem_start + 0x800;
256
257 AINTMASK(mask);
258}
259
260static int arcrimi_status(struct net_device *dev)
261{
262 struct arcnet_local *lp = dev->priv;
263 void __iomem *ioaddr = lp->mem_start + 0x800;
264
265 return ASTATUS();
266}
267
268static void arcrimi_command(struct net_device *dev, int cmd)
269{
270 struct arcnet_local *lp = dev->priv;
271 void __iomem *ioaddr = lp->mem_start + 0x800;
272
273 ACOMMAND(cmd);
274}
275
276static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
277 void *buf, int count)
278{
279 struct arcnet_local *lp = dev->priv;
280 void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
281 TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
282}
283
284
285static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
286 void *buf, int count)
287{
288 struct arcnet_local *lp = dev->priv;
289 void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
290 TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
291}
292
293static int node;
294static int io; /* use the insmod io= irq= node= options */
295static int irq;
296static char device[9]; /* use eg. device=arc1 to change name */
297
298module_param(node, int, 0);
299module_param(io, int, 0);
300module_param(irq, int, 0);
301module_param_string(device, device, sizeof(device), 0);
302MODULE_LICENSE("GPL");
303
304static struct net_device *my_dev;
305
306static int __init arc_rimi_init(void)
307{
308 struct net_device *dev;
309
310 dev = alloc_arcdev(device);
311 if (!dev)
312 return -ENOMEM;
313
314 if (node && node != 0xff)
315 dev->dev_addr[0] = node;
316
317 dev->mem_start = io;
318 dev->irq = irq;
319 if (dev->irq == 2)
320 dev->irq = 9;
321
322 if (arcrimi_probe(dev)) {
323 free_netdev(dev);
324 return -EIO;
325 }
326
327 my_dev = dev;
328 return 0;
329}
330
331static void __exit arc_rimi_exit(void)
332{
333 struct net_device *dev = my_dev;
334 struct arcnet_local *lp = dev->priv;
335
336 unregister_netdev(dev);
337 iounmap(lp->mem_start);
338 release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
339 free_irq(dev->irq, dev);
340 free_netdev(dev);
341}
342
343#ifndef MODULE
344static int __init arcrimi_setup(char *s)
345{
346 int ints[8];
347 s = get_options(s, 8, ints);
348 if (!ints[0])
349 return 1;
350 switch (ints[0]) {
351 default: /* ERROR */
352 printk("arcrimi: Too many arguments.\n");
353 case 3: /* Node ID */
354 node = ints[3];
355 case 2: /* IRQ */
356 irq = ints[2];
357 case 1: /* IO address */
358 io = ints[1];
359 }
360 if (*s)
361 snprintf(device, sizeof(device), "%s", s);
362 return 1;
363}
364__setup("arcrimi=", arcrimi_setup);
365#endif /* MODULE */
366
367module_init(arc_rimi_init)
368module_exit(arc_rimi_exit)
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
new file mode 100644
index 000000000000..4f9f69e22c1b
--- /dev/null
+++ b/drivers/net/arcnet/arcnet.c
@@ -0,0 +1,1102 @@
1/*
2 * Linux ARCnet driver - device-independent routines
3 *
4 * Written 1997 by David Woodhouse.
5 * Written 1994-1999 by Avery Pennarun.
6 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
7 * Derived from skeleton.c by Donald Becker.
8 *
9 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
10 * for sponsoring the further development of this driver.
11 *
12 * **********************
13 *
14 * The original copyright was as follows:
15 *
16 * skeleton.c Written 1993 by Donald Becker.
17 * Copyright 1993 United States Government as represented by the
18 * Director, National Security Agency. This software may only be used
19 * and distributed according to the terms of the GNU General Public License as
20 * modified by SRC, incorporated herein by reference.
21 *
22 * **********************
23 *
24 * The change log is now in a file called ChangeLog in this directory.
25 *
26 * Sources:
27 * - Crynwr arcnet.com/arcether.com packet drivers.
28 * - arcnet.c v0.00 dated 1/1/94 and apparently by
29 * Donald Becker - it didn't work :)
30 * - skeleton.c v0.05 dated 11/16/93 by Donald Becker
31 * (from Linux Kernel 1.1.45)
32 * - RFC's 1201 and 1051 - re: TCP/IP over ARCnet
33 * - The official ARCnet COM9026 data sheets (!) thanks to
34 * Ken Cornetet <kcornete@nyx10.cs.du.edu>
35 * - The official ARCnet COM20020 data sheets.
36 * - Information on some more obscure ARCnet controller chips, thanks
37 * to the nice people at SMSC.
38 * - net/inet/eth.c (from kernel 1.1.50) for header-building info.
39 * - Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su>
40 * - Textual information and more alternate source from Joachim Koenig
41 * <jojo@repas.de>
42 */
43
44#define VERSION "arcnet: v3.93 BETA 2000/04/29 - by Avery Pennarun et al.\n"
45
46#include <linux/module.h>
47#include <linux/config.h>
48#include <linux/types.h>
49#include <linux/delay.h>
50#include <linux/netdevice.h>
51#include <linux/if_arp.h>
52#include <net/arp.h>
53#include <linux/init.h>
54#include <linux/arcdevice.h>
55
56/* "do nothing" functions for protocol drivers */
57static void null_rx(struct net_device *dev, int bufnum,
58 struct archdr *pkthdr, int length);
59static int null_build_header(struct sk_buff *skb, struct net_device *dev,
60 unsigned short type, uint8_t daddr);
61static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
62 int length, int bufnum);
63
64
65/*
66 * one ArcProto per possible proto ID. None of the elements of
67 * arc_proto_map are allowed to be NULL; they will get set to
68 * arc_proto_default instead. It also must not be NULL; if you would like
69 * to set it to NULL, set it to &arc_proto_null instead.
70 */
71 struct ArcProto *arc_proto_map[256], *arc_proto_default,
72 *arc_bcast_proto, *arc_raw_proto;
73
74struct ArcProto arc_proto_null =
75{
76 .suffix = '?',
77 .mtu = XMTU,
78 .is_ip = 0,
79 .rx = null_rx,
80 .build_header = null_build_header,
81 .prepare_tx = null_prepare_tx,
82 .continue_tx = NULL,
83 .ack_tx = NULL
84};
85
86/* Exported function prototypes */
87int arcnet_debug = ARCNET_DEBUG;
88
89EXPORT_SYMBOL(arc_proto_map);
90EXPORT_SYMBOL(arc_proto_default);
91EXPORT_SYMBOL(arc_bcast_proto);
92EXPORT_SYMBOL(arc_raw_proto);
93EXPORT_SYMBOL(arc_proto_null);
94EXPORT_SYMBOL(arcnet_unregister_proto);
95EXPORT_SYMBOL(arcnet_debug);
96EXPORT_SYMBOL(alloc_arcdev);
97EXPORT_SYMBOL(arcnet_interrupt);
98
99/* Internal function prototypes */
100static int arcnet_open(struct net_device *dev);
101static int arcnet_close(struct net_device *dev);
102static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
103static void arcnet_timeout(struct net_device *dev);
104static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
105 unsigned short type, void *daddr, void *saddr,
106 unsigned len);
107static int arcnet_rebuild_header(struct sk_buff *skb);
108static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
109static int go_tx(struct net_device *dev);
110
111static int debug = ARCNET_DEBUG;
112module_param(debug, int, 0);
113MODULE_LICENSE("GPL");
114
115static int __init arcnet_init(void)
116{
117 int count;
118
119 arcnet_debug = debug;
120
121 printk(VERSION);
122
123#ifdef ALPHA_WARNING
124 BUGLVL(D_EXTRA) {
125 printk("arcnet: ***\n"
126 "arcnet: * Read arcnet.txt for important release notes!\n"
127 "arcnet: *\n"
128 "arcnet: * This is an ALPHA version! (Last stable release: v3.02) E-mail\n"
129 "arcnet: * me if you have any questions, comments, or bug reports.\n"
130 "arcnet: ***\n");
131 }
132#endif
133
134 /* initialize the protocol map */
135 arc_raw_proto = arc_proto_default = arc_bcast_proto = &arc_proto_null;
136 for (count = 0; count < 256; count++)
137 arc_proto_map[count] = arc_proto_default;
138
139 BUGLVL(D_DURING)
140 printk("arcnet: struct sizes: %Zd %Zd %Zd %Zd %Zd\n",
141 sizeof(struct arc_hardware), sizeof(struct arc_rfc1201),
142 sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap),
143 sizeof(struct archdr));
144
145 return 0;
146}
147
148static void __exit arcnet_exit(void)
149{
150}
151
152module_init(arcnet_init);
153module_exit(arcnet_exit);
154
155/*
156 * Dump the contents of an sk_buff
157 */
158#if ARCNET_DEBUG_MAX & D_SKB
159void arcnet_dump_skb(struct net_device *dev,
160 struct sk_buff *skb, char *desc)
161{
162 int i;
163
164 printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc);
165 for (i = 0; i < skb->len; i++) {
166 if (i % 16 == 0)
167 printk("\n" KERN_DEBUG "[%04X] ", i);
168 printk("%02X ", ((u_char *) skb->data)[i]);
169 }
170 printk("\n");
171}
172
173EXPORT_SYMBOL(arcnet_dump_skb);
174#endif
175
176
177/*
178 * Dump the contents of an ARCnet buffer
179 */
180#if (ARCNET_DEBUG_MAX & (D_RX | D_TX))
181void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc,
182 int take_arcnet_lock)
183{
184 struct arcnet_local *lp = dev->priv;
185 int i, length;
186 unsigned long flags = 0;
187 static uint8_t buf[512];
188
189 /* hw.copy_from_card expects IRQ context so take the IRQ lock
190 to keep it single threaded */
191 if(take_arcnet_lock)
192 spin_lock_irqsave(&lp->lock, flags);
193
194 lp->hw.copy_from_card(dev, bufnum, 0, buf, 512);
195 if(take_arcnet_lock)
196 spin_unlock_irqrestore(&lp->lock, flags);
197
198 /* if the offset[0] byte is nonzero, this is a 256-byte packet */
199 length = (buf[2] ? 256 : 512);
200
201 printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc);
202 for (i = 0; i < length; i++) {
203 if (i % 16 == 0)
204 printk("\n" KERN_DEBUG "[%04X] ", i);
205 printk("%02X ", buf[i]);
206 }
207 printk("\n");
208
209}
210
211EXPORT_SYMBOL(arcnet_dump_packet);
212#endif
213
214
215/*
216 * Unregister a protocol driver from the arc_proto_map. Protocol drivers
217 * are responsible for registering themselves, but the unregister routine
218 * is pretty generic so we'll do it here.
219 */
220void arcnet_unregister_proto(struct ArcProto *proto)
221{
222 int count;
223
224 if (arc_proto_default == proto)
225 arc_proto_default = &arc_proto_null;
226 if (arc_bcast_proto == proto)
227 arc_bcast_proto = arc_proto_default;
228 if (arc_raw_proto == proto)
229 arc_raw_proto = arc_proto_default;
230
231 for (count = 0; count < 256; count++) {
232 if (arc_proto_map[count] == proto)
233 arc_proto_map[count] = arc_proto_default;
234 }
235}
236
237
238/*
239 * Add a buffer to the queue. Only the interrupt handler is allowed to do
240 * this, unless interrupts are disabled.
241 *
242 * Note: we don't check for a full queue, since there aren't enough buffers
243 * to more than fill it.
244 */
245static void release_arcbuf(struct net_device *dev, int bufnum)
246{
247 struct arcnet_local *lp = dev->priv;
248 int i;
249
250 lp->buf_queue[lp->first_free_buf++] = bufnum;
251 lp->first_free_buf %= 5;
252
253 BUGLVL(D_DURING) {
254 BUGMSG(D_DURING, "release_arcbuf: freed #%d; buffer queue is now: ",
255 bufnum);
256 for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5)
257 BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
258 BUGMSG2(D_DURING, "\n");
259 }
260}
261
262
263/*
264 * Get a buffer from the queue. If this returns -1, there are no buffers
265 * available.
266 */
267static int get_arcbuf(struct net_device *dev)
268{
269 struct arcnet_local *lp = dev->priv;
270 int buf = -1, i;
271
272 if (!atomic_dec_and_test(&lp->buf_lock)) {
273 /* already in this function */
274 BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n",
275 lp->buf_lock.counter);
276 }
277 else { /* we can continue */
278 if (lp->next_buf >= 5)
279 lp->next_buf -= 5;
280
281 if (lp->next_buf == lp->first_free_buf)
282 BUGMSG(D_NORMAL, "get_arcbuf: BUG: no buffers are available??\n");
283 else {
284 buf = lp->buf_queue[lp->next_buf++];
285 lp->next_buf %= 5;
286 }
287 }
288
289
290 BUGLVL(D_DURING) {
291 BUGMSG(D_DURING, "get_arcbuf: got #%d; buffer queue is now: ", buf);
292 for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5)
293 BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
294 BUGMSG2(D_DURING, "\n");
295 }
296
297 atomic_inc(&lp->buf_lock);
298 return buf;
299}
300
301
302static int choose_mtu(void)
303{
304 int count, mtu = 65535;
305
306 /* choose the smallest MTU of all available encaps */
307 for (count = 0; count < 256; count++) {
308 if (arc_proto_map[count] != &arc_proto_null
309 && arc_proto_map[count]->mtu < mtu) {
310 mtu = arc_proto_map[count]->mtu;
311 }
312 }
313
314 return mtu == 65535 ? XMTU : mtu;
315}
316
317
318/* Setup a struct device for ARCnet. */
319static void arcdev_setup(struct net_device *dev)
320{
321 dev->type = ARPHRD_ARCNET;
322 dev->hard_header_len = sizeof(struct archdr);
323 dev->mtu = choose_mtu();
324
325 dev->addr_len = ARCNET_ALEN;
326 dev->tx_queue_len = 100;
327 dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */
328 dev->watchdog_timeo = TX_TIMEOUT;
329
330 /* New-style flags. */
331 dev->flags = IFF_BROADCAST;
332
333 /*
334 * Put in this stuff here, so we don't have to export the symbols to
335 * the chipset drivers.
336 */
337 dev->open = arcnet_open;
338 dev->stop = arcnet_close;
339 dev->hard_start_xmit = arcnet_send_packet;
340 dev->tx_timeout = arcnet_timeout;
341 dev->get_stats = arcnet_get_stats;
342 dev->hard_header = arcnet_header;
343 dev->rebuild_header = arcnet_rebuild_header;
344}
345
346struct net_device *alloc_arcdev(char *name)
347{
348 struct net_device *dev;
349
350 dev = alloc_netdev(sizeof(struct arcnet_local),
351 name && *name ? name : "arc%d", arcdev_setup);
352 if(dev) {
353 struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
354 spin_lock_init(&lp->lock);
355 }
356
357 return dev;
358}
359
360/*
361 * Open/initialize the board. This is called sometime after booting when
362 * the 'ifconfig' program is run.
363 *
364 * This routine should set everything up anew at each open, even registers
365 * that "should" only need to be set once at boot, so that there is
366 * non-reboot way to recover if something goes wrong.
367 */
368static int arcnet_open(struct net_device *dev)
369{
370 struct arcnet_local *lp = dev->priv;
371 int count, newmtu, error;
372
373 BUGMSG(D_INIT,"opened.");
374
375 if (!try_module_get(lp->hw.owner))
376 return -ENODEV;
377
378 BUGLVL(D_PROTO) {
379 int count;
380 BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
381 arc_proto_default->suffix);
382 for (count = 0; count < 256; count++)
383 BUGMSG2(D_PROTO, "%c", arc_proto_map[count]->suffix);
384 BUGMSG2(D_PROTO, "\n");
385 }
386
387
388 BUGMSG(D_INIT, "arcnet_open: resetting card.\n");
389
390 /* try to put the card in a defined state - if it fails the first
391 * time, actually reset it.
392 */
393 error = -ENODEV;
394 if (ARCRESET(0) && ARCRESET(1))
395 goto out_module_put;
396
397 newmtu = choose_mtu();
398 if (newmtu < dev->mtu)
399 dev->mtu = newmtu;
400
401 BUGMSG(D_INIT, "arcnet_open: mtu: %d.\n", dev->mtu);
402
403 /* autodetect the encapsulation for each host. */
404 memset(lp->default_proto, 0, sizeof(lp->default_proto));
405
406 /* the broadcast address is special - use the 'bcast' protocol */
407 for (count = 0; count < 256; count++) {
408 if (arc_proto_map[count] == arc_bcast_proto) {
409 lp->default_proto[0] = count;
410 break;
411 }
412 }
413
414 /* initialize buffers */
415 atomic_set(&lp->buf_lock, 1);
416
417 lp->next_buf = lp->first_free_buf = 0;
418 release_arcbuf(dev, 0);
419 release_arcbuf(dev, 1);
420 release_arcbuf(dev, 2);
421 release_arcbuf(dev, 3);
422 lp->cur_tx = lp->next_tx = -1;
423 lp->cur_rx = -1;
424
425 lp->rfc1201.sequence = 1;
426
427 /* bring up the hardware driver */
428 if (lp->hw.open)
429 lp->hw.open(dev);
430
431 if (dev->dev_addr[0] == 0)
432 BUGMSG(D_NORMAL, "WARNING! Station address 00 is reserved "
433 "for broadcasts!\n");
434 else if (dev->dev_addr[0] == 255)
435 BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
436 "DOS networking programs!\n");
437
438 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
439 if (ASTATUS() & RESETflag) {
440 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
441 ACOMMAND(CFLAGScmd | RESETclear);
442 }
443
444
445 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
446 /* make sure we're ready to receive IRQ's. */
447 AINTMASK(0);
448 udelay(1); /* give it time to set the mask before
449 * we reset it again. (may not even be
450 * necessary)
451 */
452 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
453 lp->intmask = NORXflag | RECONflag;
454 AINTMASK(lp->intmask);
455 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
456
457 netif_start_queue(dev);
458
459 return 0;
460
461 out_module_put:
462 module_put(lp->hw.owner);
463 return error;
464}
465
466
467/* The inverse routine to arcnet_open - shuts down the card. */
468static int arcnet_close(struct net_device *dev)
469{
470 struct arcnet_local *lp = dev->priv;
471
472 netif_stop_queue(dev);
473
474 /* flush TX and disable RX */
475 AINTMASK(0);
476 ACOMMAND(NOTXcmd); /* stop transmit */
477 ACOMMAND(NORXcmd); /* disable receive */
478 mdelay(1);
479
480 /* shut down the card */
481 lp->hw.close(dev);
482 module_put(lp->hw.owner);
483 return 0;
484}
485
486
487static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
488 unsigned short type, void *daddr, void *saddr,
489 unsigned len)
490{
491 struct arcnet_local *lp = dev->priv;
492 uint8_t _daddr, proto_num;
493 struct ArcProto *proto;
494
495 BUGMSG(D_DURING,
496 "create header from %d to %d; protocol %d (%Xh); size %u.\n",
497 saddr ? *(uint8_t *) saddr : -1,
498 daddr ? *(uint8_t *) daddr : -1,
499 type, type, len);
500
501 if (skb->len!=0 && len != skb->len)
502 BUGMSG(D_NORMAL, "arcnet_header: Yikes! skb->len(%d) != len(%d)!\n",
503 skb->len, len);
504
505
506 /* Type is host order - ? */
507 if(type == ETH_P_ARCNET) {
508 proto = arc_raw_proto;
509 BUGMSG(D_DEBUG, "arc_raw_proto used. proto='%c'\n",proto->suffix);
510 _daddr = daddr ? *(uint8_t *) daddr : 0;
511 }
512 else if (!daddr) {
513 /*
514 * if the dest addr isn't provided, we can't choose an encapsulation!
515 * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
516 * real header when we do rebuild_header.
517 */
518 *(uint16_t *) skb_push(skb, 2) = type;
519 if (skb->nh.raw - skb->mac.raw != 2)
520 BUGMSG(D_NORMAL, "arcnet_header: Yikes! diff (%d) is not 2!\n",
521 (int)(skb->nh.raw - skb->mac.raw));
522 return -2; /* return error -- can't transmit yet! */
523 }
524 else {
525 /* otherwise, we can just add the header as usual. */
526 _daddr = *(uint8_t *) daddr;
527 proto_num = lp->default_proto[_daddr];
528 proto = arc_proto_map[proto_num];
529 BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
530 proto_num, proto->suffix);
531 if (proto == &arc_proto_null && arc_bcast_proto != proto) {
532 BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
533 arc_bcast_proto->suffix);
534 proto = arc_bcast_proto;
535 }
536 }
537 return proto->build_header(skb, dev, type, _daddr);
538}
539
540
541/*
542 * Rebuild the ARCnet hard header. This is called after an ARP (or in the
543 * future other address resolution) has completed on this sk_buff. We now
544 * let ARP fill in the destination field.
545 */
546static int arcnet_rebuild_header(struct sk_buff *skb)
547{
548 struct net_device *dev = skb->dev;
549 struct arcnet_local *lp = dev->priv;
550 int status = 0; /* default is failure */
551 unsigned short type;
552 uint8_t daddr=0;
553 struct ArcProto *proto;
554
555 if (skb->nh.raw - skb->mac.raw != 2) {
556 BUGMSG(D_NORMAL,
557 "rebuild_header: shouldn't be here! (hdrsize=%d)\n",
558 (int)(skb->nh.raw - skb->mac.raw));
559 return 0;
560 }
561 type = *(uint16_t *) skb_pull(skb, 2);
562 BUGMSG(D_DURING, "rebuild header for protocol %Xh\n", type);
563
564 if (type == ETH_P_IP) {
565#ifdef CONFIG_INET
566 BUGMSG(D_DURING, "rebuild header for ethernet protocol %Xh\n", type);
567 status = arp_find(&daddr, skb) ? 1 : 0;
568 BUGMSG(D_DURING, " rebuilt: dest is %d; protocol %Xh\n",
569 daddr, type);
570#endif
571 } else {
572 BUGMSG(D_NORMAL,
573 "I don't understand ethernet protocol %Xh addresses!\n", type);
574 lp->stats.tx_errors++;
575 lp->stats.tx_aborted_errors++;
576 }
577
578 /* if we couldn't resolve the address... give up. */
579 if (!status)
580 return 0;
581
582 /* add the _real_ header this time! */
583 proto = arc_proto_map[lp->default_proto[daddr]];
584 proto->build_header(skb, dev, type, daddr);
585
586 return 1; /* success */
587}
588
589
590
591/* Called by the kernel in order to transmit a packet. */
592static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
593{
594 struct arcnet_local *lp = dev->priv;
595 struct archdr *pkt;
596 struct arc_rfc1201 *soft;
597 struct ArcProto *proto;
598 int txbuf;
599 unsigned long flags;
600 int freeskb = 0;
601
602 BUGMSG(D_DURING,
603 "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
604 ASTATUS(), lp->cur_tx, lp->next_tx, skb->len,skb->protocol);
605
606 pkt = (struct archdr *) skb->data;
607 soft = &pkt->soft.rfc1201;
608 proto = arc_proto_map[soft->proto];
609
610 BUGMSG(D_SKB_SIZE, "skb: transmitting %d bytes to %02X\n",
611 skb->len, pkt->hard.dest);
612 BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx");
613
614 /* fits in one packet? */
615 if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) {
616 BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n");
617 dev_kfree_skb(skb);
618 return 0; /* don't try again */
619 }
620
621 /* We're busy transmitting a packet... */
622 netif_stop_queue(dev);
623
624 spin_lock_irqsave(&lp->lock, flags);
625 AINTMASK(0);
626
627 txbuf = get_arcbuf(dev);
628 if (txbuf != -1) {
629 if (proto->prepare_tx(dev, pkt, skb->len, txbuf) &&
630 !proto->ack_tx) {
631 /* done right away and we don't want to acknowledge
632 the package later - forget about it now */
633 lp->stats.tx_bytes += skb->len;
634 freeskb = 1;
635 } else {
636 /* do it the 'split' way */
637 lp->outgoing.proto = proto;
638 lp->outgoing.skb = skb;
639 lp->outgoing.pkt = pkt;
640
641 if (proto->continue_tx &&
642 proto->continue_tx(dev, txbuf)) {
643 BUGMSG(D_NORMAL,
644 "bug! continue_tx finished the first time! "
645 "(proto='%c')\n", proto->suffix);
646 }
647 }
648
649 lp->next_tx = txbuf;
650 } else {
651 freeskb = 1;
652 }
653
654 BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
655 /* make sure we didn't ignore a TX IRQ while we were in here */
656 AINTMASK(0);
657
658 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
659 lp->intmask |= TXFREEflag|EXCNAKflag;
660 AINTMASK(lp->intmask);
661 BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
662
663 spin_unlock_irqrestore(&lp->lock, flags);
664 if (freeskb) {
665 dev_kfree_skb(skb);
666 }
667 return 0; /* no need to try again */
668}
669
670
671/*
672 * Actually start transmitting a packet that was loaded into a buffer
673 * by prepare_tx. This should _only_ be called by the interrupt handler.
674 */
675static int go_tx(struct net_device *dev)
676{
677 struct arcnet_local *lp = dev->priv;
678
679 BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
680 ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
681
682 if (lp->cur_tx != -1 || lp->next_tx == -1)
683 return 0;
684
685 BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx", 0);
686
687 lp->cur_tx = lp->next_tx;
688 lp->next_tx = -1;
689
690 /* start sending */
691 ACOMMAND(TXcmd | (lp->cur_tx << 3));
692
693 dev->trans_start = jiffies;
694 lp->stats.tx_packets++;
695 lp->lasttrans_dest = lp->lastload_dest;
696 lp->lastload_dest = 0;
697 lp->excnak_pending = 0;
698 lp->intmask |= TXFREEflag|EXCNAKflag;
699
700 return 1;
701}
702
703
704/* Called by the kernel when transmit times out */
705static void arcnet_timeout(struct net_device *dev)
706{
707 unsigned long flags;
708 struct arcnet_local *lp = dev->priv;
709 int status = ASTATUS();
710 char *msg;
711
712 spin_lock_irqsave(&lp->lock, flags);
713 if (status & TXFREEflag) { /* transmit _DID_ finish */
714 msg = " - missed IRQ?";
715 } else {
716 msg = "";
717 lp->stats.tx_aborted_errors++;
718 lp->timed_out = 1;
719 ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
720 }
721 lp->stats.tx_errors++;
722
723 /* make sure we didn't miss a TX or a EXC NAK IRQ */
724 AINTMASK(0);
725 lp->intmask |= TXFREEflag|EXCNAKflag;
726 AINTMASK(lp->intmask);
727
728 spin_unlock_irqrestore(&lp->lock, flags);
729
730 if (jiffies - lp->last_timeout > 10*HZ) {
731 BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n",
732 msg, status, lp->intmask, lp->lasttrans_dest);
733 lp->last_timeout = jiffies;
734 }
735
736 if (lp->cur_tx == -1)
737 netif_wake_queue(dev);
738}
739
740
741/*
742 * The typical workload of the driver: Handle the network interface
743 * interrupts. Establish which device needs attention, and call the correct
744 * chipset interrupt handler.
745 */
746irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
747{
748 struct net_device *dev = dev_id;
749 struct arcnet_local *lp;
750 int recbuf, status, diagstatus, didsomething, boguscount;
751 int retval = IRQ_NONE;
752
753 BUGMSG(D_DURING, "\n");
754
755 BUGMSG(D_DURING, "in arcnet_interrupt\n");
756
757 lp = dev->priv;
758 if (!lp)
759 BUG();
760
761 spin_lock(&lp->lock);
762
763 /*
764 * RESET flag was enabled - if device is not running, we must clear it right
765 * away (but nothing else).
766 */
767 if (!netif_running(dev)) {
768 if (ASTATUS() & RESETflag)
769 ACOMMAND(CFLAGScmd | RESETclear);
770 AINTMASK(0);
771 spin_unlock(&lp->lock);
772 return IRQ_HANDLED;
773 }
774
775 BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
776 ASTATUS(), lp->intmask);
777
778 boguscount = 5;
779 do {
780 status = ASTATUS();
781 diagstatus = (status >> 8) & 0xFF;
782
783 BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
784 __FILE__,__LINE__,__FUNCTION__,status);
785 didsomething = 0;
786
787 /*
788 * RESET flag was enabled - card is resetting and if RX is
789 * disabled, it's NOT because we just got a packet.
790 *
791 * The card is in an undefined state. Clear it out and start over.
792 */
793 if (status & RESETflag) {
794 BUGMSG(D_NORMAL, "spurious reset (status=%Xh)\n", status);
795 arcnet_close(dev);
796 arcnet_open(dev);
797
798 /* get out of the interrupt handler! */
799 break;
800 }
801 /*
802 * RX is inhibited - we must have received something. Prepare to
803 * receive into the next buffer.
804 *
805 * We don't actually copy the received packet from the card until
806 * after the transmit handler runs (and possibly launches the next
807 * tx); this should improve latency slightly if we get both types
808 * of interrupts at once.
809 */
810 recbuf = -1;
811 if (status & lp->intmask & NORXflag) {
812 recbuf = lp->cur_rx;
813 BUGMSG(D_DURING, "Buffer #%d: receive irq (status=%Xh)\n",
814 recbuf, status);
815
816 lp->cur_rx = get_arcbuf(dev);
817 if (lp->cur_rx != -1) {
818 BUGMSG(D_DURING, "enabling receive to buffer #%d\n",
819 lp->cur_rx);
820 ACOMMAND(RXcmd | (lp->cur_rx << 3) | RXbcasts);
821 }
822 didsomething++;
823 }
824
825 if((diagstatus & EXCNAKflag)) {
826 BUGMSG(D_DURING, "EXCNAK IRQ (diagstat=%Xh)\n",
827 diagstatus);
828
829 ACOMMAND(NOTXcmd); /* disable transmit */
830 lp->excnak_pending = 1;
831
832 ACOMMAND(EXCNAKclear);
833 lp->intmask &= ~(EXCNAKflag);
834 didsomething++;
835 }
836
837
838 /* a transmit finished, and we're interested in it. */
839 if ((status & lp->intmask & TXFREEflag) || lp->timed_out) {
840 lp->intmask &= ~(TXFREEflag|EXCNAKflag);
841
842 BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status);
843
844 if (lp->cur_tx != -1 && !lp->timed_out) {
845 if(!(status & TXACKflag)) {
846 if (lp->lasttrans_dest != 0) {
847 BUGMSG(D_EXTRA,
848 "transmit was not acknowledged! "
849 "(status=%Xh, dest=%02Xh)\n",
850 status, lp->lasttrans_dest);
851 lp->stats.tx_errors++;
852 lp->stats.tx_carrier_errors++;
853 } else {
854 BUGMSG(D_DURING,
855 "broadcast was not acknowledged; that's normal "
856 "(status=%Xh, dest=%02Xh)\n",
857 status, lp->lasttrans_dest);
858 }
859 }
860
861 if (lp->outgoing.proto &&
862 lp->outgoing.proto->ack_tx) {
863 int ackstatus;
864 if(status & TXACKflag)
865 ackstatus=2;
866 else if(lp->excnak_pending)
867 ackstatus=1;
868 else
869 ackstatus=0;
870
871 lp->outgoing.proto
872 ->ack_tx(dev, ackstatus);
873 }
874 }
875 if (lp->cur_tx != -1)
876 release_arcbuf(dev, lp->cur_tx);
877
878 lp->cur_tx = -1;
879 lp->timed_out = 0;
880 didsomething++;
881
882 /* send another packet if there is one */
883 go_tx(dev);
884
885 /* continue a split packet, if any */
886 if (lp->outgoing.proto && lp->outgoing.proto->continue_tx) {
887 int txbuf = get_arcbuf(dev);
888 if (txbuf != -1) {
889 if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
890 /* that was the last segment */
891 lp->stats.tx_bytes += lp->outgoing.skb->len;
892 if(!lp->outgoing.proto->ack_tx)
893 {
894 dev_kfree_skb_irq(lp->outgoing.skb);
895 lp->outgoing.proto = NULL;
896 }
897 }
898 lp->next_tx = txbuf;
899 }
900 }
901 /* inform upper layers of idleness, if necessary */
902 if (lp->cur_tx == -1)
903 netif_wake_queue(dev);
904 }
905 /* now process the received packet, if any */
906 if (recbuf != -1) {
907 BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq", 0);
908
909 arcnet_rx(dev, recbuf);
910 release_arcbuf(dev, recbuf);
911
912 didsomething++;
913 }
914 if (status & lp->intmask & RECONflag) {
915 ACOMMAND(CFLAGScmd | CONFIGclear);
916 lp->stats.tx_carrier_errors++;
917
918 BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
919 status);
920
921 /* is the RECON info empty or old? */
922 if (!lp->first_recon || !lp->last_recon ||
923 jiffies - lp->last_recon > HZ * 10) {
924 if (lp->network_down)
925 BUGMSG(D_NORMAL, "reconfiguration detected: cabling restored?\n");
926 lp->first_recon = lp->last_recon = jiffies;
927 lp->num_recons = lp->network_down = 0;
928
929 BUGMSG(D_DURING, "recon: clearing counters.\n");
930 } else { /* add to current RECON counter */
931 lp->last_recon = jiffies;
932 lp->num_recons++;
933
934 BUGMSG(D_DURING, "recon: counter=%d, time=%lds, net=%d\n",
935 lp->num_recons,
936 (lp->last_recon - lp->first_recon) / HZ,
937 lp->network_down);
938
939 /* if network is marked up;
940 * and first_recon and last_recon are 60+ apart;
941 * and the average no. of recons counted is
942 * > RECON_THRESHOLD/min;
943 * then print a warning message.
944 */
945 if (!lp->network_down
946 && (lp->last_recon - lp->first_recon) <= HZ * 60
947 && lp->num_recons >= RECON_THRESHOLD) {
948 lp->network_down = 1;
949 BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");
950 } else if (!lp->network_down
951 && lp->last_recon - lp->first_recon > HZ * 60) {
952 /* reset counters if we've gone for over a minute. */
953 lp->first_recon = lp->last_recon;
954 lp->num_recons = 1;
955 }
956 }
957 } else if (lp->network_down && jiffies - lp->last_recon > HZ * 10) {
958 if (lp->network_down)
959 BUGMSG(D_NORMAL, "cabling restored?\n");
960 lp->first_recon = lp->last_recon = 0;
961 lp->num_recons = lp->network_down = 0;
962
963 BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");
964 }
965
966 if(didsomething) {
967 retval |= IRQ_HANDLED;
968 }
969 }
970 while (--boguscount && didsomething);
971
972 BUGMSG(D_DURING, "arcnet_interrupt complete (status=%Xh, count=%d)\n",
973 ASTATUS(), boguscount);
974 BUGMSG(D_DURING, "\n");
975
976
977 AINTMASK(0);
978 udelay(1);
979 AINTMASK(lp->intmask);
980
981 spin_unlock(&lp->lock);
982 return retval;
983}
984
985
986/*
987 * This is a generic packet receiver that calls arcnet??_rx depending on the
988 * protocol ID found.
989 */
990void arcnet_rx(struct net_device *dev, int bufnum)
991{
992 struct arcnet_local *lp = dev->priv;
993 struct archdr pkt;
994 struct arc_rfc1201 *soft;
995 int length, ofs;
996
997 soft = &pkt.soft.rfc1201;
998
999 lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE));
1000 if (pkt.hard.offset[0]) {
1001 ofs = pkt.hard.offset[0];
1002 length = 256 - ofs;
1003 } else {
1004 ofs = pkt.hard.offset[1];
1005 length = 512 - ofs;
1006 }
1007
1008 /* get the full header, if possible */
1009 if (sizeof(pkt.soft) <= length)
1010 lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
1011 else {
1012 memset(&pkt.soft, 0, sizeof(pkt.soft));
1013 lp->hw.copy_from_card(dev, bufnum, ofs, soft, length);
1014 }
1015
1016 BUGMSG(D_DURING, "Buffer #%d: received packet from %02Xh to %02Xh "
1017 "(%d+4 bytes)\n",
1018 bufnum, pkt.hard.source, pkt.hard.dest, length);
1019
1020 lp->stats.rx_packets++;
1021 lp->stats.rx_bytes += length + ARC_HDR_SIZE;
1022
1023 /* call the right receiver for the protocol */
1024 if (arc_proto_map[soft->proto]->is_ip) {
1025 BUGLVL(D_PROTO) {
1026 struct ArcProto
1027 *oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
1028 *newp = arc_proto_map[soft->proto];
1029
1030 if (oldp != newp) {
1031 BUGMSG(D_PROTO,
1032 "got protocol %02Xh; encap for host %02Xh is now '%c'"
1033 " (was '%c')\n", soft->proto, pkt.hard.source,
1034 newp->suffix, oldp->suffix);
1035 }
1036 }
1037
1038 /* broadcasts will always be done with the last-used encap. */
1039 lp->default_proto[0] = soft->proto;
1040
1041 /* in striking contrast, the following isn't a hack. */
1042 lp->default_proto[pkt.hard.source] = soft->proto;
1043 }
1044 /* call the protocol-specific receiver. */
1045 arc_proto_map[soft->proto]->rx(dev, bufnum, &pkt, length);
1046}
1047
1048
1049
1050/*
1051 * Get the current statistics. This may be called with the card open or
1052 * closed.
1053 */
1054static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
1055{
1056 struct arcnet_local *lp = dev->priv;
1057 return &lp->stats;
1058}
1059
1060
1061static void null_rx(struct net_device *dev, int bufnum,
1062 struct archdr *pkthdr, int length)
1063{
1064 BUGMSG(D_PROTO,
1065 "rx: don't know how to deal with proto %02Xh from host %02Xh.\n",
1066 pkthdr->soft.rfc1201.proto, pkthdr->hard.source);
1067}
1068
1069
1070static int null_build_header(struct sk_buff *skb, struct net_device *dev,
1071 unsigned short type, uint8_t daddr)
1072{
1073 struct arcnet_local *lp = dev->priv;
1074
1075 BUGMSG(D_PROTO,
1076 "tx: can't build header for encap %02Xh; load a protocol driver.\n",
1077 lp->default_proto[daddr]);
1078
1079 /* always fails */
1080 return 0;
1081}
1082
1083
1084/* the "do nothing" prepare_tx function warns that there's nothing to do. */
1085static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
1086 int length, int bufnum)
1087{
1088 struct arcnet_local *lp = dev->priv;
1089 struct arc_hardware newpkt;
1090
1091 BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
1092
1093 /* send a packet to myself -- will never get received, of course */
1094 newpkt.source = newpkt.dest = dev->dev_addr[0];
1095
1096 /* only one byte of actual data (and it's random) */
1097 newpkt.offset[0] = 0xFF;
1098
1099 lp->hw.copy_to_card(dev, bufnum, 0, &newpkt, ARC_HDR_SIZE);
1100
1101 return 1; /* done */
1102}
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 @@
1/*
2 * Linux ARCnet driver - "cap mode" packet encapsulation.
3 * It adds sequence numbers to packets for communicating between a user space
4 * application and the driver. After a transmit it sends a packet with protocol
5 * byte 0 back up to the userspace containing the sequence number of the packet
6 * plus the transmit-status on the ArcNet.
7 *
8 * Written 2002-4 by Esben Nielsen, Vestas Wind Systems A/S
9 * Derived from arc-rawmode.c by Avery Pennarun.
10 * arc-rawmode was in turned based on skeleton.c, see below.
11 *
12 * **********************
13 *
14 * The original copyright of skeleton.c was as follows:
15 *
16 * skeleton.c Written 1993 by Donald Becker.
17 * Copyright 1993 United States Government as represented by the
18 * Director, National Security Agency. This software may only be used
19 * and distributed according to the terms of the GNU General Public License as
20 * modified by SRC, incorporated herein by reference.
21 *
22 * **********************
23 *
24 * For more details, see drivers/net/arcnet.c
25 *
26 * **********************
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/if_arp.h>
32#include <net/arp.h>
33#include <linux/netdevice.h>
34#include <linux/skbuff.h>
35#include <linux/arcdevice.h>
36
37#define VERSION "arcnet: cap mode (`c') encapsulation support loaded.\n"
38
39
40static void rx(struct net_device *dev, int bufnum,
41 struct archdr *pkthdr, int length);
42static int build_header(struct sk_buff *skb,
43 struct net_device *dev,
44 unsigned short type,
45 uint8_t daddr);
46static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
47 int bufnum);
48static int ack_tx(struct net_device *dev, int acked);
49
50
51struct ArcProto capmode_proto =
52{
53 'r',
54 XMTU,
55 0,
56 rx,
57 build_header,
58 prepare_tx,
59 NULL,
60 ack_tx
61};
62
63
64void arcnet_cap_init(void)
65{
66 int count;
67
68 for (count = 1; count <= 8; count++)
69 if (arc_proto_map[count] == arc_proto_default)
70 arc_proto_map[count] = &capmode_proto;
71
72 /* for cap mode, we only set the bcast proto if there's no better one */
73 if (arc_bcast_proto == arc_proto_default)
74 arc_bcast_proto = &capmode_proto;
75
76 arc_proto_default = &capmode_proto;
77 arc_raw_proto = &capmode_proto;
78}
79
80
81#ifdef MODULE
82
83int __init init_module(void)
84{
85 printk(VERSION);
86 arcnet_cap_init();
87 return 0;
88}
89
90void cleanup_module(void)
91{
92 arcnet_unregister_proto(&capmode_proto);
93}
94
95MODULE_LICENSE("GPL");
96#endif /* MODULE */
97
98
99
100/* packet receiver */
101static void rx(struct net_device *dev, int bufnum,
102 struct archdr *pkthdr, int length)
103{
104 struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
105 struct sk_buff *skb;
106 struct archdr *pkt = pkthdr;
107 char *pktbuf, *pkthdrbuf;
108 int ofs;
109
110 BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length);
111
112 if (length >= MinTU)
113 ofs = 512 - length;
114 else
115 ofs = 256 - length;
116
117 skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
118 if (skb == NULL) {
119 BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
120 lp->stats.rx_dropped++;
121 return;
122 }
123 skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
124 skb->dev = dev;
125
126 pkt = (struct archdr *) skb->data;
127
128 skb->mac.raw = skb->data;
129 skb_pull(skb, ARC_HDR_SIZE);
130
131 /* up to sizeof(pkt->soft) has already been copied from the card */
132 /* squeeze in an int for the cap encapsulation */
133
134 /* use these variables to be sure we count in bytes, not in
135 sizeof(struct archdr) */
136 pktbuf=(char*)pkt;
137 pkthdrbuf=(char*)pkthdr;
138 memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto));
139 memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int),
140 pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto),
141 sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto));
142
143 if (length > sizeof(pkt->soft))
144 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
145 pkt->soft.raw + sizeof(pkt->soft)
146 + sizeof(int),
147 length - sizeof(pkt->soft));
148
149 BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
150
151 skb->protocol = __constant_htons(ETH_P_ARCNET);
152;
153 netif_rx(skb);
154 dev->last_rx = jiffies;
155}
156
157
158/*
159 * Create the ARCnet hard/soft headers for cap mode.
160 * There aren't any soft headers in cap mode - not even the protocol id.
161 */
162static int build_header(struct sk_buff *skb,
163 struct net_device *dev,
164 unsigned short type,
165 uint8_t daddr)
166{
167 int hdr_size = ARC_HDR_SIZE;
168 struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
169
170 BUGMSG(D_PROTO, "Preparing header for cap packet %x.\n",
171 *((int*)&pkt->soft.cap.cookie[0]));
172 /*
173 * Set the source hardware address.
174 *
175 * This is pretty pointless for most purposes, but it can help in
176 * debugging. ARCnet does not allow us to change the source address in
177 * the actual packet sent)
178 */
179 pkt->hard.source = *dev->dev_addr;
180
181 /* see linux/net/ethernet/eth.c to see where I got the following */
182
183 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
184 /*
185 * FIXME: fill in the last byte of the dest ipaddr here to better
186 * comply with RFC1051 in "noarp" mode.
187 */
188 pkt->hard.dest = 0;
189 return hdr_size;
190 }
191 /* otherwise, just fill it in and go! */
192 pkt->hard.dest = daddr;
193
194 return hdr_size; /* success */
195}
196
197
198static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
199 int bufnum)
200{
201 struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
202 struct arc_hardware *hard = &pkt->hard;
203 int ofs;
204
205
206 /* hard header is not included in packet length */
207 length -= ARC_HDR_SIZE;
208 /* And neither is the cookie field */
209 length -= sizeof(int);
210
211 BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
212 lp->next_tx, lp->cur_tx, bufnum);
213
214 BUGMSG(D_PROTO, "Sending for cap packet %x.\n",
215 *((int*)&pkt->soft.cap.cookie[0]));
216
217 if (length > XMTU) {
218 /* should never happen! other people already check for this. */
219 BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
220 length, XMTU);
221 length = XMTU;
222 }
223 if (length > MinTU) {
224 hard->offset[0] = 0;
225 hard->offset[1] = ofs = 512 - length;
226 } else if (length > MTU) {
227 hard->offset[0] = 0;
228 hard->offset[1] = ofs = 512 - length - 3;
229 } else
230 hard->offset[0] = ofs = 256 - length;
231
232 BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
233 length,ofs);
234
235 // Copy the arcnet-header + the protocol byte down:
236 lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
237 lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto,
238 sizeof(pkt->soft.cap.proto));
239
240 // Skip the extra integer we have written into it as a cookie
241 // but write the rest of the message:
242 lp->hw.copy_to_card(dev, bufnum, ofs+1,
243 ((unsigned char*)&pkt->soft.cap.mes),length-1);
244
245 lp->lastload_dest = hard->dest;
246
247 return 1; /* done */
248}
249
250
251static int ack_tx(struct net_device *dev, int acked)
252{
253 struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
254 struct sk_buff *ackskb;
255 struct archdr *ackpkt;
256 int length=sizeof(struct arc_cap);
257
258 BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n",
259 lp->outgoing.skb->protocol, acked);
260
261 BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
262
263 /* Now alloc a skb to send back up through the layers: */
264 ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC);
265 if (ackskb == NULL) {
266 BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n");
267 goto free_outskb;
268 }
269
270 skb_put(ackskb, length + ARC_HDR_SIZE );
271 ackskb->dev = dev;
272
273 ackpkt = (struct archdr *) ackskb->data;
274
275 ackskb->mac.raw = ackskb->data;
276 /* skb_pull(ackskb, ARC_HDR_SIZE); */
277
278
279 memcpy(ackpkt, lp->outgoing.skb->data, ARC_HDR_SIZE+sizeof(struct arc_cap));
280 ackpkt->soft.cap.proto=0; /* using protocol 0 for acknowledge */
281 ackpkt->soft.cap.mes.ack=acked;
282
283 BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
284 *((int*)&ackpkt->soft.cap.cookie[0]));
285
286 ackskb->protocol = __constant_htons(ETH_P_ARCNET);
287
288 BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
289 netif_rx(ackskb);
290
291 free_outskb:
292 dev_kfree_skb_irq(lp->outgoing.skb);
293 lp->outgoing.proto = NULL; /* We are always finished when in this protocol */
294
295 return 0;
296}
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
new file mode 100644
index 000000000000..9289e6103de5
--- /dev/null
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -0,0 +1,219 @@
1/*
2 * Linux ARCnet driver - COM20020 chipset support
3 *
4 * Written 1997 by David Woodhouse.
5 * Written 1994-1999 by Avery Pennarun.
6 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
7 * Derived from skeleton.c by Donald Becker.
8 *
9 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
10 * for sponsoring the further development of this driver.
11 *
12 * **********************
13 *
14 * The original copyright of skeleton.c was as follows:
15 *
16 * skeleton.c Written 1993 by Donald Becker.
17 * Copyright 1993 United States Government as represented by the
18 * Director, National Security Agency. This software may only be used
19 * and distributed according to the terms of the GNU General Public License as
20 * modified by SRC, incorporated herein by reference.
21 *
22 * **********************
23 *
24 * For more details, see drivers/net/arcnet.c
25 *
26 * **********************
27 */
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/kernel.h>
31#include <linux/types.h>
32#include <linux/ioport.h>
33#include <linux/slab.h>
34#include <linux/errno.h>
35#include <linux/delay.h>
36#include <linux/netdevice.h>
37#include <linux/init.h>
38#include <linux/bootmem.h>
39#include <linux/arcdevice.h>
40#include <linux/com20020.h>
41
42#include <asm/io.h>
43
44#define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n"
45
46
47/*
48 * We cannot (yet) probe for an IO mapped card, although we can check that
49 * it's where we were told it was, and even do autoirq.
50 */
51static int __init com20020isa_probe(struct net_device *dev)
52{
53 int ioaddr;
54 unsigned long airqmask;
55 struct arcnet_local *lp = dev->priv;
56 int err;
57
58 BUGLVL(D_NORMAL) printk(VERSION);
59
60 ioaddr = dev->base_addr;
61 if (!ioaddr) {
62 BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you "
63 "must specify the base address!\n");
64 return -ENODEV;
65 }
66 if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
67 BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
68 ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
69 return -ENXIO;
70 }
71 if (ASTATUS() == 0xFF) {
72 BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
73 err = -ENODEV;
74 goto out;
75 }
76 if (com20020_check(dev)) {
77 err = -ENODEV;
78 goto out;
79 }
80
81 if (!dev->irq) {
82 /* if we do this, we're sure to get an IRQ since the
83 * card has just reset and the NORXflag is on until
84 * we tell it to start receiving.
85 */
86 BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK));
87 outb(0, _INTMASK);
88 airqmask = probe_irq_on();
89 outb(NORXflag, _INTMASK);
90 udelay(1);
91 outb(0, _INTMASK);
92 dev->irq = probe_irq_off(airqmask);
93
94 if (dev->irq <= 0) {
95 BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
96 airqmask = probe_irq_on();
97 outb(NORXflag, _INTMASK);
98 udelay(5);
99 outb(0, _INTMASK);
100 dev->irq = probe_irq_off(airqmask);
101 if (dev->irq <= 0) {
102 BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
103 err = -ENODEV;
104 goto out;
105 }
106 }
107 }
108
109 lp->card_name = "ISA COM20020";
110 if ((err = com20020_found(dev, 0)) != 0)
111 goto out;
112
113 return 0;
114
115out:
116 release_region(ioaddr, ARCNET_TOTAL_SIZE);
117 return err;
118}
119
120static int node = 0;
121static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
122static int irq = 0; /* or use the insmod io= irq= shmem= options */
123static char device[9]; /* use eg. device="arc1" to change name */
124static int timeout = 3;
125static int backplane = 0;
126static int clockp = 0;
127static int clockm = 0;
128
129module_param(node, int, 0);
130module_param(io, int, 0);
131module_param(irq, int, 0);
132module_param_string(device, device, sizeof(device), 0);
133module_param(timeout, int, 0);
134module_param(backplane, int, 0);
135module_param(clockp, int, 0);
136module_param(clockm, int, 0);
137
138MODULE_LICENSE("GPL");
139
140static struct net_device *my_dev;
141
142static int __init com20020_init(void)
143{
144 struct net_device *dev;
145 struct arcnet_local *lp;
146
147 dev = alloc_arcdev(device);
148 if (!dev)
149 return -ENOMEM;
150
151 if (node && node != 0xff)
152 dev->dev_addr[0] = node;
153
154 lp = dev->priv;
155 lp->backplane = backplane;
156 lp->clockp = clockp & 7;
157 lp->clockm = clockm & 3;
158 lp->timeout = timeout & 3;
159 lp->hw.owner = THIS_MODULE;
160
161 dev->base_addr = io;
162 dev->irq = irq;
163
164 if (dev->irq == 2)
165 dev->irq = 9;
166
167 if (com20020isa_probe(dev)) {
168 free_netdev(dev);
169 return -EIO;
170 }
171
172 my_dev = dev;
173 return 0;
174}
175
176static void __exit com20020_exit(void)
177{
178 unregister_netdev(my_dev);
179 free_irq(my_dev->irq, my_dev);
180 release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
181 free_netdev(my_dev);
182}
183
184#ifndef MODULE
185static int __init com20020isa_setup(char *s)
186{
187 int ints[8];
188
189 s = get_options(s, 8, ints);
190 if (!ints[0])
191 return 1;
192
193 switch (ints[0]) {
194 default: /* ERROR */
195 printk("com90xx: Too many arguments.\n");
196 case 6: /* Timeout */
197 timeout = ints[6];
198 case 5: /* CKP value */
199 clockp = ints[5];
200 case 4: /* Backplane flag */
201 backplane = ints[4];
202 case 3: /* Node ID */
203 node = ints[3];
204 case 2: /* IRQ */
205 irq = ints[2];
206 case 1: /* IO address */
207 io = ints[1];
208 }
209 if (*s)
210 snprintf(device, sizeof(device), "%s", s);
211 return 1;
212}
213
214__setup("com20020=", com20020isa_setup);
215
216#endif /* MODULE */
217
218module_init(com20020_init)
219module_exit(com20020_exit)
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
new file mode 100644
index 000000000000..96636ca8754e
--- /dev/null
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -0,0 +1,189 @@
1/*
2 * Linux ARCnet driver - COM20020 PCI support
3 * Contemporary Controls PCI20 and SOHARD SH-ARC PCI
4 *
5 * Written 1994-1999 by Avery Pennarun,
6 * based on an ISA version by David Woodhouse.
7 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
8 * Derived from skeleton.c by Donald Becker.
9 *
10 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
11 * for sponsoring the further development of this driver.
12 *
13 * **********************
14 *
15 * The original copyright of skeleton.c was as follows:
16 *
17 * skeleton.c Written 1993 by Donald Becker.
18 * Copyright 1993 United States Government as represented by the
19 * Director, National Security Agency. This software may only be used
20 * and distributed according to the terms of the GNU General Public License as
21 * modified by SRC, incorporated herein by reference.
22 *
23 * **********************
24 *
25 * For more details, see drivers/net/arcnet.c
26 *
27 * **********************
28 */
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/ioport.h>
34#include <linux/slab.h>
35#include <linux/errno.h>
36#include <linux/netdevice.h>
37#include <linux/init.h>
38#include <linux/pci.h>
39#include <linux/arcdevice.h>
40#include <linux/com20020.h>
41
42#include <asm/io.h>
43
44
45#define VERSION "arcnet: COM20020 PCI support\n"
46
47/* Module parameters */
48
49static int node;
50static char device[9]; /* use eg. device="arc1" to change name */
51static int timeout = 3;
52static int backplane;
53static int clockp;
54static int clockm;
55
56module_param(node, int, 0);
57module_param_string(device, device, sizeof(device), 0);
58module_param(timeout, int, 0);
59module_param(backplane, int, 0);
60module_param(clockp, int, 0);
61module_param(clockm, int, 0);
62MODULE_LICENSE("GPL");
63
64static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
65{
66 struct net_device *dev;
67 struct arcnet_local *lp;
68 int ioaddr, err;
69
70 if (pci_enable_device(pdev))
71 return -EIO;
72 dev = alloc_arcdev(device);
73 if (!dev)
74 return -ENOMEM;
75 lp = dev->priv;
76
77 pci_set_drvdata(pdev, dev);
78
79 // SOHARD needs PCI base addr 4
80 if (pdev->vendor==0x10B5) {
81 BUGMSG(D_NORMAL, "SOHARD\n");
82 ioaddr = pci_resource_start(pdev, 4);
83 }
84 else {
85 BUGMSG(D_NORMAL, "Contemporary Controls\n");
86 ioaddr = pci_resource_start(pdev, 2);
87 }
88
89 if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
90 BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
91 ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
92 err = -EBUSY;
93 goto out_dev;
94 }
95
96 // Dummy access after Reset
97 // ARCNET controller needs this access to detect bustype
98 outb(0x00,ioaddr+1);
99 inb(ioaddr+1);
100
101 dev->base_addr = ioaddr;
102 dev->irq = pdev->irq;
103 dev->dev_addr[0] = node;
104 lp->card_name = "PCI COM20020";
105 lp->card_flags = id->driver_data;
106 lp->backplane = backplane;
107 lp->clockp = clockp & 7;
108 lp->clockm = clockm & 3;
109 lp->timeout = timeout;
110 lp->hw.owner = THIS_MODULE;
111
112 if (ASTATUS() == 0xFF) {
113 BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
114 "but seems empty!\n", ioaddr);
115 err = -EIO;
116 goto out_port;
117 }
118 if (com20020_check(dev)) {
119 err = -EIO;
120 goto out_port;
121 }
122
123 if ((err = com20020_found(dev, SA_SHIRQ)) != 0)
124 goto out_port;
125
126 return 0;
127
128out_port:
129 release_region(ioaddr, ARCNET_TOTAL_SIZE);
130out_dev:
131 free_netdev(dev);
132 return err;
133}
134
135static void __devexit com20020pci_remove(struct pci_dev *pdev)
136{
137 struct net_device *dev = pci_get_drvdata(pdev);
138 unregister_netdev(dev);
139 free_irq(dev->irq, dev);
140 release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
141 free_netdev(dev);
142}
143
144static struct pci_device_id com20020pci_id_table[] = {
145 { 0x1571, 0xa001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
146 { 0x1571, 0xa002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
147 { 0x1571, 0xa003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
148 { 0x1571, 0xa004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
149 { 0x1571, 0xa005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
150 { 0x1571, 0xa006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
151 { 0x1571, 0xa007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
152 { 0x1571, 0xa008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
153 { 0x1571, 0xa009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
154 { 0x1571, 0xa00a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
155 { 0x1571, 0xa00b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
156 { 0x1571, 0xa00c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
157 { 0x1571, 0xa00d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
158 { 0x1571, 0xa201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
159 { 0x1571, 0xa202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
160 { 0x1571, 0xa203, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
161 { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
162 { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
163 { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
164 { 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
165 {0,}
166};
167
168MODULE_DEVICE_TABLE(pci, com20020pci_id_table);
169
170static struct pci_driver com20020pci_driver = {
171 .name = "com20020",
172 .id_table = com20020pci_id_table,
173 .probe = com20020pci_probe,
174 .remove = __devexit_p(com20020pci_remove),
175};
176
177static int __init com20020pci_init(void)
178{
179 BUGLVL(D_NORMAL) printk(VERSION);
180 return pci_module_init(&com20020pci_driver);
181}
182
183static void __exit com20020pci_cleanup(void)
184{
185 pci_unregister_driver(&com20020pci_driver);
186}
187
188module_init(com20020pci_init)
189module_exit(com20020pci_cleanup)
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
new file mode 100644
index 000000000000..0dc70c7b7940
--- /dev/null
+++ b/drivers/net/arcnet/com20020.c
@@ -0,0 +1,357 @@
1/*
2 * Linux ARCnet driver - COM20020 chipset support
3 *
4 * Written 1997 by David Woodhouse.
5 * Written 1994-1999 by Avery Pennarun.
6 * Written 1999 by Martin Mares <mj@ucw.cz>.
7 * Derived from skeleton.c by Donald Becker.
8 *
9 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
10 * for sponsoring the further development of this driver.
11 *
12 * **********************
13 *
14 * The original copyright of skeleton.c was as follows:
15 *
16 * skeleton.c Written 1993 by Donald Becker.
17 * Copyright 1993 United States Government as represented by the
18 * Director, National Security Agency. This software may only be used
19 * and distributed according to the terms of the GNU General Public License as
20 * modified by SRC, incorporated herein by reference.
21 *
22 * **********************
23 *
24 * For more details, see drivers/net/arcnet.c
25 *
26 * **********************
27 */
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/ioport.h>
32#include <linux/slab.h>
33#include <linux/errno.h>
34#include <linux/delay.h>
35#include <linux/netdevice.h>
36#include <linux/init.h>
37#include <linux/arcdevice.h>
38#include <linux/com20020.h>
39
40#include <asm/io.h>
41
42#define VERSION "arcnet: COM20020 chipset support (by David Woodhouse et al.)\n"
43
44static char *clockrates[] =
45{"10 Mb/s", "Reserved", "5 Mb/s",
46 "2.5 Mb/s", "1.25Mb/s", "625 Kb/s", "312.5 Kb/s",
47 "156.25 Kb/s", "Reserved", "Reserved", "Reserved"};
48
49static void com20020_command(struct net_device *dev, int command);
50static int com20020_status(struct net_device *dev);
51static void com20020_setmask(struct net_device *dev, int mask);
52static int com20020_reset(struct net_device *dev, int really_reset);
53static void com20020_copy_to_card(struct net_device *dev, int bufnum,
54 int offset, void *buf, int count);
55static void com20020_copy_from_card(struct net_device *dev, int bufnum,
56 int offset, void *buf, int count);
57static void com20020_set_mc_list(struct net_device *dev);
58static void com20020_close(struct net_device *);
59
60static void com20020_copy_from_card(struct net_device *dev, int bufnum,
61 int offset, void *buf, int count)
62{
63 int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
64
65 /* set up the address register */
66 outb((ofs >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
67 outb(ofs & 0xff, _ADDR_LO);
68
69 /* copy the data */
70 TIME("insb", count, insb(_MEMDATA, buf, count));
71}
72
73
74static void com20020_copy_to_card(struct net_device *dev, int bufnum,
75 int offset, void *buf, int count)
76{
77 int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
78
79 /* set up the address register */
80 outb((ofs >> 8) | AUTOINCflag, _ADDR_HI);
81 outb(ofs & 0xff, _ADDR_LO);
82
83 /* copy the data */
84 TIME("outsb", count, outsb(_MEMDATA, buf, count));
85}
86
87
88/* Reset the card and check some basic stuff during the detection stage. */
89int com20020_check(struct net_device *dev)
90{
91 int ioaddr = dev->base_addr, status;
92 struct arcnet_local *lp = dev->priv;
93
94 ARCRESET0;
95 mdelay(RESETtime);
96
97 lp->setup = lp->clockm ? 0 : (lp->clockp << 1);
98 lp->setup2 = (lp->clockm << 4) | 8;
99
100 /* CHECK: should we do this for SOHARD cards ? */
101 /* Enable P1Mode for backplane mode */
102 lp->setup = lp->setup | P1MODE;
103
104 SET_SUBADR(SUB_SETUP1);
105 outb(lp->setup, _XREG);
106
107 if (lp->card_flags & ARC_CAN_10MBIT)
108 {
109 SET_SUBADR(SUB_SETUP2);
110 outb(lp->setup2, _XREG);
111
112 /* must now write the magic "restart operation" command */
113 mdelay(1);
114 outb(0x18, _COMMAND);
115 }
116
117 lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
118 /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
119 SETCONF;
120 outb(0x42, ioaddr + BUS_ALIGN*7);
121
122 status = ASTATUS();
123
124 if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag)) {
125 BUGMSG(D_NORMAL, "status invalid (%Xh).\n", status);
126 return -ENODEV;
127 }
128 BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status);
129
130 /* Enable TX */
131 outb(0x39, _CONFIG);
132 outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7);
133
134 ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
135
136 status = ASTATUS();
137 BUGMSG(D_INIT_REASONS, "status after reset acknowledged: %X\n",
138 status);
139
140 /* Read first location of memory */
141 outb(0 | RDDATAflag | AUTOINCflag, _ADDR_HI);
142 outb(0, _ADDR_LO);
143
144 if ((status = inb(_MEMDATA)) != TESTvalue) {
145 BUGMSG(D_NORMAL, "Signature byte not found (%02Xh != D1h).\n",
146 status);
147 return -ENODEV;
148 }
149 return 0;
150}
151
152/* Set up the struct net_device associated with this card. Called after
153 * probing succeeds.
154 */
155int com20020_found(struct net_device *dev, int shared)
156{
157 struct arcnet_local *lp;
158 int ioaddr = dev->base_addr;
159
160 /* Initialize the rest of the device structure. */
161
162 lp = dev->priv;
163
164 lp->hw.owner = THIS_MODULE;
165 lp->hw.command = com20020_command;
166 lp->hw.status = com20020_status;
167 lp->hw.intmask = com20020_setmask;
168 lp->hw.reset = com20020_reset;
169 lp->hw.copy_to_card = com20020_copy_to_card;
170 lp->hw.copy_from_card = com20020_copy_from_card;
171 lp->hw.close = com20020_close;
172
173 dev->set_multicast_list = com20020_set_mc_list;
174
175 if (!dev->dev_addr[0])
176 dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */
177
178 SET_SUBADR(SUB_SETUP1);
179 outb(lp->setup, _XREG);
180
181 if (lp->card_flags & ARC_CAN_10MBIT)
182 {
183 SET_SUBADR(SUB_SETUP2);
184 outb(lp->setup2, _XREG);
185
186 /* must now write the magic "restart operation" command */
187 mdelay(1);
188 outb(0x18, _COMMAND);
189 }
190
191 lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1;
192 /* Default 0x38 + register: Node ID */
193 SETCONF;
194 outb(dev->dev_addr[0], _XREG);
195
196 /* reserve the irq */
197 if (request_irq(dev->irq, &arcnet_interrupt, shared,
198 "arcnet (COM20020)", dev)) {
199 BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
200 return -ENODEV;
201 }
202
203 dev->base_addr = ioaddr;
204
205 BUGMSG(D_NORMAL, "%s: station %02Xh found at %03lXh, IRQ %d.\n",
206 lp->card_name, dev->dev_addr[0], dev->base_addr, dev->irq);
207
208 if (lp->backplane)
209 BUGMSG(D_NORMAL, "Using backplane mode.\n");
210
211 if (lp->timeout != 3)
212 BUGMSG(D_NORMAL, "Using extended timeout value of %d.\n", lp->timeout);
213
214 BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
215 lp->setup >> 1,
216 clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
217
218 if (register_netdev(dev)) {
219 free_irq(dev->irq, dev);
220 return -EIO;
221 }
222 return 0;
223}
224
225
226/*
227 * Do a hardware reset on the card, and set up necessary registers.
228 *
229 * This should be called as little as possible, because it disrupts the
230 * token on the network (causes a RECON) and requires a significant delay.
231 *
232 * However, it does make sure the card is in a defined state.
233 */
234static int com20020_reset(struct net_device *dev, int really_reset)
235{
236 struct arcnet_local *lp = dev->priv;
237 u_int ioaddr = dev->base_addr;
238 u_char inbyte;
239
240 BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
241 __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name);
242 BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
243 dev->name, ASTATUS());
244
245 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
246 lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
247 /* power-up defaults */
248 SETCONF;
249 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
250
251 if (really_reset) {
252 /* reset the card */
253 ARCRESET;
254 mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */
255 }
256 /* clear flags & end reset */
257 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
258 ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
259
260 /* verify that the ARCnet signature byte is present */
261 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
262
263 com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
264 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
265 if (inbyte != TESTvalue) {
266 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
267 BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
268 return 1;
269 }
270 /* enable extended (512-byte) packets */
271 ACOMMAND(CONFIGcmd | EXTconf);
272 BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
273
274 /* done! return success. */
275 return 0;
276}
277
278
279static void com20020_setmask(struct net_device *dev, int mask)
280{
281 u_int ioaddr = dev->base_addr;
282 BUGMSG(D_DURING, "Setting mask to %x at %x\n",mask,ioaddr);
283 AINTMASK(mask);
284}
285
286
287static void com20020_command(struct net_device *dev, int cmd)
288{
289 u_int ioaddr = dev->base_addr;
290 ACOMMAND(cmd);
291}
292
293
294static int com20020_status(struct net_device *dev)
295{
296 u_int ioaddr = dev->base_addr;
297
298 return ASTATUS() + (ADIAGSTATUS()<<8);
299}
300
301static void com20020_close(struct net_device *dev)
302{
303 struct arcnet_local *lp = dev->priv;
304 int ioaddr = dev->base_addr;
305
306 /* disable transmitter */
307 lp->config &= ~TXENcfg;
308 SETCONF;
309}
310
311/* Set or clear the multicast filter for this adaptor.
312 * num_addrs == -1 Promiscuous mode, receive all packets
313 * num_addrs == 0 Normal mode, clear multicast list
314 * num_addrs > 0 Multicast mode, receive normal and MC packets, and do
315 * best-effort filtering.
316 * FIXME - do multicast stuff, not just promiscuous.
317 */
318static void com20020_set_mc_list(struct net_device *dev)
319{
320 struct arcnet_local *lp = dev->priv;
321 int ioaddr = dev->base_addr;
322
323 if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) { /* Enable promiscuous mode */
324 if (!(lp->setup & PROMISCset))
325 BUGMSG(D_NORMAL, "Setting promiscuous flag...\n");
326 SET_SUBADR(SUB_SETUP1);
327 lp->setup |= PROMISCset;
328 outb(lp->setup, _XREG);
329 } else
330 /* Disable promiscuous mode, use normal mode */
331 {
332 if ((lp->setup & PROMISCset))
333 BUGMSG(D_NORMAL, "Resetting promiscuous flag...\n");
334 SET_SUBADR(SUB_SETUP1);
335 lp->setup &= ~PROMISCset;
336 outb(lp->setup, _XREG);
337 }
338}
339
340#ifdef MODULE
341
342EXPORT_SYMBOL(com20020_check);
343EXPORT_SYMBOL(com20020_found);
344
345MODULE_LICENSE("GPL");
346
347int init_module(void)
348{
349 BUGLVL(D_NORMAL) printk(VERSION);
350 return 0;
351}
352
353void cleanup_module(void)
354{
355}
356
357#endif /* MODULE */
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
new file mode 100644
index 000000000000..52c77cbe8c62
--- /dev/null
+++ b/drivers/net/arcnet/com90io.c
@@ -0,0 +1,435 @@
1/*
2 * Linux ARCnet driver - COM90xx chipset (IO-mapped buffers)
3 *
4 * Written 1997 by David Woodhouse.
5 * Written 1994-1999 by Avery Pennarun.
6 * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
7 * Derived from skeleton.c by Donald Becker.
8 *
9 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
10 * for sponsoring the further development of this driver.
11 *
12 * **********************
13 *
14 * The original copyright of skeleton.c was as follows:
15 *
16 * skeleton.c Written 1993 by Donald Becker.
17 * Copyright 1993 United States Government as represented by the
18 * Director, National Security Agency. This software may only be used
19 * and distributed according to the terms of the GNU General Public License as
20 * modified by SRC, incorporated herein by reference.
21 *
22 * **********************
23 *
24 * For more details, see drivers/net/arcnet.c
25 *
26 * **********************
27 */
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/ioport.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34#include <linux/netdevice.h>
35#include <linux/bootmem.h>
36#include <linux/init.h>
37#include <asm/io.h>
38#include <linux/arcdevice.h>
39
40
41#define VERSION "arcnet: COM90xx IO-mapped mode support (by David Woodhouse et el.)\n"
42
43
44/* Internal function declarations */
45
46static int com90io_found(struct net_device *dev);
47static void com90io_command(struct net_device *dev, int command);
48static int com90io_status(struct net_device *dev);
49static void com90io_setmask(struct net_device *dev, int mask);
50static int com90io_reset(struct net_device *dev, int really_reset);
51static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
52 void *buf, int count);
53static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
54 void *buf, int count);
55
56
57/* Handy defines for ARCnet specific stuff */
58
59/* The number of low I/O ports used by the card. */
60#define ARCNET_TOTAL_SIZE 16
61
62/* COM 9026 controller chip --> ARCnet register addresses */
63#define _INTMASK (ioaddr+0) /* writable */
64#define _STATUS (ioaddr+0) /* readable */
65#define _COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
66#define _RESET (ioaddr+8) /* software reset (on read) */
67#define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */
68#define _ADDR_HI (ioaddr+15) /* Control registers for said */
69#define _ADDR_LO (ioaddr+14)
70#define _CONFIG (ioaddr+2) /* Configuration register */
71
72#undef ASTATUS
73#undef ACOMMAND
74#undef AINTMASK
75
76#define ASTATUS() inb(_STATUS)
77#define ACOMMAND(cmd) outb((cmd),_COMMAND)
78#define AINTMASK(msk) outb((msk),_INTMASK)
79#define SETCONF() outb((lp->config),_CONFIG)
80
81
82/****************************************************************************
83 * *
84 * IO-mapped operation routines *
85 * *
86 ****************************************************************************/
87
88#undef ONE_AT_A_TIME_TX
89#undef ONE_AT_A_TIME_RX
90
91static u_char get_buffer_byte(struct net_device *dev, unsigned offset)
92{
93 int ioaddr = dev->base_addr;
94
95 outb(offset >> 8, _ADDR_HI);
96 outb(offset & 0xff, _ADDR_LO);
97
98 return inb(_MEMDATA);
99}
100
101#ifdef ONE_AT_A_TIME_TX
102static void put_buffer_byte(struct net_device *dev, unsigned offset, u_char datum)
103{
104 int ioaddr = dev->base_addr;
105
106 outb(offset >> 8, _ADDR_HI);
107 outb(offset & 0xff, _ADDR_LO);
108
109 outb(datum, _MEMDATA);
110}
111
112#endif
113
114
115static void get_whole_buffer(struct net_device *dev, unsigned offset, unsigned length, char *dest)
116{
117 int ioaddr = dev->base_addr;
118
119 outb((offset >> 8) | AUTOINCflag, _ADDR_HI);
120 outb(offset & 0xff, _ADDR_LO);
121
122 while (length--)
123#ifdef ONE_AT_A_TIME_RX
124 *(dest++) = get_buffer_byte(dev, offset++);
125#else
126 *(dest++) = inb(_MEMDATA);
127#endif
128}
129
130static void put_whole_buffer(struct net_device *dev, unsigned offset, unsigned length, char *dest)
131{
132 int ioaddr = dev->base_addr;
133
134 outb((offset >> 8) | AUTOINCflag, _ADDR_HI);
135 outb(offset & 0xff, _ADDR_LO);
136
137 while (length--)
138#ifdef ONE_AT_A_TIME_TX
139 put_buffer_byte(dev, offset++, *(dest++));
140#else
141 outb(*(dest++), _MEMDATA);
142#endif
143}
144
145/*
146 * We cannot probe for an IO mapped card either, although we can check that
147 * it's where we were told it was, and even autoirq
148 */
149static int __init com90io_probe(struct net_device *dev)
150{
151 int ioaddr = dev->base_addr, status;
152 unsigned long airqmask;
153
154 BUGLVL(D_NORMAL) printk(VERSION);
155 BUGLVL(D_NORMAL) printk("E-mail me if you actually test this driver, please!\n");
156
157 if (!ioaddr) {
158 BUGMSG(D_NORMAL, "No autoprobe for IO mapped cards; you "
159 "must specify the base address!\n");
160 return -ENODEV;
161 }
162 if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) {
163 BUGMSG(D_INIT_REASONS, "IO check_region %x-%x failed.\n",
164 ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
165 return -ENXIO;
166 }
167 if (ASTATUS() == 0xFF) {
168 BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr);
169 goto err_out;
170 }
171 inb(_RESET);
172 mdelay(RESETtime);
173
174 status = ASTATUS();
175
176 if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
177 BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status);
178 goto err_out;
179 }
180 BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status);
181
182 ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
183
184 BUGMSG(D_INIT_REASONS, "Status after reset acknowledged: %X\n", status);
185
186 status = ASTATUS();
187
188 if (status & RESETflag) {
189 BUGMSG(D_INIT_REASONS, "Eternal reset (status=%Xh)\n", status);
190 goto err_out;
191 }
192 outb((0x16 | IOMAPflag) & ~ENABLE16flag, _CONFIG);
193
194 /* Read first loc'n of memory */
195
196 outb(AUTOINCflag, _ADDR_HI);
197 outb(0, _ADDR_LO);
198
199 if ((status = inb(_MEMDATA)) != 0xd1) {
200 BUGMSG(D_INIT_REASONS, "Signature byte not found"
201 " (%Xh instead).\n", status);
202 goto err_out;
203 }
204 if (!dev->irq) {
205 /*
206 * if we do this, we're sure to get an IRQ since the
207 * card has just reset and the NORXflag is on until
208 * we tell it to start receiving.
209 */
210
211 airqmask = probe_irq_on();
212 outb(NORXflag, _INTMASK);
213 udelay(1);
214 outb(0, _INTMASK);
215 dev->irq = probe_irq_off(airqmask);
216
217 if (dev->irq <= 0) {
218 BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed\n");
219 goto err_out;
220 }
221 }
222 release_region(ioaddr, ARCNET_TOTAL_SIZE); /* end of probing */
223 return com90io_found(dev);
224
225err_out:
226 release_region(ioaddr, ARCNET_TOTAL_SIZE);
227 return -ENODEV;
228}
229
230
231/* Set up the struct net_device associated with this card. Called after
232 * probing succeeds.
233 */
234static int __init com90io_found(struct net_device *dev)
235{
236 struct arcnet_local *lp;
237 int ioaddr = dev->base_addr;
238 int err;
239
240 /* Reserve the irq */
241 if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
242 BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
243 return -ENODEV;
244 }
245 /* Reserve the I/O region - guaranteed to work by check_region */
246 if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)")) {
247 free_irq(dev->irq, dev);
248 return -EBUSY;
249 }
250
251 lp = dev->priv;
252 lp->card_name = "COM90xx I/O";
253 lp->hw.command = com90io_command;
254 lp->hw.status = com90io_status;
255 lp->hw.intmask = com90io_setmask;
256 lp->hw.reset = com90io_reset;
257 lp->hw.owner = THIS_MODULE;
258 lp->hw.copy_to_card = com90io_copy_to_card;
259 lp->hw.copy_from_card = com90io_copy_from_card;
260
261 lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag;
262 SETCONF();
263
264 /* get and check the station ID from offset 1 in shmem */
265
266 dev->dev_addr[0] = get_buffer_byte(dev, 1);
267
268 err = register_netdev(dev);
269 if (err) {
270 outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
271 free_irq(dev->irq, dev);
272 release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
273 return err;
274 }
275
276 BUGMSG(D_NORMAL, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
277 dev->dev_addr[0], dev->base_addr, dev->irq);
278
279 return 0;
280}
281
282
283/*
284 * Do a hardware reset on the card, and set up necessary registers.
285 *
286 * This should be called as little as possible, because it disrupts the
287 * token on the network (causes a RECON) and requires a significant delay.
288 *
289 * However, it does make sure the card is in a defined state.
290 */
291static int com90io_reset(struct net_device *dev, int really_reset)
292{
293 struct arcnet_local *lp = dev->priv;
294 short ioaddr = dev->base_addr;
295
296 BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
297
298 if (really_reset) {
299 /* reset the card */
300 inb(_RESET);
301 mdelay(RESETtime);
302 }
303 /* Set the thing to IO-mapped, 8-bit mode */
304 lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag;
305 SETCONF();
306
307 ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
308 ACOMMAND(CFLAGScmd | CONFIGclear);
309
310 /* verify that the ARCnet signature byte is present */
311 if (get_buffer_byte(dev, 0) != TESTvalue) {
312 BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
313 return 1;
314 }
315 /* enable extended (512-byte) packets */
316 ACOMMAND(CONFIGcmd | EXTconf);
317
318 /* done! return success. */
319 return 0;
320}
321
322
323static void com90io_command(struct net_device *dev, int cmd)
324{
325 short ioaddr = dev->base_addr;
326
327 ACOMMAND(cmd);
328}
329
330
331static int com90io_status(struct net_device *dev)
332{
333 short ioaddr = dev->base_addr;
334
335 return ASTATUS();
336}
337
338
339static void com90io_setmask(struct net_device *dev, int mask)
340{
341 short ioaddr = dev->base_addr;
342
343 AINTMASK(mask);
344}
345
346static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
347 void *buf, int count)
348{
349 TIME("put_whole_buffer", count, put_whole_buffer(dev, bufnum * 512 + offset, count, buf));
350}
351
352
353static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
354 void *buf, int count)
355{
356 TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
357}
358
359static int io; /* use the insmod io= irq= shmem= options */
360static int irq;
361static char device[9]; /* use eg. device=arc1 to change name */
362
363module_param(io, int, 0);
364module_param(irq, int, 0);
365module_param_string(device, device, sizeof(device), 0);
366MODULE_LICENSE("GPL");
367
368#ifndef MODULE
369static int __init com90io_setup(char *s)
370{
371 int ints[4];
372 s = get_options(s, 4, ints);
373 if (!ints[0])
374 return 0;
375 switch (ints[0]) {
376 default: /* ERROR */
377 printk("com90io: Too many arguments.\n");
378 case 2: /* IRQ */
379 irq = ints[2];
380 case 1: /* IO address */
381 io = ints[1];
382 }
383 if (*s)
384 snprintf(device, sizeof(device), "%s", s);
385 return 1;
386}
387__setup("com90io=", com90io_setup);
388#endif
389
390static struct net_device *my_dev;
391
392static int __init com90io_init(void)
393{
394 struct net_device *dev;
395 int err;
396
397 dev = alloc_arcdev(device);
398 if (!dev)
399 return -ENOMEM;
400
401 SET_MODULE_OWNER(dev);
402
403 dev->base_addr = io;
404 dev->irq = irq;
405 if (dev->irq == 2)
406 dev->irq = 9;
407
408 err = com90io_probe(dev);
409
410 if (err) {
411 free_netdev(dev);
412 return err;
413 }
414
415 my_dev = dev;
416 return 0;
417}
418
419static void __exit com90io_exit(void)
420{
421 struct net_device *dev = my_dev;
422 int ioaddr = dev->base_addr;
423
424 unregister_netdev(dev);
425
426 /* Set the thing back to MMAP mode, in case the old driver is loaded later */
427 outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
428
429 free_irq(dev->irq, dev);
430 release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
431 free_netdev(dev);
432}
433
434module_init(com90io_init)
435module_exit(com90io_exit)
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
new file mode 100644
index 000000000000..6c2c9b9ac6db
--- /dev/null
+++ b/drivers/net/arcnet/com90xx.c
@@ -0,0 +1,646 @@
1/*
2 * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
3 *
4 * Written 1994-1999 by Avery Pennarun.
5 * Written 1999 by Martin Mares <mj@ucw.cz>.
6 * Derived from skeleton.c by Donald Becker.
7 *
8 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
9 * for sponsoring the further development of this driver.
10 *
11 * **********************
12 *
13 * The original copyright of skeleton.c was as follows:
14 *
15 * skeleton.c Written 1993 by Donald Becker.
16 * Copyright 1993 United States Government as represented by the
17 * Director, National Security Agency. This software may only be used
18 * and distributed according to the terms of the GNU General Public License as
19 * modified by SRC, incorporated herein by reference.
20 *
21 * **********************
22 *
23 * For more details, see drivers/net/arcnet.c
24 *
25 * **********************
26 */
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/ioport.h>
31#include <linux/delay.h>
32#include <linux/netdevice.h>
33#include <asm/io.h>
34#include <linux/arcdevice.h>
35
36
37#define VERSION "arcnet: COM90xx chipset support\n"
38
39
40/* Define this to speed up the autoprobe by assuming if only one io port and
41 * shmem are left in the list at Stage 5, they must correspond to each
42 * other.
43 *
44 * This is undefined by default because it might not always be true, and the
45 * extra check makes the autoprobe even more careful. Speed demons can turn
46 * it on - I think it should be fine if you only have one ARCnet card
47 * installed.
48 *
49 * If no ARCnet cards are installed, this delay never happens anyway and thus
50 * the option has no effect.
51 */
52#undef FAST_PROBE
53
54
55/* Internal function declarations */
56static int com90xx_found(int ioaddr, int airq, u_long shmem);
57static void com90xx_command(struct net_device *dev, int command);
58static int com90xx_status(struct net_device *dev);
59static void com90xx_setmask(struct net_device *dev, int mask);
60static int com90xx_reset(struct net_device *dev, int really_reset);
61static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
62 void *buf, int count);
63static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
64 void *buf, int count);
65
66/* Known ARCnet cards */
67
68static struct net_device *cards[16];
69static int numcards;
70
71/* Handy defines for ARCnet specific stuff */
72
73/* The number of low I/O ports used by the card */
74#define ARCNET_TOTAL_SIZE 16
75
76/* Amount of I/O memory used by the card */
77#define BUFFER_SIZE (512)
78#define MIRROR_SIZE (BUFFER_SIZE*4)
79
80/* COM 9026 controller chip --> ARCnet register addresses */
81#define _INTMASK (ioaddr+0) /* writable */
82#define _STATUS (ioaddr+0) /* readable */
83#define _COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
84#define _CONFIG (ioaddr+2) /* Configuration register */
85#define _RESET (ioaddr+8) /* software reset (on read) */
86#define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */
87#define _ADDR_HI (ioaddr+15) /* Control registers for said */
88#define _ADDR_LO (ioaddr+14)
89
90#undef ASTATUS
91#undef ACOMMAND
92#undef AINTMASK
93
94#define ASTATUS() inb(_STATUS)
95#define ACOMMAND(cmd) outb((cmd),_COMMAND)
96#define AINTMASK(msk) outb((msk),_INTMASK)
97
98
99static int com90xx_skip_probe __initdata = 0;
100
101/* Module parameters */
102
103static int io; /* use the insmod io= irq= shmem= options */
104static int irq;
105static int shmem;
106static char device[9]; /* use eg. device=arc1 to change name */
107
108module_param(io, int, 0);
109module_param(irq, int, 0);
110module_param(shmem, int, 0);
111module_param_string(device, device, sizeof(device), 0);
112
113static void __init com90xx_probe(void)
114{
115 int count, status, ioaddr, numprint, airq, openparen = 0;
116 unsigned long airqmask;
117 int ports[(0x3f0 - 0x200) / 16 + 1] =
118 {0};
119 u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
120 {0};
121 int numports, numshmems, *port;
122 u_long *p;
123
124 if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
125 return;
126
127 BUGLVL(D_NORMAL) printk(VERSION);
128
129 /* set up the arrays where we'll store the possible probe addresses */
130 numports = numshmems = 0;
131 if (io)
132 ports[numports++] = io;
133 else
134 for (count = 0x200; count <= 0x3f0; count += 16)
135 ports[numports++] = count;
136 if (shmem)
137 shmems[numshmems++] = shmem;
138 else
139 for (count = 0xA0000; count <= 0xFF800; count += 2048)
140 shmems[numshmems++] = count;
141
142 /* Stage 1: abandon any reserved ports, or ones with status==0xFF
143 * (empty), and reset any others by reading the reset port.
144 */
145 numprint = -1;
146 for (port = &ports[0]; port - ports < numports; port++) {
147 numprint++;
148 numprint %= 8;
149 if (!numprint) {
150 BUGMSG2(D_INIT, "\n");
151 BUGMSG2(D_INIT, "S1: ");
152 }
153 BUGMSG2(D_INIT, "%Xh ", *port);
154
155 ioaddr = *port;
156
157 if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
158 BUGMSG2(D_INIT_REASONS, "(request_region)\n");
159 BUGMSG2(D_INIT_REASONS, "S1: ");
160 BUGLVL(D_INIT_REASONS) numprint = 0;
161 *port-- = ports[--numports];
162 continue;
163 }
164 if (ASTATUS() == 0xFF) {
165 BUGMSG2(D_INIT_REASONS, "(empty)\n");
166 BUGMSG2(D_INIT_REASONS, "S1: ");
167 BUGLVL(D_INIT_REASONS) numprint = 0;
168 release_region(*port, ARCNET_TOTAL_SIZE);
169 *port-- = ports[--numports];
170 continue;
171 }
172 inb(_RESET); /* begin resetting card */
173
174 BUGMSG2(D_INIT_REASONS, "\n");
175 BUGMSG2(D_INIT_REASONS, "S1: ");
176 BUGLVL(D_INIT_REASONS) numprint = 0;
177 }
178 BUGMSG2(D_INIT, "\n");
179
180 if (!numports) {
181 BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
182 return;
183 }
184 /* Stage 2: we have now reset any possible ARCnet cards, so we can't
185 * do anything until they finish. If D_INIT, print the list of
186 * cards that are left.
187 */
188 numprint = -1;
189 for (port = &ports[0]; port < ports + numports; port++) {
190 numprint++;
191 numprint %= 8;
192 if (!numprint) {
193 BUGMSG2(D_INIT, "\n");
194 BUGMSG2(D_INIT, "S2: ");
195 }
196 BUGMSG2(D_INIT, "%Xh ", *port);
197 }
198 BUGMSG2(D_INIT, "\n");
199 mdelay(RESETtime);
200
201 /* Stage 3: abandon any shmem addresses that don't have the signature
202 * 0xD1 byte in the right place, or are read-only.
203 */
204 numprint = -1;
205 for (p = &shmems[0]; p < shmems + numshmems; p++) {
206 u_long ptr = *p;
207
208 numprint++;
209 numprint %= 8;
210 if (!numprint) {
211 BUGMSG2(D_INIT, "\n");
212 BUGMSG2(D_INIT, "S3: ");
213 }
214 BUGMSG2(D_INIT, "%lXh ", *p);
215
216 if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) {
217 BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n");
218 BUGMSG2(D_INIT_REASONS, "Stage 3: ");
219 BUGLVL(D_INIT_REASONS) numprint = 0;
220 *p-- = shmems[--numshmems];
221 continue;
222 }
223 if (isa_readb(ptr) != TESTvalue) {
224 BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
225 isa_readb(ptr), TESTvalue);
226 BUGMSG2(D_INIT_REASONS, "S3: ");
227 BUGLVL(D_INIT_REASONS) numprint = 0;
228 release_mem_region(*p, BUFFER_SIZE);
229 *p-- = shmems[--numshmems];
230 continue;
231 }
232 /* By writing 0x42 to the TESTvalue location, we also make
233 * sure no "mirror" shmem areas show up - if they occur
234 * in another pass through this loop, they will be discarded
235 * because *cptr != TESTvalue.
236 */
237 isa_writeb(0x42, ptr);
238 if (isa_readb(ptr) != 0x42) {
239 BUGMSG2(D_INIT_REASONS, "(read only)\n");
240 BUGMSG2(D_INIT_REASONS, "S3: ");
241 release_mem_region(*p, BUFFER_SIZE);
242 *p-- = shmems[--numshmems];
243 continue;
244 }
245 BUGMSG2(D_INIT_REASONS, "\n");
246 BUGMSG2(D_INIT_REASONS, "S3: ");
247 BUGLVL(D_INIT_REASONS) numprint = 0;
248 }
249 BUGMSG2(D_INIT, "\n");
250
251 if (!numshmems) {
252 BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
253 for (port = &ports[0]; port < ports + numports; port++)
254 release_region(*port, ARCNET_TOTAL_SIZE);
255 return;
256 }
257 /* Stage 4: something of a dummy, to report the shmems that are
258 * still possible after stage 3.
259 */
260 numprint = -1;
261 for (p = &shmems[0]; p < shmems + numshmems; p++) {
262 numprint++;
263 numprint %= 8;
264 if (!numprint) {
265 BUGMSG2(D_INIT, "\n");
266 BUGMSG2(D_INIT, "S4: ");
267 }
268 BUGMSG2(D_INIT, "%lXh ", *p);
269 }
270 BUGMSG2(D_INIT, "\n");
271
272 /* Stage 5: for any ports that have the correct status, can disable
273 * the RESET flag, and (if no irq is given) generate an autoirq,
274 * register an ARCnet device.
275 *
276 * Currently, we can only register one device per probe, so quit
277 * after the first one is found.
278 */
279 numprint = -1;
280 for (port = &ports[0]; port < ports + numports; port++) {
281 int found = 0;
282 numprint++;
283 numprint %= 8;
284 if (!numprint) {
285 BUGMSG2(D_INIT, "\n");
286 BUGMSG2(D_INIT, "S5: ");
287 }
288 BUGMSG2(D_INIT, "%Xh ", *port);
289
290 ioaddr = *port;
291 status = ASTATUS();
292
293 if ((status & 0x9D)
294 != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
295 BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
296 BUGMSG2(D_INIT_REASONS, "S5: ");
297 BUGLVL(D_INIT_REASONS) numprint = 0;
298 release_region(*port, ARCNET_TOTAL_SIZE);
299 *port-- = ports[--numports];
300 continue;
301 }
302 ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
303 status = ASTATUS();
304 if (status & RESETflag) {
305 BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
306 status);
307 BUGMSG2(D_INIT_REASONS, "S5: ");
308 BUGLVL(D_INIT_REASONS) numprint = 0;
309 release_region(*port, ARCNET_TOTAL_SIZE);
310 *port-- = ports[--numports];
311 continue;
312 }
313 /* skip this completely if an IRQ was given, because maybe
314 * we're on a machine that locks during autoirq!
315 */
316 if (!irq) {
317 /* if we do this, we're sure to get an IRQ since the
318 * card has just reset and the NORXflag is on until
319 * we tell it to start receiving.
320 */
321 airqmask = probe_irq_on();
322 AINTMASK(NORXflag);
323 udelay(1);
324 AINTMASK(0);
325 airq = probe_irq_off(airqmask);
326
327 if (airq <= 0) {
328 BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
329 BUGMSG2(D_INIT_REASONS, "S5: ");
330 BUGLVL(D_INIT_REASONS) numprint = 0;
331 release_region(*port, ARCNET_TOTAL_SIZE);
332 *port-- = ports[--numports];
333 continue;
334 }
335 } else {
336 airq = irq;
337 }
338
339 BUGMSG2(D_INIT, "(%d,", airq);
340 openparen = 1;
341
342 /* Everything seems okay. But which shmem, if any, puts
343 * back its signature byte when the card is reset?
344 *
345 * If there are multiple cards installed, there might be
346 * multiple shmems still in the list.
347 */
348#ifdef FAST_PROBE
349 if (numports > 1 || numshmems > 1) {
350 inb(_RESET);
351 mdelay(RESETtime);
352 } else {
353 /* just one shmem and port, assume they match */
354 isa_writeb(TESTvalue, shmems[0]);
355 }
356#else
357 inb(_RESET);
358 mdelay(RESETtime);
359#endif
360
361 for (p = &shmems[0]; p < shmems + numshmems; p++) {
362 u_long ptr = *p;
363
364 if (isa_readb(ptr) == TESTvalue) { /* found one */
365 BUGMSG2(D_INIT, "%lXh)\n", *p);
366 openparen = 0;
367
368 /* register the card */
369 if (com90xx_found(*port, airq, *p) == 0)
370 found = 1;
371 numprint = -1;
372
373 /* remove shmem from the list */
374 *p = shmems[--numshmems];
375 break; /* go to the next I/O port */
376 } else {
377 BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
378 }
379 }
380
381 if (openparen) {
382 BUGLVL(D_INIT) printk("no matching shmem)\n");
383 BUGLVL(D_INIT_REASONS) printk("S5: ");
384 BUGLVL(D_INIT_REASONS) numprint = 0;
385 }
386 if (!found)
387 release_region(*port, ARCNET_TOTAL_SIZE);
388 *port-- = ports[--numports];
389 }
390
391 BUGLVL(D_INIT_REASONS) printk("\n");
392
393 /* Now put back TESTvalue on all leftover shmems. */
394 for (p = &shmems[0]; p < shmems + numshmems; p++) {
395 isa_writeb(TESTvalue, *p);
396 release_mem_region(*p, BUFFER_SIZE);
397 }
398}
399
400
401/* Set up the struct net_device associated with this card. Called after
402 * probing succeeds.
403 */
404static int __init com90xx_found(int ioaddr, int airq, u_long shmem)
405{
406 struct net_device *dev = NULL;
407 struct arcnet_local *lp;
408 u_long first_mirror, last_mirror;
409 int mirror_size;
410
411 /* allocate struct net_device */
412 dev = alloc_arcdev(device);
413 if (!dev) {
414 BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
415 release_mem_region(shmem, BUFFER_SIZE);
416 return -ENOMEM;
417 }
418 lp = dev->priv;
419 /* find the real shared memory start/end points, including mirrors */
420
421 /* guess the actual size of one "memory mirror" - the number of
422 * bytes between copies of the shared memory. On most cards, it's
423 * 2k (or there are no mirrors at all) but on some, it's 4k.
424 */
425 mirror_size = MIRROR_SIZE;
426 if (isa_readb(shmem) == TESTvalue
427 && isa_readb(shmem - mirror_size) != TESTvalue
428 && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
429 mirror_size *= 2;
430
431 first_mirror = last_mirror = shmem;
432 while (isa_readb(first_mirror) == TESTvalue)
433 first_mirror -= mirror_size;
434 first_mirror += mirror_size;
435
436 while (isa_readb(last_mirror) == TESTvalue)
437 last_mirror += mirror_size;
438 last_mirror -= mirror_size;
439
440 dev->mem_start = first_mirror;
441 dev->mem_end = last_mirror + MIRROR_SIZE - 1;
442
443 release_mem_region(shmem, BUFFER_SIZE);
444 if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
445 goto err_free_dev;
446
447 /* reserve the irq */
448 if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
449 BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
450 goto err_release_mem;
451 }
452 dev->irq = airq;
453
454 /* Initialize the rest of the device structure. */
455 lp->card_name = "COM90xx";
456 lp->hw.command = com90xx_command;
457 lp->hw.status = com90xx_status;
458 lp->hw.intmask = com90xx_setmask;
459 lp->hw.reset = com90xx_reset;
460 lp->hw.owner = THIS_MODULE;
461 lp->hw.copy_to_card = com90xx_copy_to_card;
462 lp->hw.copy_from_card = com90xx_copy_from_card;
463 lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
464 if (!lp->mem_start) {
465 BUGMSG(D_NORMAL, "Can't remap device memory!\n");
466 goto err_free_irq;
467 }
468
469 /* get and check the station ID from offset 1 in shmem */
470 dev->dev_addr[0] = readb(lp->mem_start + 1);
471
472 dev->base_addr = ioaddr;
473
474 BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
475 "ShMem %lXh (%ld*%xh).\n",
476 dev->dev_addr[0],
477 dev->base_addr, dev->irq, dev->mem_start,
478 (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
479
480 if (register_netdev(dev))
481 goto err_unmap;
482
483 cards[numcards++] = dev;
484 return 0;
485
486err_unmap:
487 iounmap(lp->mem_start);
488err_free_irq:
489 free_irq(dev->irq, dev);
490err_release_mem:
491 release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
492err_free_dev:
493 free_netdev(dev);
494 return -EIO;
495}
496
497
498static void com90xx_command(struct net_device *dev, int cmd)
499{
500 short ioaddr = dev->base_addr;
501
502 ACOMMAND(cmd);
503}
504
505
506static int com90xx_status(struct net_device *dev)
507{
508 short ioaddr = dev->base_addr;
509
510 return ASTATUS();
511}
512
513
514static void com90xx_setmask(struct net_device *dev, int mask)
515{
516 short ioaddr = dev->base_addr;
517
518 AINTMASK(mask);
519}
520
521
522/*
523 * Do a hardware reset on the card, and set up necessary registers.
524 *
525 * This should be called as little as possible, because it disrupts the
526 * token on the network (causes a RECON) and requires a significant delay.
527 *
528 * However, it does make sure the card is in a defined state.
529 */
530int com90xx_reset(struct net_device *dev, int really_reset)
531{
532 struct arcnet_local *lp = dev->priv;
533 short ioaddr = dev->base_addr;
534
535 BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
536
537 if (really_reset) {
538 /* reset the card */
539 inb(_RESET);
540 mdelay(RESETtime);
541 }
542 ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
543 ACOMMAND(CFLAGScmd | CONFIGclear);
544
545 /* don't do this until we verify that it doesn't hurt older cards! */
546 /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
547
548 /* verify that the ARCnet signature byte is present */
549 if (readb(lp->mem_start) != TESTvalue) {
550 if (really_reset)
551 BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
552 return 1;
553 }
554 /* enable extended (512-byte) packets */
555 ACOMMAND(CONFIGcmd | EXTconf);
556
557 /* clean out all the memory to make debugging make more sense :) */
558 BUGLVL(D_DURING)
559 memset_io(lp->mem_start, 0x42, 2048);
560
561 /* done! return success. */
562 return 0;
563}
564
565static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
566 void *buf, int count)
567{
568 struct arcnet_local *lp = dev->priv;
569 void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
570 TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
571}
572
573
574static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
575 void *buf, int count)
576{
577 struct arcnet_local *lp = dev->priv;
578 void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
579 TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
580}
581
582
583MODULE_LICENSE("GPL");
584
585static int __init com90xx_init(void)
586{
587 if (irq == 2)
588 irq = 9;
589 com90xx_probe();
590 if (!numcards)
591 return -EIO;
592 return 0;
593}
594
595static void __exit com90xx_exit(void)
596{
597 struct net_device *dev;
598 struct arcnet_local *lp;
599 int count;
600
601 for (count = 0; count < numcards; count++) {
602 dev = cards[count];
603 lp = dev->priv;
604
605 unregister_netdev(dev);
606 free_irq(dev->irq, dev);
607 iounmap(lp->mem_start);
608 release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
609 release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
610 free_netdev(dev);
611 }
612}
613
614module_init(com90xx_init);
615module_exit(com90xx_exit);
616
617#ifndef MODULE
618static int __init com90xx_setup(char *s)
619{
620 int ints[8];
621
622 s = get_options(s, 8, ints);
623 if (!ints[0] && !*s) {
624 printk("com90xx: Disabled.\n");
625 return 1;
626 }
627
628 switch (ints[0]) {
629 default: /* ERROR */
630 printk("com90xx: Too many arguments.\n");
631 case 3: /* Mem address */
632 shmem = ints[3];
633 case 2: /* IRQ */
634 irq = ints[2];
635 case 1: /* IO address */
636 io = ints[1];
637 }
638
639 if (*s)
640 snprintf(device, sizeof(device), "%s", s);
641
642 return 1;
643}
644
645__setup("com90xx=", com90xx_setup);
646#endif
diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
new file mode 100644
index 000000000000..6d7913704fb5
--- /dev/null
+++ b/drivers/net/arcnet/rfc1051.c
@@ -0,0 +1,253 @@
1/*
2 * Linux ARCnet driver - RFC1051 ("simple" standard) packet encapsulation
3 *
4 * Written 1994-1999 by Avery Pennarun.
5 * Derived from skeleton.c by Donald Becker.
6 *
7 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
8 * for sponsoring the further development of this driver.
9 *
10 * **********************
11 *
12 * The original copyright of skeleton.c was as follows:
13 *
14 * skeleton.c Written 1993 by Donald Becker.
15 * Copyright 1993 United States Government as represented by the
16 * Director, National Security Agency. This software may only be used
17 * and distributed according to the terms of the GNU General Public License as
18 * modified by SRC, incorporated herein by reference.
19 *
20 * **********************
21 *
22 * For more details, see drivers/net/arcnet.c
23 *
24 * **********************
25 */
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/if_arp.h>
29#include <net/arp.h>
30#include <linux/netdevice.h>
31#include <linux/skbuff.h>
32#include <linux/arcdevice.h>
33
34#define VERSION "arcnet: RFC1051 \"simple standard\" (`s') encapsulation support loaded.\n"
35
36
37static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev);
38static void rx(struct net_device *dev, int bufnum,
39 struct archdr *pkthdr, int length);
40static int build_header(struct sk_buff *skb, struct net_device *dev,
41 unsigned short type, uint8_t daddr);
42static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
43 int bufnum);
44
45
46struct ArcProto rfc1051_proto =
47{
48 .suffix = 's',
49 .mtu = XMTU - RFC1051_HDR_SIZE,
50 .is_ip = 1,
51 .rx = rx,
52 .build_header = build_header,
53 .prepare_tx = prepare_tx,
54 .continue_tx = NULL,
55 .ack_tx = NULL
56};
57
58
59static int __init arcnet_rfc1051_init(void)
60{
61 printk(VERSION);
62
63 arc_proto_map[ARC_P_IP_RFC1051]
64 = arc_proto_map[ARC_P_ARP_RFC1051]
65 = &rfc1051_proto;
66
67 /* if someone else already owns the broadcast, we won't take it */
68 if (arc_bcast_proto == arc_proto_default)
69 arc_bcast_proto = &rfc1051_proto;
70
71 return 0;
72}
73
74static void __exit arcnet_rfc1051_exit(void)
75{
76 arcnet_unregister_proto(&rfc1051_proto);
77}
78
79module_init(arcnet_rfc1051_init);
80module_exit(arcnet_rfc1051_exit);
81
82MODULE_LICENSE("GPL");
83
84/*
85 * Determine a packet's protocol ID.
86 *
87 * With ARCnet we have to convert everything to Ethernet-style stuff.
88 */
89static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev)
90{
91 struct arcnet_local *lp = dev->priv;
92 struct archdr *pkt = (struct archdr *) skb->data;
93 struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
94 int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
95
96 /* Pull off the arcnet header. */
97 skb->mac.raw = skb->data;
98 skb_pull(skb, hdr_size);
99
100 if (pkt->hard.dest == 0)
101 skb->pkt_type = PACKET_BROADCAST;
102 else if (dev->flags & IFF_PROMISC) {
103 /* if we're not sending to ourselves :) */
104 if (pkt->hard.dest != dev->dev_addr[0])
105 skb->pkt_type = PACKET_OTHERHOST;
106 }
107 /* now return the protocol number */
108 switch (soft->proto) {
109 case ARC_P_IP_RFC1051:
110 return htons(ETH_P_IP);
111 case ARC_P_ARP_RFC1051:
112 return htons(ETH_P_ARP);
113
114 default:
115 lp->stats.rx_errors++;
116 lp->stats.rx_crc_errors++;
117 return 0;
118 }
119
120 return htons(ETH_P_IP);
121}
122
123
124/* packet receiver */
125static void rx(struct net_device *dev, int bufnum,
126 struct archdr *pkthdr, int length)
127{
128 struct arcnet_local *lp = dev->priv;
129 struct sk_buff *skb;
130 struct archdr *pkt = pkthdr;
131 int ofs;
132
133 BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
134
135 if (length >= MinTU)
136 ofs = 512 - length;
137 else
138 ofs = 256 - length;
139
140 skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
141 if (skb == NULL) {
142 BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
143 lp->stats.rx_dropped++;
144 return;
145 }
146 skb_put(skb, length + ARC_HDR_SIZE);
147 skb->dev = dev;
148
149 pkt = (struct archdr *) skb->data;
150
151 /* up to sizeof(pkt->soft) has already been copied from the card */
152 memcpy(pkt, pkthdr, sizeof(struct archdr));
153 if (length > sizeof(pkt->soft))
154 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
155 pkt->soft.raw + sizeof(pkt->soft),
156 length - sizeof(pkt->soft));
157
158 BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
159
160 skb->protocol = type_trans(skb, dev);
161 netif_rx(skb);
162 dev->last_rx = jiffies;
163}
164
165
166/*
167 * Create the ARCnet hard/soft headers for RFC1051.
168 */
169static int build_header(struct sk_buff *skb, struct net_device *dev,
170 unsigned short type, uint8_t daddr)
171{
172 struct arcnet_local *lp = dev->priv;
173 int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
174 struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
175 struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
176
177 /* set the protocol ID according to RFC1051 */
178 switch (type) {
179 case ETH_P_IP:
180 soft->proto = ARC_P_IP_RFC1051;
181 break;
182 case ETH_P_ARP:
183 soft->proto = ARC_P_ARP_RFC1051;
184 break;
185 default:
186 BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
187 type, type);
188 lp->stats.tx_errors++;
189 lp->stats.tx_aborted_errors++;
190 return 0;
191 }
192
193
194 /*
195 * Set the source hardware address.
196 *
197 * This is pretty pointless for most purposes, but it can help in
198 * debugging. ARCnet does not allow us to change the source address in
199 * the actual packet sent)
200 */
201 pkt->hard.source = *dev->dev_addr;
202
203 /* see linux/net/ethernet/eth.c to see where I got the following */
204
205 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
206 /*
207 * FIXME: fill in the last byte of the dest ipaddr here to better
208 * comply with RFC1051 in "noarp" mode.
209 */
210 pkt->hard.dest = 0;
211 return hdr_size;
212 }
213 /* otherwise, just fill it in and go! */
214 pkt->hard.dest = daddr;
215
216 return hdr_size; /* success */
217}
218
219
220static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
221 int bufnum)
222{
223 struct arcnet_local *lp = dev->priv;
224 struct arc_hardware *hard = &pkt->hard;
225 int ofs;
226
227 BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
228 lp->next_tx, lp->cur_tx, bufnum);
229
230 length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
231
232 if (length > XMTU) {
233 /* should never happen! other people already check for this. */
234 BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
235 length, XMTU);
236 length = XMTU;
237 }
238 if (length > MinTU) {
239 hard->offset[0] = 0;
240 hard->offset[1] = ofs = 512 - length;
241 } else if (length > MTU) {
242 hard->offset[0] = 0;
243 hard->offset[1] = ofs = 512 - length - 3;
244 } else
245 hard->offset[0] = ofs = 256 - length;
246
247 lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
248 lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
249
250 lp->lastload_dest = hard->dest;
251
252 return 1; /* done */
253}
diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
new file mode 100644
index 000000000000..6b6ae4bf3d39
--- /dev/null
+++ b/drivers/net/arcnet/rfc1201.c
@@ -0,0 +1,549 @@
1/*
2 * Linux ARCnet driver - RFC1201 (standard) packet encapsulation
3 *
4 * Written 1994-1999 by Avery Pennarun.
5 * Derived from skeleton.c by Donald Becker.
6 *
7 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
8 * for sponsoring the further development of this driver.
9 *
10 * **********************
11 *
12 * The original copyright of skeleton.c was as follows:
13 *
14 * skeleton.c Written 1993 by Donald Becker.
15 * Copyright 1993 United States Government as represented by the
16 * Director, National Security Agency. This software may only be used
17 * and distributed according to the terms of the GNU General Public License as
18 * modified by SRC, incorporated herein by reference.
19 *
20 * **********************
21 *
22 * For more details, see drivers/net/arcnet.c
23 *
24 * **********************
25 */
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/if_arp.h>
29#include <linux/netdevice.h>
30#include <linux/skbuff.h>
31#include <linux/arcdevice.h>
32
33MODULE_LICENSE("GPL");
34#define VERSION "arcnet: RFC1201 \"standard\" (`a') encapsulation support loaded.\n"
35
36
37static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev);
38static void rx(struct net_device *dev, int bufnum,
39 struct archdr *pkthdr, int length);
40static int build_header(struct sk_buff *skb, struct net_device *dev,
41 unsigned short type, uint8_t daddr);
42static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
43 int bufnum);
44static int continue_tx(struct net_device *dev, int bufnum);
45
46struct ArcProto rfc1201_proto =
47{
48 .suffix = 'a',
49 .mtu = 1500, /* could be more, but some receivers can't handle it... */
50 .is_ip = 1, /* This is for sending IP and ARP packages */
51 .rx = rx,
52 .build_header = build_header,
53 .prepare_tx = prepare_tx,
54 .continue_tx = continue_tx,
55 .ack_tx = NULL
56};
57
58
59static int __init arcnet_rfc1201_init(void)
60{
61 printk(VERSION);
62
63 arc_proto_map[ARC_P_IP]
64 = arc_proto_map[ARC_P_IPV6]
65 = arc_proto_map[ARC_P_ARP]
66 = arc_proto_map[ARC_P_RARP]
67 = arc_proto_map[ARC_P_IPX]
68 = arc_proto_map[ARC_P_NOVELL_EC]
69 = &rfc1201_proto;
70
71 /* if someone else already owns the broadcast, we won't take it */
72 if (arc_bcast_proto == arc_proto_default)
73 arc_bcast_proto = &rfc1201_proto;
74
75 return 0;
76}
77
78static void __exit arcnet_rfc1201_exit(void)
79{
80 arcnet_unregister_proto(&rfc1201_proto);
81}
82
83module_init(arcnet_rfc1201_init);
84module_exit(arcnet_rfc1201_exit);
85
86/*
87 * Determine a packet's protocol ID.
88 *
89 * With ARCnet we have to convert everything to Ethernet-style stuff.
90 */
91static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev)
92{
93 struct archdr *pkt = (struct archdr *) skb->data;
94 struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
95 struct arcnet_local *lp = dev->priv;
96 int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
97
98 /* Pull off the arcnet header. */
99 skb->mac.raw = skb->data;
100 skb_pull(skb, hdr_size);
101
102 if (pkt->hard.dest == 0)
103 skb->pkt_type = PACKET_BROADCAST;
104 else if (dev->flags & IFF_PROMISC) {
105 /* if we're not sending to ourselves :) */
106 if (pkt->hard.dest != dev->dev_addr[0])
107 skb->pkt_type = PACKET_OTHERHOST;
108 }
109 /* now return the protocol number */
110 switch (soft->proto) {
111 case ARC_P_IP:
112 return htons(ETH_P_IP);
113 case ARC_P_IPV6:
114 return htons(ETH_P_IPV6);
115 case ARC_P_ARP:
116 return htons(ETH_P_ARP);
117 case ARC_P_RARP:
118 return htons(ETH_P_RARP);
119
120 case ARC_P_IPX:
121 case ARC_P_NOVELL_EC:
122 return htons(ETH_P_802_3);
123 default:
124 lp->stats.rx_errors++;
125 lp->stats.rx_crc_errors++;
126 return 0;
127 }
128
129 return htons(ETH_P_IP);
130}
131
132
133/* packet receiver */
134static void rx(struct net_device *dev, int bufnum,
135 struct archdr *pkthdr, int length)
136{
137 struct arcnet_local *lp = dev->priv;
138 struct sk_buff *skb;
139 struct archdr *pkt = pkthdr;
140 struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
141 int saddr = pkt->hard.source, ofs;
142 struct Incoming *in = &lp->rfc1201.incoming[saddr];
143
144 BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", length);
145
146 if (length >= MinTU)
147 ofs = 512 - length;
148 else
149 ofs = 256 - length;
150
151 if (soft->split_flag == 0xFF) { /* Exception Packet */
152 if (length >= 4 + RFC1201_HDR_SIZE)
153 BUGMSG(D_DURING, "compensating for exception packet\n");
154 else {
155 BUGMSG(D_EXTRA, "short RFC1201 exception packet from %02Xh",
156 saddr);
157 return;
158 }
159
160 /* skip over 4-byte junkola */
161 length -= 4;
162 ofs += 4;
163 lp->hw.copy_from_card(dev, bufnum, 512 - length,
164 soft, sizeof(pkt->soft));
165 }
166 if (!soft->split_flag) { /* not split */
167 BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n",
168 soft->split_flag);
169
170 if (in->skb) { /* already assembling one! */
171 BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
172 in->sequence, soft->split_flag, soft->sequence);
173 lp->rfc1201.aborted_seq = soft->sequence;
174 dev_kfree_skb_irq(in->skb);
175 lp->stats.rx_errors++;
176 lp->stats.rx_missed_errors++;
177 in->skb = NULL;
178 }
179 in->sequence = soft->sequence;
180
181 skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
182 if (skb == NULL) {
183 BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
184 lp->stats.rx_dropped++;
185 return;
186 }
187 skb_put(skb, length + ARC_HDR_SIZE);
188 skb->dev = dev;
189
190 pkt = (struct archdr *) skb->data;
191 soft = &pkt->soft.rfc1201;
192
193 /* up to sizeof(pkt->soft) has already been copied from the card */
194 memcpy(pkt, pkthdr, sizeof(struct archdr));
195 if (length > sizeof(pkt->soft))
196 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
197 pkt->soft.raw + sizeof(pkt->soft),
198 length - sizeof(pkt->soft));
199
200 /*
201 * ARP packets have problems when sent from some DOS systems: the
202 * source address is always 0! So we take the hardware source addr
203 * (which is impossible to fumble) and insert it ourselves.
204 */
205 if (soft->proto == ARC_P_ARP) {
206 struct arphdr *arp = (struct arphdr *) soft->payload;
207
208 /* make sure addresses are the right length */
209 if (arp->ar_hln == 1 && arp->ar_pln == 4) {
210 uint8_t *cptr = (uint8_t *) arp + sizeof(struct arphdr);
211
212 if (!*cptr) { /* is saddr = 00? */
213 BUGMSG(D_EXTRA,
214 "ARP source address was 00h, set to %02Xh.\n",
215 saddr);
216 lp->stats.rx_crc_errors++;
217 *cptr = saddr;
218 } else {
219 BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
220 *cptr);
221 }
222 } else {
223 BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
224 arp->ar_hln, arp->ar_pln);
225 lp->stats.rx_errors++;
226 lp->stats.rx_crc_errors++;
227 }
228 }
229 BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
230
231 skb->protocol = type_trans(skb, dev);
232 netif_rx(skb);
233 dev->last_rx = jiffies;
234 } else { /* split packet */
235 /*
236 * NOTE: MSDOS ARP packet correction should only need to apply to
237 * unsplit packets, since ARP packets are so short.
238 *
239 * My interpretation of the RFC1201 document is that if a packet is
240 * received out of order, the entire assembly process should be
241 * aborted.
242 *
243 * The RFC also mentions "it is possible for successfully received
244 * packets to be retransmitted." As of 0.40 all previously received
245 * packets are allowed, not just the most recent one.
246 *
247 * We allow multiple assembly processes, one for each ARCnet card
248 * possible on the network. Seems rather like a waste of memory,
249 * but there's no other way to be reliable.
250 */
251
252 BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n",
253 soft->split_flag, in->sequence);
254
255 if (in->skb && in->sequence != soft->sequence) {
256 BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
257 saddr, in->sequence, soft->sequence,
258 soft->split_flag);
259 dev_kfree_skb_irq(in->skb);
260 in->skb = NULL;
261 lp->stats.rx_errors++;
262 lp->stats.rx_missed_errors++;
263 in->lastpacket = in->numpackets = 0;
264 }
265 if (soft->split_flag & 1) { /* first packet in split */
266 BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n",
267 soft->split_flag);
268 if (in->skb) { /* already assembling one! */
269 BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly "
270 "(splitflag=%d, seq=%d)\n",
271 in->sequence, soft->split_flag,
272 soft->sequence);
273 lp->stats.rx_errors++;
274 lp->stats.rx_missed_errors++;
275 dev_kfree_skb_irq(in->skb);
276 }
277 in->sequence = soft->sequence;
278 in->numpackets = ((unsigned) soft->split_flag >> 1) + 2;
279 in->lastpacket = 1;
280
281 if (in->numpackets > 16) {
282 BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
283 soft->split_flag);
284 lp->rfc1201.aborted_seq = soft->sequence;
285 lp->stats.rx_errors++;
286 lp->stats.rx_length_errors++;
287 return;
288 }
289 in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
290 GFP_ATOMIC);
291 if (skb == NULL) {
292 BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
293 lp->rfc1201.aborted_seq = soft->sequence;
294 lp->stats.rx_dropped++;
295 return;
296 }
297 skb->dev = dev;
298 pkt = (struct archdr *) skb->data;
299 soft = &pkt->soft.rfc1201;
300
301 memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
302 skb_put(skb, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
303
304 soft->split_flag = 0; /* end result won't be split */
305 } else { /* not first packet */
306 int packetnum = ((unsigned) soft->split_flag >> 1) + 1;
307
308 /*
309 * if we're not assembling, there's no point trying to
310 * continue.
311 */
312 if (!in->skb) {
313 if (lp->rfc1201.aborted_seq != soft->sequence) {
314 BUGMSG(D_EXTRA, "can't continue split without starting "
315 "first! (splitflag=%d, seq=%d, aborted=%d)\n",
316 soft->split_flag, soft->sequence,
317 lp->rfc1201.aborted_seq);
318 lp->stats.rx_errors++;
319 lp->stats.rx_missed_errors++;
320 }
321 return;
322 }
323 in->lastpacket++;
324 if (packetnum != in->lastpacket) { /* not the right flag! */
325 /* harmless duplicate? ignore. */
326 if (packetnum <= in->lastpacket - 1) {
327 BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
328 soft->split_flag);
329 lp->stats.rx_errors++;
330 lp->stats.rx_frame_errors++;
331 return;
332 }
333 /* "bad" duplicate, kill reassembly */
334 BUGMSG(D_EXTRA, "out-of-order splitpacket, reassembly "
335 "(seq=%d) aborted (splitflag=%d, seq=%d)\n",
336 in->sequence, soft->split_flag, soft->sequence);
337 lp->rfc1201.aborted_seq = soft->sequence;
338 dev_kfree_skb_irq(in->skb);
339 in->skb = NULL;
340 lp->stats.rx_errors++;
341 lp->stats.rx_missed_errors++;
342 in->lastpacket = in->numpackets = 0;
343 return;
344 }
345 pkt = (struct archdr *) in->skb->data;
346 soft = &pkt->soft.rfc1201;
347 }
348
349 skb = in->skb;
350
351 lp->hw.copy_from_card(dev, bufnum, ofs + RFC1201_HDR_SIZE,
352 skb->data + skb->len,
353 length - RFC1201_HDR_SIZE);
354 skb_put(skb, length - RFC1201_HDR_SIZE);
355
356 /* are we done? */
357 if (in->lastpacket == in->numpackets) {
358 in->skb = NULL;
359 in->lastpacket = in->numpackets = 0;
360
361 BUGMSG(D_SKB_SIZE, "skb: received %d bytes from %02X (unsplit)\n",
362 skb->len, pkt->hard.source);
363 BUGMSG(D_SKB_SIZE, "skb: received %d bytes from %02X (split)\n",
364 skb->len, pkt->hard.source);
365 BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
366
367 skb->protocol = type_trans(skb, dev);
368 netif_rx(skb);
369 dev->last_rx = jiffies;
370 }
371 }
372}
373
374
375/* Create the ARCnet hard/soft headers for RFC1201. */
376static int build_header(struct sk_buff *skb, struct net_device *dev,
377 unsigned short type, uint8_t daddr)
378{
379 struct arcnet_local *lp = dev->priv;
380 int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
381 struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
382 struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
383
384 /* set the protocol ID according to RFC1201 */
385 switch (type) {
386 case ETH_P_IP:
387 soft->proto = ARC_P_IP;
388 break;
389 case ETH_P_IPV6:
390 soft->proto = ARC_P_IPV6;
391 break;
392 case ETH_P_ARP:
393 soft->proto = ARC_P_ARP;
394 break;
395 case ETH_P_RARP:
396 soft->proto = ARC_P_RARP;
397 break;
398 case ETH_P_IPX:
399 case ETH_P_802_3:
400 case ETH_P_802_2:
401 soft->proto = ARC_P_IPX;
402 break;
403 case ETH_P_ATALK:
404 soft->proto = ARC_P_ATALK;
405 break;
406 default:
407 BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
408 type, type);
409 lp->stats.tx_errors++;
410 lp->stats.tx_aborted_errors++;
411 return 0;
412 }
413
414 /*
415 * Set the source hardware address.
416 *
417 * This is pretty pointless for most purposes, but it can help in
418 * debugging. ARCnet does not allow us to change the source address in
419 * the actual packet sent)
420 */
421 pkt->hard.source = *dev->dev_addr;
422
423 soft->sequence = htons(lp->rfc1201.sequence++);
424 soft->split_flag = 0; /* split packets are done elsewhere */
425
426 /* see linux/net/ethernet/eth.c to see where I got the following */
427
428 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
429 /*
430 * FIXME: fill in the last byte of the dest ipaddr here to better
431 * comply with RFC1051 in "noarp" mode. For now, always broadcasting
432 * will probably at least get packets sent out :)
433 */
434 pkt->hard.dest = 0;
435 return hdr_size;
436 }
437 /* otherwise, drop in the dest address */
438 pkt->hard.dest = daddr;
439 return hdr_size;
440}
441
442
443static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
444 struct arc_rfc1201 *soft, int softlen, int bufnum)
445{
446 struct arcnet_local *lp = dev->priv;
447 int ofs;
448
449 /* assume length <= XMTU: someone should have handled that by now. */
450
451 if (softlen > MinTU) {
452 hard->offset[0] = 0;
453 hard->offset[1] = ofs = 512 - softlen;
454 } else if (softlen > MTU) { /* exception packet - add an extra header */
455 struct arc_rfc1201 excsoft;
456
457 excsoft.proto = soft->proto;
458 excsoft.split_flag = 0xff;
459 excsoft.sequence = 0xffff;
460
461 hard->offset[0] = 0;
462 ofs = 512 - softlen;
463 hard->offset[1] = ofs - RFC1201_HDR_SIZE;
464 lp->hw.copy_to_card(dev, bufnum, ofs - RFC1201_HDR_SIZE,
465 &excsoft, RFC1201_HDR_SIZE);
466 } else
467 hard->offset[0] = ofs = 256 - softlen;
468
469 lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
470 lp->hw.copy_to_card(dev, bufnum, ofs, soft, softlen);
471
472 lp->lastload_dest = hard->dest;
473}
474
475
476static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
477 int bufnum)
478{
479 struct arcnet_local *lp = dev->priv;
480 const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
481 struct Outgoing *out;
482
483
484 BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
485 lp->next_tx, lp->cur_tx, bufnum);
486
487 length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
488 pkt->soft.rfc1201.split_flag = 0;
489
490 /* need to do a split packet? */
491 if (length > XMTU) {
492 out = &lp->outgoing;
493
494 out->length = length - RFC1201_HDR_SIZE;
495 out->dataleft = lp->outgoing.length;
496 out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize;
497 out->segnum = 0;
498
499 BUGMSG(D_DURING, "rfc1201 prep_tx: ready for %d-segment split "
500 "(%d bytes, seq=%d)\n", out->numsegs, out->length,
501 pkt->soft.rfc1201.sequence);
502
503 return 0; /* not done */
504 }
505 /* just load the packet into the buffers and send it off */
506 load_pkt(dev, &pkt->hard, &pkt->soft.rfc1201, length, bufnum);
507
508 return 1; /* done */
509}
510
511
512static int continue_tx(struct net_device *dev, int bufnum)
513{
514 struct arcnet_local *lp = dev->priv;
515 struct Outgoing *out = &lp->outgoing;
516 struct arc_hardware *hard = &out->pkt->hard;
517 struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
518 int maxsegsize = XMTU - RFC1201_HDR_SIZE;
519 int seglen;
520
521 BUGMSG(D_DURING,
522 "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
523 out->segnum, out->numsegs, soft->sequence);
524
525 /* the "new" soft header comes right before the data chunk */
526 newsoft = (struct arc_rfc1201 *)
527 (out->pkt->soft.raw + out->length - out->dataleft);
528
529 if (!out->segnum) /* first packet; newsoft == soft */
530 newsoft->split_flag = ((out->numsegs - 2) << 1) | 1;
531 else {
532 newsoft->split_flag = out->segnum << 1;
533 newsoft->proto = soft->proto;
534 newsoft->sequence = soft->sequence;
535 }
536
537 seglen = maxsegsize;
538 if (seglen > out->dataleft)
539 seglen = out->dataleft;
540 out->dataleft -= seglen;
541
542 load_pkt(dev, hard, newsoft, seglen + RFC1201_HDR_SIZE, bufnum);
543
544 out->segnum++;
545 if (out->segnum >= out->numsegs)
546 return 1;
547 else
548 return 0;
549}