blob: a670f36b5f3f3c1e3222d0e45c27491132caed7d [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
213/* Statistics */
214static void update_stats(struct net_device *dev);
215static struct net_device_stats *netwave_get_stats(struct net_device *dev);
216
217/* Wireless extensions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
220static void set_multicast_list(struct net_device *dev);
221
222/*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200223 A struct pcmcia_device structure has fields for most things that are needed
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 to keep track of a socket, but there will usually be some device
225 specific information that also needs to be kept track of. The
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200226 'priv' pointer in a struct pcmcia_device structure can be used to point to
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 a device-specific private data structure, like this.
228
229 A driver needs to provide a dev_node_t structure for each device
230 on a card. In some cases, there is only one device per card (for
231 example, ethernet cards, modems). In other cases, there may be
232 many actual or logical devices (SCSI adapters, memory cards with
233 multiple partitions). The dev_node_t structures need to be kept
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200234 in a linked list starting at the 'dev' field of a struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 structure. We allocate them in the card's private data structure,
236 because they generally can't be allocated dynamically.
237*/
238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239static const struct iw_handler_def netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240
241#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
242
243#define MAX_ESA 10
244
245typedef struct net_addr {
246 u_char addr48[6];
247} net_addr;
248
249struct site_survey {
250 u_short length;
251 u_char struct_revision;
252 u_char roaming_state;
253
254 u_char sp_existsFlag;
255 u_char sp_link_quality;
256 u_char sp_max_link_quality;
257 u_char linkQualityGoodFairBoundary;
258 u_char linkQualityFairPoorBoundary;
259 u_char sp_utilization;
260 u_char sp_goodness;
261 u_char sp_hotheadcount;
262 u_char roaming_condition;
263
264 net_addr sp;
265 u_char numAPs;
266 net_addr nearByAccessPoints[MAX_ESA];
267};
268
269typedef struct netwave_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100270 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
272 dev_node_t node;
273 u_char __iomem *ramBase;
274 int timeoutCounter;
275 int lastExec;
276 struct timer_list watchdog; /* To avoid blocking state */
277 struct site_survey nss;
278 struct net_device_stats stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 struct iw_statistics iw_stats; /* Wireless stats */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280} netwave_private;
281
282#ifdef NETWAVE_STATS
283static struct net_device_stats *netwave_get_stats(struct net_device *dev);
284#endif
285
286/*
287 * The Netwave card is little-endian, so won't work for big endian
288 * systems.
289 */
290static inline unsigned short get_uint16(u_char __iomem *staddr)
291{
292 return readw(staddr); /* Return only 16 bits */
293}
294
295static inline short get_int16(u_char __iomem * staddr)
296{
297 return readw(staddr);
298}
299
300/*
301 * Wait until the WOC (Write Operation Complete) bit in the
302 * ASR (Adapter Status Register) is asserted.
303 * This should have aborted if it takes too long time.
304 */
305static inline void wait_WOC(unsigned int iobase)
306{
307 /* Spin lock */
308 while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
309}
310
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
Olof Johansson906da802008-02-04 22:27:35 -0800312 unsigned int iobase) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 u_short resultBuffer;
314
315 /* if time since last snapshot is > 1 sec. (100 jiffies?) then take
316 * new snapshot, else return cached data. This is the recommended rate.
317 */
318 if ( jiffies - priv->lastExec > 100) {
319 /* Take site survey snapshot */
320 /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies -
321 priv->lastExec); */
322 wait_WOC(iobase);
323 writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0);
324 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
325 wait_WOC(iobase);
326
327 /* Get result and copy to cach */
328 resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP);
329 copy_from_pc( &priv->nss, ramBase+resultBuffer,
330 sizeof(struct site_survey));
331 }
332}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334/*
335 * Function netwave_get_wireless_stats (dev)
336 *
337 * Wireless extensions statistics
338 *
339 */
340static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
341{
342 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800343 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 netwave_private *priv = netdev_priv(dev);
345 u_char __iomem *ramBase = priv->ramBase;
346 struct iw_statistics* wstats;
347
348 wstats = &priv->iw_stats;
349
350 spin_lock_irqsave(&priv->spinlock, flags);
351
352 netwave_snapshot( priv, ramBase, iobase);
353
354 wstats->status = priv->nss.roaming_state;
355 wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ);
356 wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ);
357 wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f;
358 wstats->discard.nwid = 0L;
359 wstats->discard.code = 0L;
360 wstats->discard.misc = 0L;
361
362 spin_unlock_irqrestore(&priv->spinlock, flags);
363
364 return &priv->iw_stats;
365}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
367/*
368 * Function netwave_attach (void)
369 *
370 * Creates an "instance" of the driver, allocating local data
371 * structures for one device. The device is registered with Card
372 * Services.
373 *
374 * The dev_link structure is initialized, but we don't actually
375 * configure the card at this point -- we wait until we receive a
376 * card insertion event.
377 */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200378static int netwave_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 struct net_device *dev;
381 netwave_private *priv;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 DEBUG(0, "netwave_attach()\n");
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100384
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200385 /* Initialize the struct pcmcia_device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 dev = alloc_etherdev(sizeof(netwave_private));
387 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100388 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200390 priv->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 link->priv = dev;
392
393 /* The io structure describes IO port mapping */
394 link->io.NumPorts1 = 16;
395 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
396 /* link->io.NumPorts2 = 16;
397 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
398 link->io.IOAddrLines = 5;
399
400 /* Interrupt setup */
Alan Cox47cbb112008-09-23 13:53:09 +0100401 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
403 link->irq.Handler = &netwave_interrupt;
404
405 /* General socket configuration */
406 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 link->conf.IntType = INT_MEMORY_AND_IO;
408 link->conf.ConfigIndex = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
410 /* Netwave private struct init. link/dev/node already taken care of,
411 * other stuff zero'd - Jean II */
412 spin_lock_init(&priv->spinlock);
413
414 /* Netwave specific entries in the device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 dev->hard_start_xmit = &netwave_start_xmit;
416 dev->get_stats = &netwave_get_stats;
417 dev->set_multicast_list = &set_multicast_list;
418 /* wireless extensions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
421 dev->tx_timeout = &netwave_watchdog;
422 dev->watchdog_timeo = TX_TIMEOUT;
423
424 dev->open = &netwave_open;
425 dev->stop = &netwave_close;
426 link->irq.Instance = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200428 return netwave_pcmcia_config( link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429} /* netwave_attach */
430
431/*
432 * Function netwave_detach (link)
433 *
434 * This deletes a driver "instance". The device is de-registered
435 * with Card Services. If it has been released, all local data
436 * structures are freed. Otherwise, the structures will be freed
437 * when the device is released.
438 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200439static void netwave_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440{
Dominik Brodowskib4635812005-11-14 21:25:35 +0100441 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
Dominik Brodowskib4635812005-11-14 21:25:35 +0100443 DEBUG(0, "netwave_detach(0x%p)\n", link);
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100444
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100445 netwave_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
Dominik Brodowskifd238232006-03-05 10:45:09 +0100447 if (link->dev_node)
Dominik Brodowskib4635812005-11-14 21:25:35 +0100448 unregister_netdev(dev);
449
450 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451} /* netwave_detach */
452
453/*
454 * Wireless Handler : get protocol name
455 */
456static int netwave_get_name(struct net_device *dev,
457 struct iw_request_info *info,
458 union iwreq_data *wrqu,
459 char *extra)
460{
461 strcpy(wrqu->name, "Netwave");
462 return 0;
463}
464
465/*
466 * Wireless Handler : set Network ID
467 */
468static int netwave_set_nwid(struct net_device *dev,
469 struct iw_request_info *info,
470 union iwreq_data *wrqu,
471 char *extra)
472{
473 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800474 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 netwave_private *priv = netdev_priv(dev);
476 u_char __iomem *ramBase = priv->ramBase;
477
478 /* Disable interrupts & save flags */
479 spin_lock_irqsave(&priv->spinlock, flags);
480
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 if(!wrqu->nwid.disabled) {
482 domain = wrqu->nwid.value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
484 (domain >> 8) & 0x01, domain & 0xff);
485 wait_WOC(iobase);
486 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
487 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
488 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
489 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
490 }
491
492 /* ReEnable interrupts & restore flags */
493 spin_unlock_irqrestore(&priv->spinlock, flags);
494
495 return 0;
496}
497
498/*
499 * Wireless Handler : get Network ID
500 */
501static int netwave_get_nwid(struct net_device *dev,
502 struct iw_request_info *info,
503 union iwreq_data *wrqu,
504 char *extra)
505{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 wrqu->nwid.value = domain;
507 wrqu->nwid.disabled = 0;
508 wrqu->nwid.fixed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 return 0;
510}
511
512/*
513 * Wireless Handler : set scramble key
514 */
515static int netwave_set_scramble(struct net_device *dev,
516 struct iw_request_info *info,
517 union iwreq_data *wrqu,
518 char *key)
519{
520 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800521 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 netwave_private *priv = netdev_priv(dev);
523 u_char __iomem *ramBase = priv->ramBase;
524
525 /* Disable interrupts & save flags */
526 spin_lock_irqsave(&priv->spinlock, flags);
527
528 scramble_key = (key[0] << 8) | key[1];
529 wait_WOC(iobase);
530 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
531 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
532 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
533 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
534
535 /* ReEnable interrupts & restore flags */
536 spin_unlock_irqrestore(&priv->spinlock, flags);
537
538 return 0;
539}
540
541/*
542 * Wireless Handler : get scramble key
543 */
544static int netwave_get_scramble(struct net_device *dev,
545 struct iw_request_info *info,
546 union iwreq_data *wrqu,
547 char *key)
548{
549 key[1] = scramble_key & 0xff;
550 key[0] = (scramble_key>>8) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 wrqu->encoding.flags = IW_ENCODE_ENABLED;
552 wrqu->encoding.length = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 return 0;
554}
555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556/*
557 * Wireless Handler : get mode
558 */
559static int netwave_get_mode(struct net_device *dev,
560 struct iw_request_info *info,
561 union iwreq_data *wrqu,
562 char *extra)
563{
564 if(domain & 0x100)
565 wrqu->mode = IW_MODE_INFRA;
566 else
567 wrqu->mode = IW_MODE_ADHOC;
568
569 return 0;
570}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
572/*
573 * Wireless Handler : get range info
574 */
575static int netwave_get_range(struct net_device *dev,
576 struct iw_request_info *info,
577 union iwreq_data *wrqu,
578 char *extra)
579{
580 struct iw_range *range = (struct iw_range *) extra;
581 int ret = 0;
582
583 /* Set the length (very important for backward compatibility) */
584 wrqu->data.length = sizeof(struct iw_range);
585
586 /* Set all the info we don't care or don't know about to zero */
587 memset(range, 0, sizeof(struct iw_range));
588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 /* Set the Wireless Extension versions */
590 range->we_version_compiled = WIRELESS_EXT;
591 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592
593 /* Set information in the range struct */
594 range->throughput = 450 * 1000; /* don't argue on this ! */
595 range->min_nwid = 0x0000;
596 range->max_nwid = 0x01FF;
597
598 range->num_channels = range->num_frequency = 0;
599
600 range->sensitivity = 0x3F;
601 range->max_qual.qual = 255;
602 range->max_qual.level = 255;
603 range->max_qual.noise = 0;
604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 range->num_bitrates = 1;
606 range->bitrate[0] = 1000000; /* 1 Mb/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 range->encoding_size[0] = 2; /* 16 bits scrambling */
609 range->num_encoding_sizes = 1;
610 range->max_encoding_tokens = 1; /* Only one key possible */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 return ret;
613}
614
615/*
616 * Wireless Private Handler : get snapshot
617 */
618static int netwave_get_snap(struct net_device *dev,
619 struct iw_request_info *info,
620 union iwreq_data *wrqu,
621 char *extra)
622{
623 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800624 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 netwave_private *priv = netdev_priv(dev);
626 u_char __iomem *ramBase = priv->ramBase;
627
628 /* Disable interrupts & save flags */
629 spin_lock_irqsave(&priv->spinlock, flags);
630
631 /* Take snapshot of environment */
632 netwave_snapshot( priv, ramBase, iobase);
633 wrqu->data.length = priv->nss.length;
634 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
635
636 priv->lastExec = jiffies;
637
638 /* ReEnable interrupts & restore flags */
639 spin_unlock_irqrestore(&priv->spinlock, flags);
640
641 return(0);
642}
643
644/*
645 * Structures to export the Wireless Handlers
646 * This is the stuff that are treated the wireless extensions (iwconfig)
647 */
648
649static const struct iw_priv_args netwave_private_args[] = {
650/*{ cmd, set_args, get_args, name } */
651 { SIOCGIPSNAP, 0,
652 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
653 "getsitesurvey" },
654};
655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656static const iw_handler netwave_handler[] =
657{
658 NULL, /* SIOCSIWNAME */
659 netwave_get_name, /* SIOCGIWNAME */
660 netwave_set_nwid, /* SIOCSIWNWID */
661 netwave_get_nwid, /* SIOCGIWNWID */
662 NULL, /* SIOCSIWFREQ */
663 NULL, /* SIOCGIWFREQ */
664 NULL, /* SIOCSIWMODE */
665 netwave_get_mode, /* SIOCGIWMODE */
666 NULL, /* SIOCSIWSENS */
667 NULL, /* SIOCGIWSENS */
668 NULL, /* SIOCSIWRANGE */
669 netwave_get_range, /* SIOCGIWRANGE */
670 NULL, /* SIOCSIWPRIV */
671 NULL, /* SIOCGIWPRIV */
672 NULL, /* SIOCSIWSTATS */
673 NULL, /* SIOCGIWSTATS */
674 NULL, /* SIOCSIWSPY */
675 NULL, /* SIOCGIWSPY */
676 NULL, /* -- hole -- */
677 NULL, /* -- hole -- */
678 NULL, /* SIOCSIWAP */
679 NULL, /* SIOCGIWAP */
680 NULL, /* -- hole -- */
681 NULL, /* SIOCGIWAPLIST */
682 NULL, /* -- hole -- */
683 NULL, /* -- hole -- */
684 NULL, /* SIOCSIWESSID */
685 NULL, /* SIOCGIWESSID */
686 NULL, /* SIOCSIWNICKN */
687 NULL, /* SIOCGIWNICKN */
688 NULL, /* -- hole -- */
689 NULL, /* -- hole -- */
690 NULL, /* SIOCSIWRATE */
691 NULL, /* SIOCGIWRATE */
692 NULL, /* SIOCSIWRTS */
693 NULL, /* SIOCGIWRTS */
694 NULL, /* SIOCSIWFRAG */
695 NULL, /* SIOCGIWFRAG */
696 NULL, /* SIOCSIWTXPOW */
697 NULL, /* SIOCGIWTXPOW */
698 NULL, /* SIOCSIWRETRY */
699 NULL, /* SIOCGIWRETRY */
700 netwave_set_scramble, /* SIOCSIWENCODE */
701 netwave_get_scramble, /* SIOCGIWENCODE */
702};
703
704static const iw_handler netwave_private_handler[] =
705{
706 NULL, /* SIOCIWFIRSTPRIV */
707 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
708};
709
710static const struct iw_handler_def netwave_handler_def =
711{
Denis Chengff8ac602007-09-02 18:30:18 +0800712 .num_standard = ARRAY_SIZE(netwave_handler),
713 .num_private = ARRAY_SIZE(netwave_private_handler),
714 .num_private_args = ARRAY_SIZE(netwave_private_args),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 .standard = (iw_handler *) netwave_handler,
716 .private = (iw_handler *) netwave_private_handler,
717 .private_args = (struct iw_priv_args *) netwave_private_args,
Jean Tourrilhes62337dd2005-09-02 11:39:02 -0700718 .get_wireless_stats = netwave_get_wireless_stats,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721/*
722 * Function netwave_pcmcia_config (link)
723 *
724 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
725 * event is received, to configure the PCMCIA socket, and to make the
726 * device available to the system.
727 *
728 */
729
730#define CS_CHECK(fn, ret) \
731do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
732
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200733static int netwave_pcmcia_config(struct pcmcia_device *link) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 struct net_device *dev = link->priv;
735 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 int i, j, last_ret, last_fn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 win_req_t req;
738 memreq_t mem;
739 u_char __iomem *ramBase = NULL;
Joe Perches0795af52007-10-03 17:59:30 -0700740 DECLARE_MAC_BUF(mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
743
744 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 * Try allocating IO ports. This tries a few fixed addresses.
746 * If you want, you can also read the card's config table to
747 * pick addresses -- see the serial driver for an example.
748 */
749 for (i = j = 0x0; j < 0x400; j += 0x20) {
750 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200751 i = pcmcia_request_io(link, &link->io);
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200752 if (i == 0)
753 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 }
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200755 if (i != 0) {
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200756 cs_error(link, RequestIO, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 goto failed;
758 }
759
760 /*
761 * Now allocate an interrupt line. Note that this does not
762 * actually assign a handler to the interrupt.
763 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200764 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765
766 /*
767 * This actually configures the PCMCIA socket -- setting up
768 * the I/O windows and the interrupt mapping.
769 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200770 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
772 /*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200773 * Allocate a 32K memory window. Note that the struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 * structure provides space for one window handle -- if your
775 * device needs several windows, you'll need to keep track of
776 * the handles in your private data structure, dev->priv.
777 */
778 DEBUG(1, "Setting mem speed of %d\n", mem_speed);
779
780 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
781 req.Base = 0; req.Size = 0x8000;
782 req.AccessSpeed = mem_speed;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200783 CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 mem.CardOffset = 0x20000; mem.Page = 0;
785 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
786
787 /* Store base address of the common window frame */
788 ramBase = ioremap(req.Base, 0x8000);
789 priv->ramBase = ramBase;
790
791 dev->irq = link->irq.AssignedIRQ;
792 dev->base_addr = link->io.BasePort1;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200793 SET_NETDEV_DEV(dev, &handle_to_dev(link));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
795 if (register_netdev(dev) != 0) {
796 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
797 goto failed;
798 }
799
800 strcpy(priv->node.dev_name, dev->name);
Dominik Brodowskifd238232006-03-05 10:45:09 +0100801 link->dev_node = &priv->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 /* Reset card before reading physical address */
804 netwave_doreset(dev->base_addr, ramBase);
805
806 /* Read the ethernet address and fill in the Netwave registers. */
807 for (i = 0; i < 6; i++)
808 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
809
Joe Perches8376e7a2007-11-19 17:48:27 -0800810 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
Joe Perches0795af52007-10-03 17:59:30 -0700811 "id %c%c, hw_addr %s\n",
812 dev->name, dev->base_addr, dev->irq,
813 (u_long) ramBase,
814 (int) readb(ramBase+NETWAVE_EREG_NI),
815 (int) readb(ramBase+NETWAVE_EREG_NI+1),
816 print_mac(mac, dev->dev_addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
818 /* get revision words */
819 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
820 get_uint16(ramBase + NETWAVE_EREG_ARW),
821 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200822 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
824cs_failed:
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200825 cs_error(link, last_fn, last_ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826failed:
827 netwave_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200828 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829} /* netwave_pcmcia_config */
830
831/*
832 * Function netwave_release (arg)
833 *
834 * After a card is removed, netwave_release() will unregister the net
835 * device, and release the PCMCIA configuration. If the device is
836 * still open, this will be postponed until it is closed.
837 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200838static void netwave_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100840 struct net_device *dev = link->priv;
841 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100843 DEBUG(0, "netwave_release(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200845 pcmcia_disable_device(link);
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100846 if (link->win)
847 iounmap(priv->ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848}
849
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200850static int netwave_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100851{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100852 struct net_device *dev = link->priv;
853
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100854 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100855 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100856
857 return 0;
858}
859
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200860static int netwave_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100861{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100862 struct net_device *dev = link->priv;
863
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100864 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100865 netwave_reset(dev);
866 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100867 }
868
869 return 0;
870}
871
872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 * Function netwave_doreset (ioBase, ramBase)
875 *
876 * Proper hardware reset of the card.
877 */
Olof Johansson906da802008-02-04 22:27:35 -0800878static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879{
880 /* Reset card */
881 wait_WOC(ioBase);
882 outb(0x80, ioBase + NETWAVE_REG_PMR);
883 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
884 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
885}
886
887/*
888 * Function netwave_reset (dev)
889 *
890 * Reset and restore all of the netwave registers
891 */
892static void netwave_reset(struct net_device *dev) {
893 /* u_char state; */
894 netwave_private *priv = netdev_priv(dev);
895 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800896 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
898 DEBUG(0, "netwave_reset: Done with hardware reset\n");
899
900 priv->timeoutCounter = 0;
901
902 /* Reset card */
903 netwave_doreset(iobase, ramBase);
904 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
905
906 /* Write a NOP to check the card */
907 wait_WOC(iobase);
908 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
909 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
910
911 /* Set receive conf */
912 wait_WOC(iobase);
913 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
914 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
915 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
916
917 /* Set transmit conf */
918 wait_WOC(iobase);
919 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
920 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
921 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
922
923 /* Now set the MU Domain */
924 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
925 wait_WOC(iobase);
926 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
927 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
928 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
929 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
930
931 /* Set scramble key */
932 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
933 wait_WOC(iobase);
934 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
935 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
936 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
937 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
938
939 /* Enable interrupts, bit 4 high to keep unused
940 * source from interrupting us, bit 2 high to
941 * set interrupt enable, 567 to enable TxDN,
942 * RxErr and RxRdy
943 */
944 wait_WOC(iobase);
945 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
946
947 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
948 * waitWOC
949 * skriv 80 til d000:3688
950 * sjekk om det ble 80
951 */
952
953 /* Enable Receiver */
954 wait_WOC(iobase);
955 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
956 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
957
958 /* Set the IENA bit in COR */
959 wait_WOC(iobase);
960 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
961}
962
963/*
964 * Function netwave_hw_xmit (data, len, dev)
965 */
966static int netwave_hw_xmit(unsigned char* data, int len,
967 struct net_device* dev) {
968 unsigned long flags;
969 unsigned int TxFreeList,
970 curBuff,
971 MaxData,
972 DataOffset;
973 int tmpcount;
974
975 netwave_private *priv = netdev_priv(dev);
976 u_char __iomem * ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800977 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
979 /* Disable interrupts & save flags */
980 spin_lock_irqsave(&priv->spinlock, flags);
981
982 /* Check if there are transmit buffers available */
983 wait_WOC(iobase);
984 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
985 /* No buffers available */
986 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
987 dev->name);
988 spin_unlock_irqrestore(&priv->spinlock, flags);
989 return 1;
990 }
991
992 priv->stats.tx_bytes += len;
993
994 DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
995 readb(ramBase + NETWAVE_EREG_SPCQ),
996 readb(ramBase + NETWAVE_EREG_SPU),
997 readb(ramBase + NETWAVE_EREG_LIF),
998 readb(ramBase + NETWAVE_EREG_ISPLQ));
999
1000 /* Now try to insert it into the adapters free memory */
1001 wait_WOC(iobase);
1002 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
1003 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
1004 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
1005
1006 DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
1007 TxFreeList, MaxData, DataOffset);
1008
1009 /* Copy packet to the adapter fragment buffers */
1010 curBuff = TxFreeList;
1011 tmpcount = 0;
1012 while (tmpcount < len) {
1013 int tmplen = len - tmpcount;
1014 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
1015 (tmplen < MaxData) ? tmplen : MaxData);
1016 tmpcount += MaxData;
1017
1018 /* Advance to next buffer */
1019 curBuff = get_uint16(ramBase + curBuff);
1020 }
1021
1022 /* Now issue transmit list */
1023 wait_WOC(iobase);
1024 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1025 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1026 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1027 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1028
1029 spin_unlock_irqrestore(&priv->spinlock, flags);
1030 return 0;
1031}
1032
1033static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1034 /* This flag indicate that the hardware can't perform a transmission.
1035 * Theoritically, NET3 check it before sending a packet to the driver,
1036 * but in fact it never do that and pool continuously.
1037 * As the watchdog will abort too long transmissions, we are quite safe...
1038 */
1039
1040 netif_stop_queue(dev);
1041
1042 {
1043 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1044 unsigned char* buf = skb->data;
1045
1046 if (netwave_hw_xmit( buf, length, dev) == 1) {
1047 /* Some error, let's make them call us another time? */
1048 netif_start_queue(dev);
1049 }
1050 dev->trans_start = jiffies;
1051 }
1052 dev_kfree_skb(skb);
1053
1054 return 0;
1055} /* netwave_start_xmit */
1056
1057/*
David Howells7d12e782006-10-05 14:55:46 +01001058 * Function netwave_interrupt (irq, dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 *
1060 * This function is the interrupt handler for the Netwave card. This
1061 * routine will be called whenever:
1062 * 1. A packet is received.
1063 * 2. A packet has successfully been transferred and the unit is
1064 * ready to transmit another packet.
1065 * 3. A command has completed execution.
1066 */
David Howells7d12e782006-10-05 14:55:46 +01001067static irqreturn_t netwave_interrupt(int irq, void* dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068{
Olof Johansson906da802008-02-04 22:27:35 -08001069 unsigned int iobase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 u_char __iomem *ramBase;
1071 struct net_device *dev = (struct net_device *)dev_id;
1072 struct netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001073 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 int i;
1075
1076 if (!netif_device_present(dev))
1077 return IRQ_NONE;
1078
1079 iobase = dev->base_addr;
1080 ramBase = priv->ramBase;
1081
1082 /* Now find what caused the interrupt, check while interrupts ready */
1083 for (i = 0; i < 10; i++) {
1084 u_char status;
1085
1086 wait_WOC(iobase);
1087 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1088 break; /* None of the interrupt sources asserted (normal exit) */
1089
1090 status = inb(iobase + NETWAVE_REG_ASR);
1091
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001092 if (!pcmcia_dev_present(link)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
1094 "from removed or suspended card!\n", status);
1095 break;
1096 }
1097
1098 /* RxRdy */
1099 if (status & 0x80) {
1100 netwave_rx(dev);
1101 /* wait_WOC(iobase); */
1102 /* RxRdy cannot be reset directly by the host */
1103 }
1104 /* RxErr */
1105 if (status & 0x40) {
1106 u_char rser;
1107
1108 rser = readb(ramBase + NETWAVE_EREG_RSER);
1109
1110 if (rser & 0x04) {
1111 ++priv->stats.rx_dropped;
1112 ++priv->stats.rx_crc_errors;
1113 }
1114 if (rser & 0x02)
1115 ++priv->stats.rx_frame_errors;
1116
1117 /* Clear the RxErr bit in RSER. RSER+4 is the
1118 * write part. Also clear the RxCRC (0x04) and
1119 * RxBig (0x02) bits if present */
1120 wait_WOC(iobase);
1121 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1122
1123 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1124 * WOC must be set first!
1125 */
1126 wait_WOC(iobase);
1127 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1128
1129 /* Remember to count up priv->stats on error packets */
1130 ++priv->stats.rx_errors;
1131 }
1132 /* TxDN */
1133 if (status & 0x20) {
1134 int txStatus;
1135
1136 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
1137 DEBUG(3, "Transmit done. TSER = %x id %x\n",
1138 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1139
1140 if (txStatus & 0x20) {
1141 /* Transmitting was okay, clear bits */
1142 wait_WOC(iobase);
1143 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
1144 ++priv->stats.tx_packets;
1145 }
1146
1147 if (txStatus & 0xd0) {
1148 if (txStatus & 0x80) {
1149 ++priv->stats.collisions; /* Because of /proc/net/dev*/
1150 /* ++priv->stats.tx_aborted_errors; */
1151 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1152 }
1153 if (txStatus & 0x40)
1154 ++priv->stats.tx_carrier_errors;
1155 /* 0x80 TxGU Transmit giveup - nine times and no luck
1156 * 0x40 TxNOAP No access point. Discarded packet.
1157 * 0x10 TxErr Transmit error. Always set when
1158 * TxGU and TxNOAP is set. (Those are the only ones
1159 * to set TxErr).
1160 */
1161 DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
1162 txStatus);
1163
1164 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1165 wait_WOC(iobase);
1166 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
1167 ++priv->stats.tx_errors;
1168 }
1169 DEBUG(3, "New status is TSER %x ASR %x\n",
1170 readb(ramBase + NETWAVE_EREG_TSER),
1171 inb(iobase + NETWAVE_REG_ASR));
1172
1173 netif_wake_queue(dev);
1174 }
1175 /* TxBA, this would trigger on all error packets received */
1176 /* if (status & 0x01) {
1177 DEBUG(4, "Transmit buffers available, %x\n", status);
1178 }
1179 */
1180 }
1181 /* Handled if we looped at least one time - Jean II */
1182 return IRQ_RETVAL(i);
1183} /* netwave_interrupt */
1184
1185/*
1186 * Function netwave_watchdog (a)
1187 *
1188 * Watchdog : when we start a transmission, we set a timer in the
1189 * kernel. If the transmission complete, this timer is disabled. If
1190 * it expire, we reset the card.
1191 *
1192 */
1193static void netwave_watchdog(struct net_device *dev) {
1194
1195 DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
1196 netwave_reset(dev);
1197 dev->trans_start = jiffies;
1198 netif_wake_queue(dev);
1199} /* netwave_watchdog */
1200
1201static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
1202 netwave_private *priv = netdev_priv(dev);
1203
1204 update_stats(dev);
1205
1206 DEBUG(2, "netwave: SPCQ %x SPU %x LIF %x ISPLQ %x MHS %x rxtx %x"
1207 " %x tx %x %x %x %x\n",
1208 readb(priv->ramBase + NETWAVE_EREG_SPCQ),
1209 readb(priv->ramBase + NETWAVE_EREG_SPU),
1210 readb(priv->ramBase + NETWAVE_EREG_LIF),
1211 readb(priv->ramBase + NETWAVE_EREG_ISPLQ),
1212 readb(priv->ramBase + NETWAVE_EREG_MHS),
1213 readb(priv->ramBase + NETWAVE_EREG_EC + 0xe),
1214 readb(priv->ramBase + NETWAVE_EREG_EC + 0xf),
1215 readb(priv->ramBase + NETWAVE_EREG_EC + 0x18),
1216 readb(priv->ramBase + NETWAVE_EREG_EC + 0x19),
1217 readb(priv->ramBase + NETWAVE_EREG_EC + 0x1a),
1218 readb(priv->ramBase + NETWAVE_EREG_EC + 0x1b));
1219
1220 return &priv->stats;
1221}
1222
1223static void update_stats(struct net_device *dev) {
1224 //unsigned long flags;
1225/* netwave_private *priv = netdev_priv(dev); */
1226
1227 //spin_lock_irqsave(&priv->spinlock, flags);
1228
1229/* priv->stats.rx_packets = readb(priv->ramBase + 0x18e);
1230 priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */
1231
1232 //spin_unlock_irqrestore(&priv->spinlock, flags);
1233}
1234
1235static int netwave_rx(struct net_device *dev)
1236{
1237 netwave_private *priv = netdev_priv(dev);
1238 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -08001239 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 u_char rxStatus;
1241 struct sk_buff *skb = NULL;
1242 unsigned int curBuffer,
1243 rcvList;
1244 int rcvLen;
1245 int tmpcount = 0;
1246 int dataCount, dataOffset;
1247 int i;
1248 u_char *ptr;
1249
1250 DEBUG(3, "xinw_rx: Receiving ... \n");
1251
1252 /* Receive max 10 packets for now. */
1253 for (i = 0; i < 10; i++) {
1254 /* Any packets? */
1255 wait_WOC(iobase);
1256 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1257 if ( !( rxStatus & 0x80)) /* No more packets */
1258 break;
1259
1260 /* Check if multicast/broadcast or other */
1261 /* multicast = (rxStatus & 0x20); */
1262
1263 /* The receive list pointer and length of the packet */
1264 wait_WOC(iobase);
1265 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1266 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1267
1268 if (rcvLen < 0) {
1269 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1270 rcvLen);
1271 return 0;
1272 }
1273
1274 skb = dev_alloc_skb(rcvLen+5);
1275 if (skb == NULL) {
1276 DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
1277 "length %d\n", rcvLen);
1278 ++priv->stats.rx_dropped;
1279 /* Tell the adapter to skip the packet */
1280 wait_WOC(iobase);
1281 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1282 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1283 return 0;
1284 }
1285
1286 skb_reserve( skb, 2); /* Align IP on 16 byte */
1287 skb_put( skb, rcvLen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289 /* Copy packet fragments to the skb data area */
1290 ptr = (u_char*) skb->data;
1291 curBuffer = rcvList;
1292 tmpcount = 0;
1293 while ( tmpcount < rcvLen) {
1294 /* Get length and offset of current buffer */
1295 dataCount = get_uint16( ramBase+curBuffer+2);
1296 dataOffset = get_uint16( ramBase+curBuffer+4);
1297
1298 copy_from_pc( ptr + tmpcount,
1299 ramBase+curBuffer+dataOffset, dataCount);
1300
1301 tmpcount += dataCount;
1302
1303 /* Point to next buffer */
1304 curBuffer = get_uint16(ramBase + curBuffer);
1305 }
1306
1307 skb->protocol = eth_type_trans(skb,dev);
1308 /* Queue packet for network layer */
1309 netif_rx(skb);
1310
1311 dev->last_rx = jiffies;
1312 priv->stats.rx_packets++;
1313 priv->stats.rx_bytes += rcvLen;
1314
1315 /* Got the packet, tell the adapter to skip it */
1316 wait_WOC(iobase);
1317 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1318 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1319 DEBUG(3, "Packet reception ok\n");
1320 }
1321 return 0;
1322}
1323
1324static int netwave_open(struct net_device *dev) {
1325 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001326 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327
1328 DEBUG(1, "netwave_open: starting.\n");
1329
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001330 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 return -ENODEV;
1332
1333 link->open++;
1334
1335 netif_start_queue(dev);
1336 netwave_reset(dev);
1337
1338 return 0;
1339}
1340
1341static int netwave_close(struct net_device *dev) {
1342 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001343 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344
1345 DEBUG(1, "netwave_close: finishing.\n");
1346
1347 link->open--;
1348 netif_stop_queue(dev);
1349
1350 return 0;
1351}
1352
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001353static struct pcmcia_device_id netwave_ids[] = {
1354 PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
1355 PCMCIA_DEVICE_NULL,
1356};
1357MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
1358
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359static struct pcmcia_driver netwave_driver = {
1360 .owner = THIS_MODULE,
1361 .drv = {
1362 .name = "netwave_cs",
1363 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001364 .probe = netwave_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001365 .remove = netwave_detach,
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001366 .id_table = netwave_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001367 .suspend = netwave_suspend,
1368 .resume = netwave_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369};
1370
1371static int __init init_netwave_cs(void)
1372{
1373 return pcmcia_register_driver(&netwave_driver);
1374}
1375
1376static void __exit exit_netwave_cs(void)
1377{
1378 pcmcia_unregister_driver(&netwave_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379}
1380
1381module_init(init_netwave_cs);
1382module_exit(exit_netwave_cs);
1383
1384/* Set or clear the multicast filter for this adaptor.
1385 num_addrs == -1 Promiscuous mode, receive all packets
1386 num_addrs == 0 Normal mode, clear multicast list
1387 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1388 best-effort filtering.
1389 */
1390static void set_multicast_list(struct net_device *dev)
1391{
Olof Johansson906da802008-02-04 22:27:35 -08001392 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 netwave_private *priv = netdev_priv(dev);
1394 u_char __iomem * ramBase = priv->ramBase;
1395 u_char rcvMode = 0;
1396
1397#ifdef PCMCIA_DEBUG
1398 if (pc_debug > 2) {
1399 static int old;
1400 if (old != dev->mc_count) {
1401 old = dev->mc_count;
1402 DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
1403 dev->name, dev->mc_count);
1404 }
1405 }
1406#endif
1407
1408 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1409 /* Multicast Mode */
1410 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1411 } else if (dev->flags & IFF_PROMISC) {
1412 /* Promiscous mode */
1413 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1414 } else {
1415 /* Normal mode */
1416 rcvMode = rxConfRxEna + rxConfBcast;
1417 }
1418
1419 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1420 /* Now set receive mode */
1421 wait_WOC(iobase);
1422 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1423 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1424 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1425}
1426MODULE_LICENSE("GPL");