blob: d63c8992f229bf8287f78ed2f790fe93cc5f0421 [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
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000358static const struct net_device_ops netwave_netdev_ops = {
359 .ndo_open = netwave_open,
360 .ndo_stop = netwave_close,
361 .ndo_start_xmit = netwave_start_xmit,
362 .ndo_set_multicast_list = set_multicast_list,
363 .ndo_tx_timeout = netwave_watchdog,
364 .ndo_change_mtu = eth_change_mtu,
365 .ndo_set_mac_address = eth_mac_addr,
366 .ndo_validate_addr = eth_validate_addr,
367};
368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369/*
370 * Function netwave_attach (void)
371 *
372 * Creates an "instance" of the driver, allocating local data
373 * structures for one device. The device is registered with Card
374 * Services.
375 *
376 * The dev_link structure is initialized, but we don't actually
377 * configure the card at this point -- we wait until we receive a
378 * card insertion event.
379 */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200380static int netwave_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 struct net_device *dev;
383 netwave_private *priv;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100384
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 DEBUG(0, "netwave_attach()\n");
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100386
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200387 /* Initialize the struct pcmcia_device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 dev = alloc_etherdev(sizeof(netwave_private));
389 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100390 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200392 priv->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 link->priv = dev;
394
395 /* The io structure describes IO port mapping */
396 link->io.NumPorts1 = 16;
397 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
398 /* link->io.NumPorts2 = 16;
399 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
400 link->io.IOAddrLines = 5;
401
402 /* Interrupt setup */
Alan Cox47cbb112008-09-23 13:53:09 +0100403 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
405 link->irq.Handler = &netwave_interrupt;
406
407 /* General socket configuration */
408 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 link->conf.IntType = INT_MEMORY_AND_IO;
410 link->conf.ConfigIndex = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
412 /* Netwave private struct init. link/dev/node already taken care of,
413 * other stuff zero'd - Jean II */
414 spin_lock_init(&priv->spinlock);
415
416 /* Netwave specific entries in the device structure */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000417 dev->netdev_ops = &netwave_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 /* wireless extensions */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000419 dev->wireless_handlers = &netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 dev->watchdog_timeo = TX_TIMEOUT;
422
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 link->irq.Instance = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200425 return netwave_pcmcia_config( link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426} /* netwave_attach */
427
428/*
429 * Function netwave_detach (link)
430 *
431 * This deletes a driver "instance". The device is de-registered
432 * with Card Services. If it has been released, all local data
433 * structures are freed. Otherwise, the structures will be freed
434 * when the device is released.
435 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200436static void netwave_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
Dominik Brodowskib4635812005-11-14 21:25:35 +0100438 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
Dominik Brodowskib4635812005-11-14 21:25:35 +0100440 DEBUG(0, "netwave_detach(0x%p)\n", link);
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100441
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100442 netwave_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
Dominik Brodowskifd238232006-03-05 10:45:09 +0100444 if (link->dev_node)
Dominik Brodowskib4635812005-11-14 21:25:35 +0100445 unregister_netdev(dev);
446
447 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448} /* netwave_detach */
449
450/*
451 * Wireless Handler : get protocol name
452 */
453static int netwave_get_name(struct net_device *dev,
454 struct iw_request_info *info,
455 union iwreq_data *wrqu,
456 char *extra)
457{
458 strcpy(wrqu->name, "Netwave");
459 return 0;
460}
461
462/*
463 * Wireless Handler : set Network ID
464 */
465static int netwave_set_nwid(struct net_device *dev,
466 struct iw_request_info *info,
467 union iwreq_data *wrqu,
468 char *extra)
469{
470 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800471 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 netwave_private *priv = netdev_priv(dev);
473 u_char __iomem *ramBase = priv->ramBase;
474
475 /* Disable interrupts & save flags */
476 spin_lock_irqsave(&priv->spinlock, flags);
477
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 if(!wrqu->nwid.disabled) {
479 domain = wrqu->nwid.value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
481 (domain >> 8) & 0x01, domain & 0xff);
482 wait_WOC(iobase);
483 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
484 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
485 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
486 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
487 }
488
489 /* ReEnable interrupts & restore flags */
490 spin_unlock_irqrestore(&priv->spinlock, flags);
491
492 return 0;
493}
494
495/*
496 * Wireless Handler : get Network ID
497 */
498static int netwave_get_nwid(struct net_device *dev,
499 struct iw_request_info *info,
500 union iwreq_data *wrqu,
501 char *extra)
502{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 wrqu->nwid.value = domain;
504 wrqu->nwid.disabled = 0;
505 wrqu->nwid.fixed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 return 0;
507}
508
509/*
510 * Wireless Handler : set scramble key
511 */
512static int netwave_set_scramble(struct net_device *dev,
513 struct iw_request_info *info,
514 union iwreq_data *wrqu,
515 char *key)
516{
517 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800518 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 netwave_private *priv = netdev_priv(dev);
520 u_char __iomem *ramBase = priv->ramBase;
521
522 /* Disable interrupts & save flags */
523 spin_lock_irqsave(&priv->spinlock, flags);
524
525 scramble_key = (key[0] << 8) | key[1];
526 wait_WOC(iobase);
527 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
528 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
529 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
530 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
531
532 /* ReEnable interrupts & restore flags */
533 spin_unlock_irqrestore(&priv->spinlock, flags);
534
535 return 0;
536}
537
538/*
539 * Wireless Handler : get scramble key
540 */
541static int netwave_get_scramble(struct net_device *dev,
542 struct iw_request_info *info,
543 union iwreq_data *wrqu,
544 char *key)
545{
546 key[1] = scramble_key & 0xff;
547 key[0] = (scramble_key>>8) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 wrqu->encoding.flags = IW_ENCODE_ENABLED;
549 wrqu->encoding.length = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 return 0;
551}
552
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553/*
554 * Wireless Handler : get mode
555 */
556static int netwave_get_mode(struct net_device *dev,
557 struct iw_request_info *info,
558 union iwreq_data *wrqu,
559 char *extra)
560{
561 if(domain & 0x100)
562 wrqu->mode = IW_MODE_INFRA;
563 else
564 wrqu->mode = IW_MODE_ADHOC;
565
566 return 0;
567}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
569/*
570 * Wireless Handler : get range info
571 */
572static int netwave_get_range(struct net_device *dev,
573 struct iw_request_info *info,
574 union iwreq_data *wrqu,
575 char *extra)
576{
577 struct iw_range *range = (struct iw_range *) extra;
578 int ret = 0;
579
580 /* Set the length (very important for backward compatibility) */
581 wrqu->data.length = sizeof(struct iw_range);
582
583 /* Set all the info we don't care or don't know about to zero */
584 memset(range, 0, sizeof(struct iw_range));
585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 /* Set the Wireless Extension versions */
587 range->we_version_compiled = WIRELESS_EXT;
588 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590 /* Set information in the range struct */
591 range->throughput = 450 * 1000; /* don't argue on this ! */
592 range->min_nwid = 0x0000;
593 range->max_nwid = 0x01FF;
594
595 range->num_channels = range->num_frequency = 0;
596
597 range->sensitivity = 0x3F;
598 range->max_qual.qual = 255;
599 range->max_qual.level = 255;
600 range->max_qual.noise = 0;
601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 range->num_bitrates = 1;
603 range->bitrate[0] = 1000000; /* 1 Mb/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 range->encoding_size[0] = 2; /* 16 bits scrambling */
606 range->num_encoding_sizes = 1;
607 range->max_encoding_tokens = 1; /* Only one key possible */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
609 return ret;
610}
611
612/*
613 * Wireless Private Handler : get snapshot
614 */
615static int netwave_get_snap(struct net_device *dev,
616 struct iw_request_info *info,
617 union iwreq_data *wrqu,
618 char *extra)
619{
620 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800621 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 netwave_private *priv = netdev_priv(dev);
623 u_char __iomem *ramBase = priv->ramBase;
624
625 /* Disable interrupts & save flags */
626 spin_lock_irqsave(&priv->spinlock, flags);
627
628 /* Take snapshot of environment */
629 netwave_snapshot( priv, ramBase, iobase);
630 wrqu->data.length = priv->nss.length;
631 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
632
633 priv->lastExec = jiffies;
634
635 /* ReEnable interrupts & restore flags */
636 spin_unlock_irqrestore(&priv->spinlock, flags);
637
638 return(0);
639}
640
641/*
642 * Structures to export the Wireless Handlers
643 * This is the stuff that are treated the wireless extensions (iwconfig)
644 */
645
646static const struct iw_priv_args netwave_private_args[] = {
647/*{ cmd, set_args, get_args, name } */
648 { SIOCGIPSNAP, 0,
649 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
650 "getsitesurvey" },
651};
652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653static const iw_handler netwave_handler[] =
654{
655 NULL, /* SIOCSIWNAME */
656 netwave_get_name, /* SIOCGIWNAME */
657 netwave_set_nwid, /* SIOCSIWNWID */
658 netwave_get_nwid, /* SIOCGIWNWID */
659 NULL, /* SIOCSIWFREQ */
660 NULL, /* SIOCGIWFREQ */
661 NULL, /* SIOCSIWMODE */
662 netwave_get_mode, /* SIOCGIWMODE */
663 NULL, /* SIOCSIWSENS */
664 NULL, /* SIOCGIWSENS */
665 NULL, /* SIOCSIWRANGE */
666 netwave_get_range, /* SIOCGIWRANGE */
667 NULL, /* SIOCSIWPRIV */
668 NULL, /* SIOCGIWPRIV */
669 NULL, /* SIOCSIWSTATS */
670 NULL, /* SIOCGIWSTATS */
671 NULL, /* SIOCSIWSPY */
672 NULL, /* SIOCGIWSPY */
673 NULL, /* -- hole -- */
674 NULL, /* -- hole -- */
675 NULL, /* SIOCSIWAP */
676 NULL, /* SIOCGIWAP */
677 NULL, /* -- hole -- */
678 NULL, /* SIOCGIWAPLIST */
679 NULL, /* -- hole -- */
680 NULL, /* -- hole -- */
681 NULL, /* SIOCSIWESSID */
682 NULL, /* SIOCGIWESSID */
683 NULL, /* SIOCSIWNICKN */
684 NULL, /* SIOCGIWNICKN */
685 NULL, /* -- hole -- */
686 NULL, /* -- hole -- */
687 NULL, /* SIOCSIWRATE */
688 NULL, /* SIOCGIWRATE */
689 NULL, /* SIOCSIWRTS */
690 NULL, /* SIOCGIWRTS */
691 NULL, /* SIOCSIWFRAG */
692 NULL, /* SIOCGIWFRAG */
693 NULL, /* SIOCSIWTXPOW */
694 NULL, /* SIOCGIWTXPOW */
695 NULL, /* SIOCSIWRETRY */
696 NULL, /* SIOCGIWRETRY */
697 netwave_set_scramble, /* SIOCSIWENCODE */
698 netwave_get_scramble, /* SIOCGIWENCODE */
699};
700
701static const iw_handler netwave_private_handler[] =
702{
703 NULL, /* SIOCIWFIRSTPRIV */
704 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
705};
706
707static const struct iw_handler_def netwave_handler_def =
708{
Denis Chengff8ac602007-09-02 18:30:18 +0800709 .num_standard = ARRAY_SIZE(netwave_handler),
710 .num_private = ARRAY_SIZE(netwave_private_handler),
711 .num_private_args = ARRAY_SIZE(netwave_private_args),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 .standard = (iw_handler *) netwave_handler,
713 .private = (iw_handler *) netwave_private_handler,
714 .private_args = (struct iw_priv_args *) netwave_private_args,
Jean Tourrilhes62337dd2005-09-02 11:39:02 -0700715 .get_wireless_stats = netwave_get_wireless_stats,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717
718/*
719 * Function netwave_pcmcia_config (link)
720 *
721 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
722 * event is received, to configure the PCMCIA socket, and to make the
723 * device available to the system.
724 *
725 */
726
727#define CS_CHECK(fn, ret) \
728do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
729
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200730static int netwave_pcmcia_config(struct pcmcia_device *link) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 struct net_device *dev = link->priv;
732 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 int i, j, last_ret, last_fn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 win_req_t req;
735 memreq_t mem;
736 u_char __iomem *ramBase = NULL;
737
738 DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
739
740 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 * Try allocating IO ports. This tries a few fixed addresses.
742 * If you want, you can also read the card's config table to
743 * pick addresses -- see the serial driver for an example.
744 */
745 for (i = j = 0x0; j < 0x400; j += 0x20) {
746 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200747 i = pcmcia_request_io(link, &link->io);
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200748 if (i == 0)
749 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 }
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200751 if (i != 0) {
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200752 cs_error(link, RequestIO, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 goto failed;
754 }
755
756 /*
757 * Now allocate an interrupt line. Note that this does not
758 * actually assign a handler to the interrupt.
759 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200760 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761
762 /*
763 * This actually configures the PCMCIA socket -- setting up
764 * the I/O windows and the interrupt mapping.
765 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200766 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767
768 /*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200769 * Allocate a 32K memory window. Note that the struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 * structure provides space for one window handle -- if your
771 * device needs several windows, you'll need to keep track of
772 * the handles in your private data structure, dev->priv.
773 */
774 DEBUG(1, "Setting mem speed of %d\n", mem_speed);
775
776 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
777 req.Base = 0; req.Size = 0x8000;
778 req.AccessSpeed = mem_speed;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200779 CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 mem.CardOffset = 0x20000; mem.Page = 0;
781 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
782
783 /* Store base address of the common window frame */
784 ramBase = ioremap(req.Base, 0x8000);
785 priv->ramBase = ramBase;
786
787 dev->irq = link->irq.AssignedIRQ;
788 dev->base_addr = link->io.BasePort1;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200789 SET_NETDEV_DEV(dev, &handle_to_dev(link));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
791 if (register_netdev(dev) != 0) {
792 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
793 goto failed;
794 }
795
796 strcpy(priv->node.dev_name, dev->name);
Dominik Brodowskifd238232006-03-05 10:45:09 +0100797 link->dev_node = &priv->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
799 /* Reset card before reading physical address */
800 netwave_doreset(dev->base_addr, ramBase);
801
802 /* Read the ethernet address and fill in the Netwave registers. */
803 for (i = 0; i < 6; i++)
804 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
805
Joe Perches8376e7a2007-11-19 17:48:27 -0800806 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
Johannes Berge1749612008-10-27 15:59:26 -0700807 "id %c%c, hw_addr %pM\n",
Joe Perches0795af52007-10-03 17:59:30 -0700808 dev->name, dev->base_addr, dev->irq,
809 (u_long) ramBase,
810 (int) readb(ramBase+NETWAVE_EREG_NI),
811 (int) readb(ramBase+NETWAVE_EREG_NI+1),
Johannes Berge1749612008-10-27 15:59:26 -0700812 dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 /* get revision words */
815 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
816 get_uint16(ramBase + NETWAVE_EREG_ARW),
817 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200818 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
820cs_failed:
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200821 cs_error(link, last_fn, last_ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822failed:
823 netwave_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200824 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825} /* netwave_pcmcia_config */
826
827/*
828 * Function netwave_release (arg)
829 *
830 * After a card is removed, netwave_release() will unregister the net
831 * device, and release the PCMCIA configuration. If the device is
832 * still open, this will be postponed until it is closed.
833 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200834static void netwave_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100836 struct net_device *dev = link->priv;
837 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100839 DEBUG(0, "netwave_release(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200841 pcmcia_disable_device(link);
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100842 if (link->win)
843 iounmap(priv->ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844}
845
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200846static int netwave_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100847{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100848 struct net_device *dev = link->priv;
849
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100850 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100851 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100852
853 return 0;
854}
855
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200856static int netwave_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100857{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100858 struct net_device *dev = link->priv;
859
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100860 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100861 netwave_reset(dev);
862 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100863 }
864
865 return 0;
866}
867
868
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 * Function netwave_doreset (ioBase, ramBase)
871 *
872 * Proper hardware reset of the card.
873 */
Olof Johansson906da802008-02-04 22:27:35 -0800874static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875{
876 /* Reset card */
877 wait_WOC(ioBase);
878 outb(0x80, ioBase + NETWAVE_REG_PMR);
879 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
880 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
881}
882
883/*
884 * Function netwave_reset (dev)
885 *
886 * Reset and restore all of the netwave registers
887 */
888static void netwave_reset(struct net_device *dev) {
889 /* u_char state; */
890 netwave_private *priv = netdev_priv(dev);
891 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800892 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
894 DEBUG(0, "netwave_reset: Done with hardware reset\n");
895
896 priv->timeoutCounter = 0;
897
898 /* Reset card */
899 netwave_doreset(iobase, ramBase);
900 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
901
902 /* Write a NOP to check the card */
903 wait_WOC(iobase);
904 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
905 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
906
907 /* Set receive conf */
908 wait_WOC(iobase);
909 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
910 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
911 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
912
913 /* Set transmit conf */
914 wait_WOC(iobase);
915 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
916 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
917 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
918
919 /* Now set the MU Domain */
920 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
921 wait_WOC(iobase);
922 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
923 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
924 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
925 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
926
927 /* Set scramble key */
928 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
929 wait_WOC(iobase);
930 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
931 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
932 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
933 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
934
935 /* Enable interrupts, bit 4 high to keep unused
936 * source from interrupting us, bit 2 high to
937 * set interrupt enable, 567 to enable TxDN,
938 * RxErr and RxRdy
939 */
940 wait_WOC(iobase);
941 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
942
943 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
944 * waitWOC
945 * skriv 80 til d000:3688
946 * sjekk om det ble 80
947 */
948
949 /* Enable Receiver */
950 wait_WOC(iobase);
951 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
952 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
953
954 /* Set the IENA bit in COR */
955 wait_WOC(iobase);
956 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
957}
958
959/*
960 * Function netwave_hw_xmit (data, len, dev)
961 */
962static int netwave_hw_xmit(unsigned char* data, int len,
963 struct net_device* dev) {
964 unsigned long flags;
965 unsigned int TxFreeList,
966 curBuff,
967 MaxData,
968 DataOffset;
969 int tmpcount;
970
971 netwave_private *priv = netdev_priv(dev);
972 u_char __iomem * ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800973 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
975 /* Disable interrupts & save flags */
976 spin_lock_irqsave(&priv->spinlock, flags);
977
978 /* Check if there are transmit buffers available */
979 wait_WOC(iobase);
980 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
981 /* No buffers available */
982 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
983 dev->name);
984 spin_unlock_irqrestore(&priv->spinlock, flags);
985 return 1;
986 }
987
Stephen Hemmingerf56ef162009-03-20 19:36:21 +0000988 dev->stats.tx_bytes += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989
990 DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
991 readb(ramBase + NETWAVE_EREG_SPCQ),
992 readb(ramBase + NETWAVE_EREG_SPU),
993 readb(ramBase + NETWAVE_EREG_LIF),
994 readb(ramBase + NETWAVE_EREG_ISPLQ));
995
996 /* Now try to insert it into the adapters free memory */
997 wait_WOC(iobase);
998 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
999 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
1000 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
1001
1002 DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
1003 TxFreeList, MaxData, DataOffset);
1004
1005 /* Copy packet to the adapter fragment buffers */
1006 curBuff = TxFreeList;
1007 tmpcount = 0;
1008 while (tmpcount < len) {
1009 int tmplen = len - tmpcount;
1010 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
1011 (tmplen < MaxData) ? tmplen : MaxData);
1012 tmpcount += MaxData;
1013
1014 /* Advance to next buffer */
1015 curBuff = get_uint16(ramBase + curBuff);
1016 }
1017
1018 /* Now issue transmit list */
1019 wait_WOC(iobase);
1020 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1021 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1022 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1023 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1024
1025 spin_unlock_irqrestore(&priv->spinlock, flags);
1026 return 0;
1027}
1028
1029static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1030 /* This flag indicate that the hardware can't perform a transmission.
1031 * Theoritically, NET3 check it before sending a packet to the driver,
1032 * but in fact it never do that and pool continuously.
1033 * As the watchdog will abort too long transmissions, we are quite safe...
1034 */
1035
1036 netif_stop_queue(dev);
1037
1038 {
1039 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1040 unsigned char* buf = skb->data;
1041
1042 if (netwave_hw_xmit( buf, length, dev) == 1) {
1043 /* Some error, let's make them call us another time? */
1044 netif_start_queue(dev);
1045 }
1046 dev->trans_start = jiffies;
1047 }
1048 dev_kfree_skb(skb);
1049
1050 return 0;
1051} /* netwave_start_xmit */
1052
1053/*
David Howells7d12e782006-10-05 14:55:46 +01001054 * Function netwave_interrupt (irq, dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 *
1056 * This function is the interrupt handler for the Netwave card. This
1057 * routine will be called whenever:
1058 * 1. A packet is received.
1059 * 2. A packet has successfully been transferred and the unit is
1060 * ready to transmit another packet.
1061 * 3. A command has completed execution.
1062 */
David Howells7d12e782006-10-05 14:55:46 +01001063static irqreturn_t netwave_interrupt(int irq, void* dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064{
Olof Johansson906da802008-02-04 22:27:35 -08001065 unsigned int iobase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 u_char __iomem *ramBase;
1067 struct net_device *dev = (struct net_device *)dev_id;
1068 struct netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001069 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 int i;
1071
1072 if (!netif_device_present(dev))
1073 return IRQ_NONE;
1074
1075 iobase = dev->base_addr;
1076 ramBase = priv->ramBase;
1077
1078 /* Now find what caused the interrupt, check while interrupts ready */
1079 for (i = 0; i < 10; i++) {
1080 u_char status;
1081
1082 wait_WOC(iobase);
1083 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1084 break; /* None of the interrupt sources asserted (normal exit) */
1085
1086 status = inb(iobase + NETWAVE_REG_ASR);
1087
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001088 if (!pcmcia_dev_present(link)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
1090 "from removed or suspended card!\n", status);
1091 break;
1092 }
1093
1094 /* RxRdy */
1095 if (status & 0x80) {
1096 netwave_rx(dev);
1097 /* wait_WOC(iobase); */
1098 /* RxRdy cannot be reset directly by the host */
1099 }
1100 /* RxErr */
1101 if (status & 0x40) {
1102 u_char rser;
1103
1104 rser = readb(ramBase + NETWAVE_EREG_RSER);
1105
1106 if (rser & 0x04) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001107 ++dev->stats.rx_dropped;
1108 ++dev->stats.rx_crc_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 }
1110 if (rser & 0x02)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001111 ++dev->stats.rx_frame_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
1113 /* Clear the RxErr bit in RSER. RSER+4 is the
1114 * write part. Also clear the RxCRC (0x04) and
1115 * RxBig (0x02) bits if present */
1116 wait_WOC(iobase);
1117 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1118
1119 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1120 * WOC must be set first!
1121 */
1122 wait_WOC(iobase);
1123 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1124
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001125 /* Remember to count up dev->stats on error packets */
1126 ++dev->stats.rx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 }
1128 /* TxDN */
1129 if (status & 0x20) {
1130 int txStatus;
1131
1132 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
1133 DEBUG(3, "Transmit done. TSER = %x id %x\n",
1134 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1135
1136 if (txStatus & 0x20) {
1137 /* Transmitting was okay, clear bits */
1138 wait_WOC(iobase);
1139 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001140 ++dev->stats.tx_packets;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 }
1142
1143 if (txStatus & 0xd0) {
1144 if (txStatus & 0x80) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001145 ++dev->stats.collisions; /* Because of /proc/net/dev*/
1146 /* ++dev->stats.tx_aborted_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1148 }
1149 if (txStatus & 0x40)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001150 ++dev->stats.tx_carrier_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 /* 0x80 TxGU Transmit giveup - nine times and no luck
1152 * 0x40 TxNOAP No access point. Discarded packet.
1153 * 0x10 TxErr Transmit error. Always set when
1154 * TxGU and TxNOAP is set. (Those are the only ones
1155 * to set TxErr).
1156 */
1157 DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
1158 txStatus);
1159
1160 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1161 wait_WOC(iobase);
1162 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001163 ++dev->stats.tx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 }
1165 DEBUG(3, "New status is TSER %x ASR %x\n",
1166 readb(ramBase + NETWAVE_EREG_TSER),
1167 inb(iobase + NETWAVE_REG_ASR));
1168
1169 netif_wake_queue(dev);
1170 }
1171 /* TxBA, this would trigger on all error packets received */
1172 /* if (status & 0x01) {
1173 DEBUG(4, "Transmit buffers available, %x\n", status);
1174 }
1175 */
1176 }
1177 /* Handled if we looped at least one time - Jean II */
1178 return IRQ_RETVAL(i);
1179} /* netwave_interrupt */
1180
1181/*
1182 * Function netwave_watchdog (a)
1183 *
1184 * Watchdog : when we start a transmission, we set a timer in the
1185 * kernel. If the transmission complete, this timer is disabled. If
1186 * it expire, we reset the card.
1187 *
1188 */
1189static void netwave_watchdog(struct net_device *dev) {
1190
1191 DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
1192 netwave_reset(dev);
1193 dev->trans_start = jiffies;
1194 netif_wake_queue(dev);
1195} /* netwave_watchdog */
1196
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197static int netwave_rx(struct net_device *dev)
1198{
1199 netwave_private *priv = netdev_priv(dev);
1200 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -08001201 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 u_char rxStatus;
1203 struct sk_buff *skb = NULL;
1204 unsigned int curBuffer,
1205 rcvList;
1206 int rcvLen;
1207 int tmpcount = 0;
1208 int dataCount, dataOffset;
1209 int i;
1210 u_char *ptr;
1211
1212 DEBUG(3, "xinw_rx: Receiving ... \n");
1213
1214 /* Receive max 10 packets for now. */
1215 for (i = 0; i < 10; i++) {
1216 /* Any packets? */
1217 wait_WOC(iobase);
1218 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1219 if ( !( rxStatus & 0x80)) /* No more packets */
1220 break;
1221
1222 /* Check if multicast/broadcast or other */
1223 /* multicast = (rxStatus & 0x20); */
1224
1225 /* The receive list pointer and length of the packet */
1226 wait_WOC(iobase);
1227 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1228 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1229
1230 if (rcvLen < 0) {
1231 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1232 rcvLen);
1233 return 0;
1234 }
1235
1236 skb = dev_alloc_skb(rcvLen+5);
1237 if (skb == NULL) {
1238 DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
1239 "length %d\n", rcvLen);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001240 ++dev->stats.rx_dropped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 /* Tell the adapter to skip the packet */
1242 wait_WOC(iobase);
1243 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1244 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1245 return 0;
1246 }
1247
1248 skb_reserve( skb, 2); /* Align IP on 16 byte */
1249 skb_put( skb, rcvLen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250
1251 /* Copy packet fragments to the skb data area */
1252 ptr = (u_char*) skb->data;
1253 curBuffer = rcvList;
1254 tmpcount = 0;
1255 while ( tmpcount < rcvLen) {
1256 /* Get length and offset of current buffer */
1257 dataCount = get_uint16( ramBase+curBuffer+2);
1258 dataOffset = get_uint16( ramBase+curBuffer+4);
1259
1260 copy_from_pc( ptr + tmpcount,
1261 ramBase+curBuffer+dataOffset, dataCount);
1262
1263 tmpcount += dataCount;
1264
1265 /* Point to next buffer */
1266 curBuffer = get_uint16(ramBase + curBuffer);
1267 }
1268
1269 skb->protocol = eth_type_trans(skb,dev);
1270 /* Queue packet for network layer */
1271 netif_rx(skb);
1272
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001273 dev->stats.rx_packets++;
1274 dev->stats.rx_bytes += rcvLen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275
1276 /* Got the packet, tell the adapter to skip it */
1277 wait_WOC(iobase);
1278 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1279 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1280 DEBUG(3, "Packet reception ok\n");
1281 }
1282 return 0;
1283}
1284
1285static int netwave_open(struct net_device *dev) {
1286 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001287 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289 DEBUG(1, "netwave_open: starting.\n");
1290
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001291 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 return -ENODEV;
1293
1294 link->open++;
1295
1296 netif_start_queue(dev);
1297 netwave_reset(dev);
1298
1299 return 0;
1300}
1301
1302static int netwave_close(struct net_device *dev) {
1303 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001304 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
1306 DEBUG(1, "netwave_close: finishing.\n");
1307
1308 link->open--;
1309 netif_stop_queue(dev);
1310
1311 return 0;
1312}
1313
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001314static struct pcmcia_device_id netwave_ids[] = {
1315 PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
1316 PCMCIA_DEVICE_NULL,
1317};
1318MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
1319
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320static struct pcmcia_driver netwave_driver = {
1321 .owner = THIS_MODULE,
1322 .drv = {
1323 .name = "netwave_cs",
1324 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001325 .probe = netwave_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001326 .remove = netwave_detach,
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001327 .id_table = netwave_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001328 .suspend = netwave_suspend,
1329 .resume = netwave_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330};
1331
1332static int __init init_netwave_cs(void)
1333{
1334 return pcmcia_register_driver(&netwave_driver);
1335}
1336
1337static void __exit exit_netwave_cs(void)
1338{
1339 pcmcia_unregister_driver(&netwave_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340}
1341
1342module_init(init_netwave_cs);
1343module_exit(exit_netwave_cs);
1344
1345/* Set or clear the multicast filter for this adaptor.
1346 num_addrs == -1 Promiscuous mode, receive all packets
1347 num_addrs == 0 Normal mode, clear multicast list
1348 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1349 best-effort filtering.
1350 */
1351static void set_multicast_list(struct net_device *dev)
1352{
Olof Johansson906da802008-02-04 22:27:35 -08001353 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 netwave_private *priv = netdev_priv(dev);
1355 u_char __iomem * ramBase = priv->ramBase;
1356 u_char rcvMode = 0;
1357
1358#ifdef PCMCIA_DEBUG
1359 if (pc_debug > 2) {
1360 static int old;
1361 if (old != dev->mc_count) {
1362 old = dev->mc_count;
1363 DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
1364 dev->name, dev->mc_count);
1365 }
1366 }
1367#endif
1368
1369 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1370 /* Multicast Mode */
1371 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1372 } else if (dev->flags & IFF_PROMISC) {
1373 /* Promiscous mode */
1374 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1375 } else {
1376 /* Normal mode */
1377 rcvMode = rxConfRxEna + rxConfBcast;
1378 }
1379
1380 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1381 /* Now set receive mode */
1382 wait_WOC(iobase);
1383 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1384 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1385 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1386}
1387MODULE_LICENSE("GPL");