blob: 9e7e37f5cdcb05ec2ddc68f7ac04b3c1bb0d5cea [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*********************************************************************
2 *
3 * Filename: netwave_cs.c
4 * Version: 0.4.1
5 * Description: Netwave AirSurfer Wireless LAN PC Card driver
6 * Status: Experimental.
Jan Engelhardt96de0e22007-10-19 23:21:04 +02007 * Authors: John Markus Bjørndalen <johnm@cs.uit.no>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 * Dag Brattli <dagb@cs.uit.no>
9 * David Hinds <dahinds@users.sourceforge.net>
10 * Created at: A long time ago!
11 * Modified at: Mon Nov 10 11:54:37 1997
12 * Modified by: Dag Brattli <dagb@cs.uit.no>
13 *
Jan Engelhardt96de0e22007-10-19 23:21:04 +020014 * Copyright (c) 1997 University of Tromsø, Norway
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 *
16 * Revision History:
17 *
Jan Engelhardt96de0e22007-10-19 23:21:04 +020018 * 08-Nov-97 15:14:47 John Markus Bjørndalen <johnm@cs.uit.no>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 * - Fixed some bugs in netwave_rx and cleaned it up a bit.
20 * (One of the bugs would have destroyed packets when receiving
21 * multiple packets per interrupt).
22 * - Cleaned up parts of newave_hw_xmit.
23 * - A few general cleanups.
24 * 24-Oct-97 13:17:36 Dag Brattli <dagb@cs.uit.no>
25 * - Fixed netwave_rx receive function (got updated docs)
26 * Others:
27 * - Changed name from xircnw to netwave, take a look at
28 * http://www.netwave-wireless.com
29 * - Some reorganizing of the code
30 * - Removed possible race condition between interrupt handler and transmit
31 * function
32 * - Started to add wireless extensions, but still needs some coding
33 * - Added watchdog for better handling of transmission timeouts
34 * (hopefully this works better)
35 ********************************************************************/
36
37/* To have statistics (just packets sent) define this */
38#undef NETWAVE_STATS
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/module.h>
41#include <linux/kernel.h>
42#include <linux/init.h>
43#include <linux/types.h>
44#include <linux/fcntl.h>
45#include <linux/interrupt.h>
46#include <linux/ptrace.h>
47#include <linux/ioport.h>
48#include <linux/in.h>
49#include <linux/slab.h>
50#include <linux/string.h>
51#include <linux/timer.h>
52#include <linux/errno.h>
53#include <linux/netdevice.h>
54#include <linux/etherdevice.h>
55#include <linux/skbuff.h>
56#include <linux/bitops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070057#include <linux/wireless.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#include <net/iw_handler.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Linus Torvalds1da177e2005-04-16 15:20:36 -070060#include <pcmcia/cs_types.h>
61#include <pcmcia/cs.h>
62#include <pcmcia/cistpl.h>
63#include <pcmcia/cisreg.h>
64#include <pcmcia/ds.h>
65#include <pcmcia/mem_op.h>
66
67#include <asm/system.h>
68#include <asm/io.h>
69#include <asm/dma.h>
70
71#define NETWAVE_REGOFF 0x8000
72/* The Netwave IO registers, offsets to iobase */
73#define NETWAVE_REG_COR 0x0
74#define NETWAVE_REG_CCSR 0x2
75#define NETWAVE_REG_ASR 0x4
76#define NETWAVE_REG_IMR 0xa
77#define NETWAVE_REG_PMR 0xc
78#define NETWAVE_REG_IOLOW 0x6
79#define NETWAVE_REG_IOHI 0x7
80#define NETWAVE_REG_IOCONTROL 0x8
81#define NETWAVE_REG_DATA 0xf
82/* The Netwave Extended IO registers, offsets to RamBase */
83#define NETWAVE_EREG_ASCC 0x114
84#define NETWAVE_EREG_RSER 0x120
85#define NETWAVE_EREG_RSERW 0x124
86#define NETWAVE_EREG_TSER 0x130
87#define NETWAVE_EREG_TSERW 0x134
88#define NETWAVE_EREG_CB 0x100
89#define NETWAVE_EREG_SPCQ 0x154
90#define NETWAVE_EREG_SPU 0x155
91#define NETWAVE_EREG_LIF 0x14e
92#define NETWAVE_EREG_ISPLQ 0x156
93#define NETWAVE_EREG_HHC 0x158
94#define NETWAVE_EREG_NI 0x16e
95#define NETWAVE_EREG_MHS 0x16b
96#define NETWAVE_EREG_TDP 0x140
97#define NETWAVE_EREG_RDP 0x150
98#define NETWAVE_EREG_PA 0x160
99#define NETWAVE_EREG_EC 0x180
100#define NETWAVE_EREG_CRBP 0x17a
101#define NETWAVE_EREG_ARW 0x166
102
103/*
104 * Commands used in the extended command buffer
105 * NETWAVE_EREG_CB (0x100-0x10F)
106 */
107#define NETWAVE_CMD_NOP 0x00
108#define NETWAVE_CMD_SRC 0x01
109#define NETWAVE_CMD_STC 0x02
110#define NETWAVE_CMD_AMA 0x03
111#define NETWAVE_CMD_DMA 0x04
112#define NETWAVE_CMD_SAMA 0x05
113#define NETWAVE_CMD_ER 0x06
114#define NETWAVE_CMD_DR 0x07
115#define NETWAVE_CMD_TL 0x08
116#define NETWAVE_CMD_SRP 0x09
117#define NETWAVE_CMD_SSK 0x0a
118#define NETWAVE_CMD_SMD 0x0b
119#define NETWAVE_CMD_SAPD 0x0c
120#define NETWAVE_CMD_SSS 0x11
121/* End of Command marker */
122#define NETWAVE_CMD_EOC 0x00
123
124/* ASR register bits */
125#define NETWAVE_ASR_RXRDY 0x80
126#define NETWAVE_ASR_TXBA 0x01
127
128#define TX_TIMEOUT ((32*HZ)/100)
129
130static const unsigned int imrConfRFU1 = 0x10; /* RFU interrupt mask, keep high */
131static const unsigned int imrConfIENA = 0x02; /* Interrupt enable */
132
133static const unsigned int corConfIENA = 0x01; /* Interrupt enable */
134static const unsigned int corConfLVLREQ = 0x40; /* Keep high */
135
136static const unsigned int rxConfRxEna = 0x80; /* Receive Enable */
137static const unsigned int rxConfMAC = 0x20; /* MAC host receive mode*/
138static const unsigned int rxConfPro = 0x10; /* Promiscuous */
139static const unsigned int rxConfAMP = 0x08; /* Accept Multicast Packets */
140static const unsigned int rxConfBcast = 0x04; /* Accept Broadcast Packets */
141
142static const unsigned int txConfTxEna = 0x80; /* Transmit Enable */
143static const unsigned int txConfMAC = 0x20; /* Host sends MAC mode */
144static const unsigned int txConfEUD = 0x10; /* Enable Uni-Data packets */
145static const unsigned int txConfKey = 0x02; /* Scramble data packets */
146static const unsigned int txConfLoop = 0x01; /* Loopback mode */
147
148/*
149 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
150 you do not define PCMCIA_DEBUG at all, all the debug code will be
151 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
152 be present but disabled -- but it can then be enabled for specific
153 modules at load time with a 'pc_debug=#' option to insmod.
154*/
155
156#ifdef PCMCIA_DEBUG
157static int pc_debug = PCMCIA_DEBUG;
158module_param(pc_debug, int, 0);
159#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
160static char *version =
Jan Engelhardt96de0e22007-10-19 23:21:04 +0200161"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162#else
163#define DEBUG(n, args...)
164#endif
165
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166/*====================================================================*/
167
168/* Parameters that can be set with 'insmod' */
169
170/* Choose the domain, default is 0x100 */
171static u_int domain = 0x100;
172
173/* Scramble key, range from 0x0 to 0xffff.
174 * 0x0 is no scrambling.
175 */
176static u_int scramble_key = 0x0;
177
178/* Shared memory speed, in ns. The documentation states that
179 * the card should not be read faster than every 400ns.
180 * This timing should be provided by the HBA. If it becomes a
181 * problem, try setting mem_speed to 400.
182 */
183static int mem_speed;
184
185module_param(domain, int, 0);
186module_param(scramble_key, int, 0);
187module_param(mem_speed, int, 0);
188
189/*====================================================================*/
190
191/* PCMCIA (Card Services) related functions */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200192static void netwave_release(struct pcmcia_device *link); /* Card removal */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200193static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 insertion */
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100195static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197/* Hardware configuration */
Olof Johansson906da802008-02-04 22:27:35 -0800198static void netwave_doreset(unsigned int iobase, u_char __iomem *ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199static void netwave_reset(struct net_device *dev);
200
201/* Misc device stuff */
202static int netwave_open(struct net_device *dev); /* Open the device */
203static int netwave_close(struct net_device *dev); /* Close the device */
204
205/* Packet transmission and Packet reception */
206static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
207static int netwave_rx( struct net_device *dev);
208
209/* Interrupt routines */
David Howells7d12e782006-10-05 14:55:46 +0100210static irqreturn_t netwave_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211static void netwave_watchdog(struct net_device *);
212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213/* Wireless extensions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216static void set_multicast_list(struct net_device *dev);
217
218/*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200219 A struct pcmcia_device structure has fields for most things that are needed
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 to keep track of a socket, but there will usually be some device
221 specific information that also needs to be kept track of. The
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200222 'priv' pointer in a struct pcmcia_device structure can be used to point to
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 a device-specific private data structure, like this.
224
225 A driver needs to provide a dev_node_t structure for each device
226 on a card. In some cases, there is only one device per card (for
227 example, ethernet cards, modems). In other cases, there may be
228 many actual or logical devices (SCSI adapters, memory cards with
229 multiple partitions). The dev_node_t structures need to be kept
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200230 in a linked list starting at the 'dev' field of a struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 structure. We allocate them in the card's private data structure,
232 because they generally can't be allocated dynamically.
233*/
234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235static const struct iw_handler_def netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
237#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
238
239#define MAX_ESA 10
240
241typedef struct net_addr {
242 u_char addr48[6];
243} net_addr;
244
245struct site_survey {
246 u_short length;
247 u_char struct_revision;
248 u_char roaming_state;
249
250 u_char sp_existsFlag;
251 u_char sp_link_quality;
252 u_char sp_max_link_quality;
253 u_char linkQualityGoodFairBoundary;
254 u_char linkQualityFairPoorBoundary;
255 u_char sp_utilization;
256 u_char sp_goodness;
257 u_char sp_hotheadcount;
258 u_char roaming_condition;
259
260 net_addr sp;
261 u_char numAPs;
262 net_addr nearByAccessPoints[MAX_ESA];
263};
264
265typedef struct netwave_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100266 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
268 dev_node_t node;
269 u_char __iomem *ramBase;
270 int timeoutCounter;
271 int lastExec;
272 struct timer_list watchdog; /* To avoid blocking state */
273 struct site_survey nss;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 struct iw_statistics iw_stats; /* Wireless stats */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275} netwave_private;
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277/*
278 * The Netwave card is little-endian, so won't work for big endian
279 * systems.
280 */
281static inline unsigned short get_uint16(u_char __iomem *staddr)
282{
283 return readw(staddr); /* Return only 16 bits */
284}
285
286static inline short get_int16(u_char __iomem * staddr)
287{
288 return readw(staddr);
289}
290
291/*
292 * Wait until the WOC (Write Operation Complete) bit in the
293 * ASR (Adapter Status Register) is asserted.
294 * This should have aborted if it takes too long time.
295 */
296static inline void wait_WOC(unsigned int iobase)
297{
298 /* Spin lock */
299 while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
300}
301
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
Olof Johansson906da802008-02-04 22:27:35 -0800303 unsigned int iobase) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 u_short resultBuffer;
305
306 /* if time since last snapshot is > 1 sec. (100 jiffies?) then take
307 * new snapshot, else return cached data. This is the recommended rate.
308 */
309 if ( jiffies - priv->lastExec > 100) {
310 /* Take site survey snapshot */
311 /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies -
312 priv->lastExec); */
313 wait_WOC(iobase);
314 writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0);
315 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
316 wait_WOC(iobase);
317
318 /* Get result and copy to cach */
319 resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP);
320 copy_from_pc( &priv->nss, ramBase+resultBuffer,
321 sizeof(struct site_survey));
322 }
323}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325/*
326 * Function netwave_get_wireless_stats (dev)
327 *
328 * Wireless extensions statistics
329 *
330 */
331static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
332{
333 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800334 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 netwave_private *priv = netdev_priv(dev);
336 u_char __iomem *ramBase = priv->ramBase;
337 struct iw_statistics* wstats;
338
339 wstats = &priv->iw_stats;
340
341 spin_lock_irqsave(&priv->spinlock, flags);
342
343 netwave_snapshot( priv, ramBase, iobase);
344
345 wstats->status = priv->nss.roaming_state;
346 wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ);
347 wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ);
348 wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f;
349 wstats->discard.nwid = 0L;
350 wstats->discard.code = 0L;
351 wstats->discard.misc = 0L;
352
353 spin_unlock_irqrestore(&priv->spinlock, flags);
354
355 return &priv->iw_stats;
356}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358/*
359 * Function netwave_attach (void)
360 *
361 * Creates an "instance" of the driver, allocating local data
362 * structures for one device. The device is registered with Card
363 * Services.
364 *
365 * The dev_link structure is initialized, but we don't actually
366 * configure the card at this point -- we wait until we receive a
367 * card insertion event.
368 */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200369static int netwave_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 struct net_device *dev;
372 netwave_private *priv;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 DEBUG(0, "netwave_attach()\n");
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100375
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200376 /* Initialize the struct pcmcia_device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 dev = alloc_etherdev(sizeof(netwave_private));
378 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100379 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200381 priv->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 link->priv = dev;
383
384 /* The io structure describes IO port mapping */
385 link->io.NumPorts1 = 16;
386 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
387 /* link->io.NumPorts2 = 16;
388 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
389 link->io.IOAddrLines = 5;
390
391 /* Interrupt setup */
Alan Cox47cbb112008-09-23 13:53:09 +0100392 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
394 link->irq.Handler = &netwave_interrupt;
395
396 /* General socket configuration */
397 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 link->conf.IntType = INT_MEMORY_AND_IO;
399 link->conf.ConfigIndex = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
401 /* Netwave private struct init. link/dev/node already taken care of,
402 * other stuff zero'd - Jean II */
403 spin_lock_init(&priv->spinlock);
404
405 /* Netwave specific entries in the device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 dev->hard_start_xmit = &netwave_start_xmit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 dev->set_multicast_list = &set_multicast_list;
408 /* wireless extensions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
411 dev->tx_timeout = &netwave_watchdog;
412 dev->watchdog_timeo = TX_TIMEOUT;
413
414 dev->open = &netwave_open;
415 dev->stop = &netwave_close;
416 link->irq.Instance = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200418 return netwave_pcmcia_config( link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419} /* netwave_attach */
420
421/*
422 * Function netwave_detach (link)
423 *
424 * This deletes a driver "instance". The device is de-registered
425 * with Card Services. If it has been released, all local data
426 * structures are freed. Otherwise, the structures will be freed
427 * when the device is released.
428 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200429static void netwave_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430{
Dominik Brodowskib4635812005-11-14 21:25:35 +0100431 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
Dominik Brodowskib4635812005-11-14 21:25:35 +0100433 DEBUG(0, "netwave_detach(0x%p)\n", link);
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100434
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100435 netwave_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
Dominik Brodowskifd238232006-03-05 10:45:09 +0100437 if (link->dev_node)
Dominik Brodowskib4635812005-11-14 21:25:35 +0100438 unregister_netdev(dev);
439
440 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441} /* netwave_detach */
442
443/*
444 * Wireless Handler : get protocol name
445 */
446static int netwave_get_name(struct net_device *dev,
447 struct iw_request_info *info,
448 union iwreq_data *wrqu,
449 char *extra)
450{
451 strcpy(wrqu->name, "Netwave");
452 return 0;
453}
454
455/*
456 * Wireless Handler : set Network ID
457 */
458static int netwave_set_nwid(struct net_device *dev,
459 struct iw_request_info *info,
460 union iwreq_data *wrqu,
461 char *extra)
462{
463 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800464 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 netwave_private *priv = netdev_priv(dev);
466 u_char __iomem *ramBase = priv->ramBase;
467
468 /* Disable interrupts & save flags */
469 spin_lock_irqsave(&priv->spinlock, flags);
470
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 if(!wrqu->nwid.disabled) {
472 domain = wrqu->nwid.value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
474 (domain >> 8) & 0x01, domain & 0xff);
475 wait_WOC(iobase);
476 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
477 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
478 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
479 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
480 }
481
482 /* ReEnable interrupts & restore flags */
483 spin_unlock_irqrestore(&priv->spinlock, flags);
484
485 return 0;
486}
487
488/*
489 * Wireless Handler : get Network ID
490 */
491static int netwave_get_nwid(struct net_device *dev,
492 struct iw_request_info *info,
493 union iwreq_data *wrqu,
494 char *extra)
495{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 wrqu->nwid.value = domain;
497 wrqu->nwid.disabled = 0;
498 wrqu->nwid.fixed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 return 0;
500}
501
502/*
503 * Wireless Handler : set scramble key
504 */
505static int netwave_set_scramble(struct net_device *dev,
506 struct iw_request_info *info,
507 union iwreq_data *wrqu,
508 char *key)
509{
510 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800511 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 netwave_private *priv = netdev_priv(dev);
513 u_char __iomem *ramBase = priv->ramBase;
514
515 /* Disable interrupts & save flags */
516 spin_lock_irqsave(&priv->spinlock, flags);
517
518 scramble_key = (key[0] << 8) | key[1];
519 wait_WOC(iobase);
520 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
521 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
522 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
523 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
524
525 /* ReEnable interrupts & restore flags */
526 spin_unlock_irqrestore(&priv->spinlock, flags);
527
528 return 0;
529}
530
531/*
532 * Wireless Handler : get scramble key
533 */
534static int netwave_get_scramble(struct net_device *dev,
535 struct iw_request_info *info,
536 union iwreq_data *wrqu,
537 char *key)
538{
539 key[1] = scramble_key & 0xff;
540 key[0] = (scramble_key>>8) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 wrqu->encoding.flags = IW_ENCODE_ENABLED;
542 wrqu->encoding.length = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 return 0;
544}
545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546/*
547 * Wireless Handler : get mode
548 */
549static int netwave_get_mode(struct net_device *dev,
550 struct iw_request_info *info,
551 union iwreq_data *wrqu,
552 char *extra)
553{
554 if(domain & 0x100)
555 wrqu->mode = IW_MODE_INFRA;
556 else
557 wrqu->mode = IW_MODE_ADHOC;
558
559 return 0;
560}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562/*
563 * Wireless Handler : get range info
564 */
565static int netwave_get_range(struct net_device *dev,
566 struct iw_request_info *info,
567 union iwreq_data *wrqu,
568 char *extra)
569{
570 struct iw_range *range = (struct iw_range *) extra;
571 int ret = 0;
572
573 /* Set the length (very important for backward compatibility) */
574 wrqu->data.length = sizeof(struct iw_range);
575
576 /* Set all the info we don't care or don't know about to zero */
577 memset(range, 0, sizeof(struct iw_range));
578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 /* Set the Wireless Extension versions */
580 range->we_version_compiled = WIRELESS_EXT;
581 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
583 /* Set information in the range struct */
584 range->throughput = 450 * 1000; /* don't argue on this ! */
585 range->min_nwid = 0x0000;
586 range->max_nwid = 0x01FF;
587
588 range->num_channels = range->num_frequency = 0;
589
590 range->sensitivity = 0x3F;
591 range->max_qual.qual = 255;
592 range->max_qual.level = 255;
593 range->max_qual.noise = 0;
594
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 range->num_bitrates = 1;
596 range->bitrate[0] = 1000000; /* 1 Mb/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 range->encoding_size[0] = 2; /* 16 bits scrambling */
599 range->num_encoding_sizes = 1;
600 range->max_encoding_tokens = 1; /* Only one key possible */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
602 return ret;
603}
604
605/*
606 * Wireless Private Handler : get snapshot
607 */
608static int netwave_get_snap(struct net_device *dev,
609 struct iw_request_info *info,
610 union iwreq_data *wrqu,
611 char *extra)
612{
613 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800614 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 netwave_private *priv = netdev_priv(dev);
616 u_char __iomem *ramBase = priv->ramBase;
617
618 /* Disable interrupts & save flags */
619 spin_lock_irqsave(&priv->spinlock, flags);
620
621 /* Take snapshot of environment */
622 netwave_snapshot( priv, ramBase, iobase);
623 wrqu->data.length = priv->nss.length;
624 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
625
626 priv->lastExec = jiffies;
627
628 /* ReEnable interrupts & restore flags */
629 spin_unlock_irqrestore(&priv->spinlock, flags);
630
631 return(0);
632}
633
634/*
635 * Structures to export the Wireless Handlers
636 * This is the stuff that are treated the wireless extensions (iwconfig)
637 */
638
639static const struct iw_priv_args netwave_private_args[] = {
640/*{ cmd, set_args, get_args, name } */
641 { SIOCGIPSNAP, 0,
642 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
643 "getsitesurvey" },
644};
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646static const iw_handler netwave_handler[] =
647{
648 NULL, /* SIOCSIWNAME */
649 netwave_get_name, /* SIOCGIWNAME */
650 netwave_set_nwid, /* SIOCSIWNWID */
651 netwave_get_nwid, /* SIOCGIWNWID */
652 NULL, /* SIOCSIWFREQ */
653 NULL, /* SIOCGIWFREQ */
654 NULL, /* SIOCSIWMODE */
655 netwave_get_mode, /* SIOCGIWMODE */
656 NULL, /* SIOCSIWSENS */
657 NULL, /* SIOCGIWSENS */
658 NULL, /* SIOCSIWRANGE */
659 netwave_get_range, /* SIOCGIWRANGE */
660 NULL, /* SIOCSIWPRIV */
661 NULL, /* SIOCGIWPRIV */
662 NULL, /* SIOCSIWSTATS */
663 NULL, /* SIOCGIWSTATS */
664 NULL, /* SIOCSIWSPY */
665 NULL, /* SIOCGIWSPY */
666 NULL, /* -- hole -- */
667 NULL, /* -- hole -- */
668 NULL, /* SIOCSIWAP */
669 NULL, /* SIOCGIWAP */
670 NULL, /* -- hole -- */
671 NULL, /* SIOCGIWAPLIST */
672 NULL, /* -- hole -- */
673 NULL, /* -- hole -- */
674 NULL, /* SIOCSIWESSID */
675 NULL, /* SIOCGIWESSID */
676 NULL, /* SIOCSIWNICKN */
677 NULL, /* SIOCGIWNICKN */
678 NULL, /* -- hole -- */
679 NULL, /* -- hole -- */
680 NULL, /* SIOCSIWRATE */
681 NULL, /* SIOCGIWRATE */
682 NULL, /* SIOCSIWRTS */
683 NULL, /* SIOCGIWRTS */
684 NULL, /* SIOCSIWFRAG */
685 NULL, /* SIOCGIWFRAG */
686 NULL, /* SIOCSIWTXPOW */
687 NULL, /* SIOCGIWTXPOW */
688 NULL, /* SIOCSIWRETRY */
689 NULL, /* SIOCGIWRETRY */
690 netwave_set_scramble, /* SIOCSIWENCODE */
691 netwave_get_scramble, /* SIOCGIWENCODE */
692};
693
694static const iw_handler netwave_private_handler[] =
695{
696 NULL, /* SIOCIWFIRSTPRIV */
697 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
698};
699
700static const struct iw_handler_def netwave_handler_def =
701{
Denis Chengff8ac602007-09-02 18:30:18 +0800702 .num_standard = ARRAY_SIZE(netwave_handler),
703 .num_private = ARRAY_SIZE(netwave_private_handler),
704 .num_private_args = ARRAY_SIZE(netwave_private_args),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 .standard = (iw_handler *) netwave_handler,
706 .private = (iw_handler *) netwave_private_handler,
707 .private_args = (struct iw_priv_args *) netwave_private_args,
Jean Tourrilhes62337dd2005-09-02 11:39:02 -0700708 .get_wireless_stats = netwave_get_wireless_stats,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710
711/*
712 * Function netwave_pcmcia_config (link)
713 *
714 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
715 * event is received, to configure the PCMCIA socket, and to make the
716 * device available to the system.
717 *
718 */
719
720#define CS_CHECK(fn, ret) \
721do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
722
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200723static int netwave_pcmcia_config(struct pcmcia_device *link) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 struct net_device *dev = link->priv;
725 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 int i, j, last_ret, last_fn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 win_req_t req;
728 memreq_t mem;
729 u_char __iomem *ramBase = NULL;
730
731 DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
732
733 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 * Try allocating IO ports. This tries a few fixed addresses.
735 * If you want, you can also read the card's config table to
736 * pick addresses -- see the serial driver for an example.
737 */
738 for (i = j = 0x0; j < 0x400; j += 0x20) {
739 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200740 i = pcmcia_request_io(link, &link->io);
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200741 if (i == 0)
742 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 }
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200744 if (i != 0) {
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200745 cs_error(link, RequestIO, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 goto failed;
747 }
748
749 /*
750 * Now allocate an interrupt line. Note that this does not
751 * actually assign a handler to the interrupt.
752 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200753 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754
755 /*
756 * This actually configures the PCMCIA socket -- setting up
757 * the I/O windows and the interrupt mapping.
758 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200759 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760
761 /*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200762 * Allocate a 32K memory window. Note that the struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 * structure provides space for one window handle -- if your
764 * device needs several windows, you'll need to keep track of
765 * the handles in your private data structure, dev->priv.
766 */
767 DEBUG(1, "Setting mem speed of %d\n", mem_speed);
768
769 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
770 req.Base = 0; req.Size = 0x8000;
771 req.AccessSpeed = mem_speed;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200772 CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 mem.CardOffset = 0x20000; mem.Page = 0;
774 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
775
776 /* Store base address of the common window frame */
777 ramBase = ioremap(req.Base, 0x8000);
778 priv->ramBase = ramBase;
779
780 dev->irq = link->irq.AssignedIRQ;
781 dev->base_addr = link->io.BasePort1;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200782 SET_NETDEV_DEV(dev, &handle_to_dev(link));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
784 if (register_netdev(dev) != 0) {
785 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
786 goto failed;
787 }
788
789 strcpy(priv->node.dev_name, dev->name);
Dominik Brodowskifd238232006-03-05 10:45:09 +0100790 link->dev_node = &priv->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
792 /* Reset card before reading physical address */
793 netwave_doreset(dev->base_addr, ramBase);
794
795 /* Read the ethernet address and fill in the Netwave registers. */
796 for (i = 0; i < 6; i++)
797 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
798
Joe Perches8376e7a2007-11-19 17:48:27 -0800799 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
Johannes Berge1749612008-10-27 15:59:26 -0700800 "id %c%c, hw_addr %pM\n",
Joe Perches0795af52007-10-03 17:59:30 -0700801 dev->name, dev->base_addr, dev->irq,
802 (u_long) ramBase,
803 (int) readb(ramBase+NETWAVE_EREG_NI),
804 (int) readb(ramBase+NETWAVE_EREG_NI+1),
Johannes Berge1749612008-10-27 15:59:26 -0700805 dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806
807 /* get revision words */
808 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
809 get_uint16(ramBase + NETWAVE_EREG_ARW),
810 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200811 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
813cs_failed:
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200814 cs_error(link, last_fn, last_ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815failed:
816 netwave_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200817 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818} /* netwave_pcmcia_config */
819
820/*
821 * Function netwave_release (arg)
822 *
823 * After a card is removed, netwave_release() will unregister the net
824 * device, and release the PCMCIA configuration. If the device is
825 * still open, this will be postponed until it is closed.
826 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200827static void netwave_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100829 struct net_device *dev = link->priv;
830 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100832 DEBUG(0, "netwave_release(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200834 pcmcia_disable_device(link);
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100835 if (link->win)
836 iounmap(priv->ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837}
838
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200839static int netwave_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100840{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100841 struct net_device *dev = link->priv;
842
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100843 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100844 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100845
846 return 0;
847}
848
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200849static int netwave_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100850{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100851 struct net_device *dev = link->priv;
852
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100853 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100854 netwave_reset(dev);
855 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100856 }
857
858 return 0;
859}
860
861
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 * Function netwave_doreset (ioBase, ramBase)
864 *
865 * Proper hardware reset of the card.
866 */
Olof Johansson906da802008-02-04 22:27:35 -0800867static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868{
869 /* Reset card */
870 wait_WOC(ioBase);
871 outb(0x80, ioBase + NETWAVE_REG_PMR);
872 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
873 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
874}
875
876/*
877 * Function netwave_reset (dev)
878 *
879 * Reset and restore all of the netwave registers
880 */
881static void netwave_reset(struct net_device *dev) {
882 /* u_char state; */
883 netwave_private *priv = netdev_priv(dev);
884 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800885 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 DEBUG(0, "netwave_reset: Done with hardware reset\n");
888
889 priv->timeoutCounter = 0;
890
891 /* Reset card */
892 netwave_doreset(iobase, ramBase);
893 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
894
895 /* Write a NOP to check the card */
896 wait_WOC(iobase);
897 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
898 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
899
900 /* Set receive conf */
901 wait_WOC(iobase);
902 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
903 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
904 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
905
906 /* Set transmit conf */
907 wait_WOC(iobase);
908 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
909 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
910 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
911
912 /* Now set the MU Domain */
913 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
914 wait_WOC(iobase);
915 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
916 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
917 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
918 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
919
920 /* Set scramble key */
921 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
922 wait_WOC(iobase);
923 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
924 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
925 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
926 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
927
928 /* Enable interrupts, bit 4 high to keep unused
929 * source from interrupting us, bit 2 high to
930 * set interrupt enable, 567 to enable TxDN,
931 * RxErr and RxRdy
932 */
933 wait_WOC(iobase);
934 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
935
936 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
937 * waitWOC
938 * skriv 80 til d000:3688
939 * sjekk om det ble 80
940 */
941
942 /* Enable Receiver */
943 wait_WOC(iobase);
944 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
945 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
946
947 /* Set the IENA bit in COR */
948 wait_WOC(iobase);
949 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
950}
951
952/*
953 * Function netwave_hw_xmit (data, len, dev)
954 */
955static int netwave_hw_xmit(unsigned char* data, int len,
956 struct net_device* dev) {
957 unsigned long flags;
958 unsigned int TxFreeList,
959 curBuff,
960 MaxData,
961 DataOffset;
962 int tmpcount;
963
964 netwave_private *priv = netdev_priv(dev);
965 u_char __iomem * ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800966 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
968 /* Disable interrupts & save flags */
969 spin_lock_irqsave(&priv->spinlock, flags);
970
971 /* Check if there are transmit buffers available */
972 wait_WOC(iobase);
973 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
974 /* No buffers available */
975 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
976 dev->name);
977 spin_unlock_irqrestore(&priv->spinlock, flags);
978 return 1;
979 }
980
Stephen Hemmingerf56ef162009-03-20 19:36:21 +0000981 dev->stats.tx_bytes += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982
983 DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
984 readb(ramBase + NETWAVE_EREG_SPCQ),
985 readb(ramBase + NETWAVE_EREG_SPU),
986 readb(ramBase + NETWAVE_EREG_LIF),
987 readb(ramBase + NETWAVE_EREG_ISPLQ));
988
989 /* Now try to insert it into the adapters free memory */
990 wait_WOC(iobase);
991 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
992 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
993 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
994
995 DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
996 TxFreeList, MaxData, DataOffset);
997
998 /* Copy packet to the adapter fragment buffers */
999 curBuff = TxFreeList;
1000 tmpcount = 0;
1001 while (tmpcount < len) {
1002 int tmplen = len - tmpcount;
1003 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
1004 (tmplen < MaxData) ? tmplen : MaxData);
1005 tmpcount += MaxData;
1006
1007 /* Advance to next buffer */
1008 curBuff = get_uint16(ramBase + curBuff);
1009 }
1010
1011 /* Now issue transmit list */
1012 wait_WOC(iobase);
1013 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1014 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1015 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1016 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1017
1018 spin_unlock_irqrestore(&priv->spinlock, flags);
1019 return 0;
1020}
1021
1022static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1023 /* This flag indicate that the hardware can't perform a transmission.
1024 * Theoritically, NET3 check it before sending a packet to the driver,
1025 * but in fact it never do that and pool continuously.
1026 * As the watchdog will abort too long transmissions, we are quite safe...
1027 */
1028
1029 netif_stop_queue(dev);
1030
1031 {
1032 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1033 unsigned char* buf = skb->data;
1034
1035 if (netwave_hw_xmit( buf, length, dev) == 1) {
1036 /* Some error, let's make them call us another time? */
1037 netif_start_queue(dev);
1038 }
1039 dev->trans_start = jiffies;
1040 }
1041 dev_kfree_skb(skb);
1042
1043 return 0;
1044} /* netwave_start_xmit */
1045
1046/*
David Howells7d12e782006-10-05 14:55:46 +01001047 * Function netwave_interrupt (irq, dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 *
1049 * This function is the interrupt handler for the Netwave card. This
1050 * routine will be called whenever:
1051 * 1. A packet is received.
1052 * 2. A packet has successfully been transferred and the unit is
1053 * ready to transmit another packet.
1054 * 3. A command has completed execution.
1055 */
David Howells7d12e782006-10-05 14:55:46 +01001056static irqreturn_t netwave_interrupt(int irq, void* dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057{
Olof Johansson906da802008-02-04 22:27:35 -08001058 unsigned int iobase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 u_char __iomem *ramBase;
1060 struct net_device *dev = (struct net_device *)dev_id;
1061 struct netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001062 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 int i;
1064
1065 if (!netif_device_present(dev))
1066 return IRQ_NONE;
1067
1068 iobase = dev->base_addr;
1069 ramBase = priv->ramBase;
1070
1071 /* Now find what caused the interrupt, check while interrupts ready */
1072 for (i = 0; i < 10; i++) {
1073 u_char status;
1074
1075 wait_WOC(iobase);
1076 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1077 break; /* None of the interrupt sources asserted (normal exit) */
1078
1079 status = inb(iobase + NETWAVE_REG_ASR);
1080
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001081 if (!pcmcia_dev_present(link)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
1083 "from removed or suspended card!\n", status);
1084 break;
1085 }
1086
1087 /* RxRdy */
1088 if (status & 0x80) {
1089 netwave_rx(dev);
1090 /* wait_WOC(iobase); */
1091 /* RxRdy cannot be reset directly by the host */
1092 }
1093 /* RxErr */
1094 if (status & 0x40) {
1095 u_char rser;
1096
1097 rser = readb(ramBase + NETWAVE_EREG_RSER);
1098
1099 if (rser & 0x04) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001100 ++dev->stats.rx_dropped;
1101 ++dev->stats.rx_crc_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 }
1103 if (rser & 0x02)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001104 ++dev->stats.rx_frame_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
1106 /* Clear the RxErr bit in RSER. RSER+4 is the
1107 * write part. Also clear the RxCRC (0x04) and
1108 * RxBig (0x02) bits if present */
1109 wait_WOC(iobase);
1110 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1111
1112 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1113 * WOC must be set first!
1114 */
1115 wait_WOC(iobase);
1116 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1117
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001118 /* Remember to count up dev->stats on error packets */
1119 ++dev->stats.rx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 }
1121 /* TxDN */
1122 if (status & 0x20) {
1123 int txStatus;
1124
1125 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
1126 DEBUG(3, "Transmit done. TSER = %x id %x\n",
1127 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1128
1129 if (txStatus & 0x20) {
1130 /* Transmitting was okay, clear bits */
1131 wait_WOC(iobase);
1132 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001133 ++dev->stats.tx_packets;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 }
1135
1136 if (txStatus & 0xd0) {
1137 if (txStatus & 0x80) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001138 ++dev->stats.collisions; /* Because of /proc/net/dev*/
1139 /* ++dev->stats.tx_aborted_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1141 }
1142 if (txStatus & 0x40)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001143 ++dev->stats.tx_carrier_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 /* 0x80 TxGU Transmit giveup - nine times and no luck
1145 * 0x40 TxNOAP No access point. Discarded packet.
1146 * 0x10 TxErr Transmit error. Always set when
1147 * TxGU and TxNOAP is set. (Those are the only ones
1148 * to set TxErr).
1149 */
1150 DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
1151 txStatus);
1152
1153 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1154 wait_WOC(iobase);
1155 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001156 ++dev->stats.tx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 }
1158 DEBUG(3, "New status is TSER %x ASR %x\n",
1159 readb(ramBase + NETWAVE_EREG_TSER),
1160 inb(iobase + NETWAVE_REG_ASR));
1161
1162 netif_wake_queue(dev);
1163 }
1164 /* TxBA, this would trigger on all error packets received */
1165 /* if (status & 0x01) {
1166 DEBUG(4, "Transmit buffers available, %x\n", status);
1167 }
1168 */
1169 }
1170 /* Handled if we looped at least one time - Jean II */
1171 return IRQ_RETVAL(i);
1172} /* netwave_interrupt */
1173
1174/*
1175 * Function netwave_watchdog (a)
1176 *
1177 * Watchdog : when we start a transmission, we set a timer in the
1178 * kernel. If the transmission complete, this timer is disabled. If
1179 * it expire, we reset the card.
1180 *
1181 */
1182static void netwave_watchdog(struct net_device *dev) {
1183
1184 DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
1185 netwave_reset(dev);
1186 dev->trans_start = jiffies;
1187 netif_wake_queue(dev);
1188} /* netwave_watchdog */
1189
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190static int netwave_rx(struct net_device *dev)
1191{
1192 netwave_private *priv = netdev_priv(dev);
1193 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -08001194 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 u_char rxStatus;
1196 struct sk_buff *skb = NULL;
1197 unsigned int curBuffer,
1198 rcvList;
1199 int rcvLen;
1200 int tmpcount = 0;
1201 int dataCount, dataOffset;
1202 int i;
1203 u_char *ptr;
1204
1205 DEBUG(3, "xinw_rx: Receiving ... \n");
1206
1207 /* Receive max 10 packets for now. */
1208 for (i = 0; i < 10; i++) {
1209 /* Any packets? */
1210 wait_WOC(iobase);
1211 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1212 if ( !( rxStatus & 0x80)) /* No more packets */
1213 break;
1214
1215 /* Check if multicast/broadcast or other */
1216 /* multicast = (rxStatus & 0x20); */
1217
1218 /* The receive list pointer and length of the packet */
1219 wait_WOC(iobase);
1220 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1221 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1222
1223 if (rcvLen < 0) {
1224 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1225 rcvLen);
1226 return 0;
1227 }
1228
1229 skb = dev_alloc_skb(rcvLen+5);
1230 if (skb == NULL) {
1231 DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
1232 "length %d\n", rcvLen);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001233 ++dev->stats.rx_dropped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 /* Tell the adapter to skip the packet */
1235 wait_WOC(iobase);
1236 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1237 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1238 return 0;
1239 }
1240
1241 skb_reserve( skb, 2); /* Align IP on 16 byte */
1242 skb_put( skb, rcvLen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
1244 /* Copy packet fragments to the skb data area */
1245 ptr = (u_char*) skb->data;
1246 curBuffer = rcvList;
1247 tmpcount = 0;
1248 while ( tmpcount < rcvLen) {
1249 /* Get length and offset of current buffer */
1250 dataCount = get_uint16( ramBase+curBuffer+2);
1251 dataOffset = get_uint16( ramBase+curBuffer+4);
1252
1253 copy_from_pc( ptr + tmpcount,
1254 ramBase+curBuffer+dataOffset, dataCount);
1255
1256 tmpcount += dataCount;
1257
1258 /* Point to next buffer */
1259 curBuffer = get_uint16(ramBase + curBuffer);
1260 }
1261
1262 skb->protocol = eth_type_trans(skb,dev);
1263 /* Queue packet for network layer */
1264 netif_rx(skb);
1265
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001266 dev->stats.rx_packets++;
1267 dev->stats.rx_bytes += rcvLen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
1269 /* Got the packet, tell the adapter to skip it */
1270 wait_WOC(iobase);
1271 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1272 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1273 DEBUG(3, "Packet reception ok\n");
1274 }
1275 return 0;
1276}
1277
1278static int netwave_open(struct net_device *dev) {
1279 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001280 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281
1282 DEBUG(1, "netwave_open: starting.\n");
1283
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001284 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 return -ENODEV;
1286
1287 link->open++;
1288
1289 netif_start_queue(dev);
1290 netwave_reset(dev);
1291
1292 return 0;
1293}
1294
1295static int netwave_close(struct net_device *dev) {
1296 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001297 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298
1299 DEBUG(1, "netwave_close: finishing.\n");
1300
1301 link->open--;
1302 netif_stop_queue(dev);
1303
1304 return 0;
1305}
1306
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001307static struct pcmcia_device_id netwave_ids[] = {
1308 PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
1309 PCMCIA_DEVICE_NULL,
1310};
1311MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
1312
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313static struct pcmcia_driver netwave_driver = {
1314 .owner = THIS_MODULE,
1315 .drv = {
1316 .name = "netwave_cs",
1317 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001318 .probe = netwave_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001319 .remove = netwave_detach,
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001320 .id_table = netwave_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001321 .suspend = netwave_suspend,
1322 .resume = netwave_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323};
1324
1325static int __init init_netwave_cs(void)
1326{
1327 return pcmcia_register_driver(&netwave_driver);
1328}
1329
1330static void __exit exit_netwave_cs(void)
1331{
1332 pcmcia_unregister_driver(&netwave_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333}
1334
1335module_init(init_netwave_cs);
1336module_exit(exit_netwave_cs);
1337
1338/* Set or clear the multicast filter for this adaptor.
1339 num_addrs == -1 Promiscuous mode, receive all packets
1340 num_addrs == 0 Normal mode, clear multicast list
1341 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1342 best-effort filtering.
1343 */
1344static void set_multicast_list(struct net_device *dev)
1345{
Olof Johansson906da802008-02-04 22:27:35 -08001346 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 netwave_private *priv = netdev_priv(dev);
1348 u_char __iomem * ramBase = priv->ramBase;
1349 u_char rcvMode = 0;
1350
1351#ifdef PCMCIA_DEBUG
1352 if (pc_debug > 2) {
1353 static int old;
1354 if (old != dev->mc_count) {
1355 old = dev->mc_count;
1356 DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
1357 dev->name, dev->mc_count);
1358 }
1359 }
1360#endif
1361
1362 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1363 /* Multicast Mode */
1364 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1365 } else if (dev->flags & IFF_PROMISC) {
1366 /* Promiscous mode */
1367 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1368 } else {
1369 /* Normal mode */
1370 rcvMode = rxConfRxEna + rxConfBcast;
1371 }
1372
1373 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1374 /* Now set receive mode */
1375 wait_WOC(iobase);
1376 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1377 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1378 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1379}
1380MODULE_LICENSE("GPL");