blob: 9498b46c99a48d1355eedd18b8044f3402432156 [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 */
Stephen Hemmingerd0cf9c02009-08-31 19:50:57 +0000206static netdev_tx_t netwave_start_xmit( struct sk_buff *skb,
207 struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208static int netwave_rx( struct net_device *dev);
209
210/* Interrupt routines */
David Howells7d12e782006-10-05 14:55:46 +0100211static irqreturn_t netwave_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212static void netwave_watchdog(struct net_device *);
213
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214/* Wireless extensions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217static void set_multicast_list(struct net_device *dev);
218
219/*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200220 A struct pcmcia_device structure has fields for most things that are needed
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 to keep track of a socket, but there will usually be some device
222 specific information that also needs to be kept track of. The
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200223 'priv' pointer in a struct pcmcia_device structure can be used to point to
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 a device-specific private data structure, like this.
225
226 A driver needs to provide a dev_node_t structure for each device
227 on a card. In some cases, there is only one device per card (for
228 example, ethernet cards, modems). In other cases, there may be
229 many actual or logical devices (SCSI adapters, memory cards with
230 multiple partitions). The dev_node_t structures need to be kept
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200231 in a linked list starting at the 'dev' field of a struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 structure. We allocate them in the card's private data structure,
233 because they generally can't be allocated dynamically.
234*/
235
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236static const struct iw_handler_def netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
238#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
239
240#define MAX_ESA 10
241
242typedef struct net_addr {
243 u_char addr48[6];
244} net_addr;
245
246struct site_survey {
247 u_short length;
248 u_char struct_revision;
249 u_char roaming_state;
250
251 u_char sp_existsFlag;
252 u_char sp_link_quality;
253 u_char sp_max_link_quality;
254 u_char linkQualityGoodFairBoundary;
255 u_char linkQualityFairPoorBoundary;
256 u_char sp_utilization;
257 u_char sp_goodness;
258 u_char sp_hotheadcount;
259 u_char roaming_condition;
260
261 net_addr sp;
262 u_char numAPs;
263 net_addr nearByAccessPoints[MAX_ESA];
264};
265
266typedef struct netwave_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100267 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
269 dev_node_t node;
270 u_char __iomem *ramBase;
271 int timeoutCounter;
272 int lastExec;
273 struct timer_list watchdog; /* To avoid blocking state */
274 struct site_survey nss;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 struct iw_statistics iw_stats; /* Wireless stats */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276} netwave_private;
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278/*
279 * The Netwave card is little-endian, so won't work for big endian
280 * systems.
281 */
282static inline unsigned short get_uint16(u_char __iomem *staddr)
283{
284 return readw(staddr); /* Return only 16 bits */
285}
286
287static inline short get_int16(u_char __iomem * staddr)
288{
289 return readw(staddr);
290}
291
292/*
293 * Wait until the WOC (Write Operation Complete) bit in the
294 * ASR (Adapter Status Register) is asserted.
295 * This should have aborted if it takes too long time.
296 */
297static inline void wait_WOC(unsigned int iobase)
298{
299 /* Spin lock */
300 while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
301}
302
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
Olof Johansson906da802008-02-04 22:27:35 -0800304 unsigned int iobase) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 u_short resultBuffer;
306
307 /* if time since last snapshot is > 1 sec. (100 jiffies?) then take
308 * new snapshot, else return cached data. This is the recommended rate.
309 */
310 if ( jiffies - priv->lastExec > 100) {
311 /* Take site survey snapshot */
312 /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies -
313 priv->lastExec); */
314 wait_WOC(iobase);
315 writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0);
316 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
317 wait_WOC(iobase);
318
319 /* Get result and copy to cach */
320 resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP);
321 copy_from_pc( &priv->nss, ramBase+resultBuffer,
322 sizeof(struct site_survey));
323 }
324}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326/*
327 * Function netwave_get_wireless_stats (dev)
328 *
329 * Wireless extensions statistics
330 *
331 */
332static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
333{
334 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800335 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 netwave_private *priv = netdev_priv(dev);
337 u_char __iomem *ramBase = priv->ramBase;
338 struct iw_statistics* wstats;
339
340 wstats = &priv->iw_stats;
341
342 spin_lock_irqsave(&priv->spinlock, flags);
343
344 netwave_snapshot( priv, ramBase, iobase);
345
346 wstats->status = priv->nss.roaming_state;
347 wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ);
348 wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ);
349 wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f;
350 wstats->discard.nwid = 0L;
351 wstats->discard.code = 0L;
352 wstats->discard.misc = 0L;
353
354 spin_unlock_irqrestore(&priv->spinlock, flags);
355
356 return &priv->iw_stats;
357}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000359static const struct net_device_ops netwave_netdev_ops = {
360 .ndo_open = netwave_open,
361 .ndo_stop = netwave_close,
362 .ndo_start_xmit = netwave_start_xmit,
363 .ndo_set_multicast_list = set_multicast_list,
364 .ndo_tx_timeout = netwave_watchdog,
365 .ndo_change_mtu = eth_change_mtu,
366 .ndo_set_mac_address = eth_mac_addr,
367 .ndo_validate_addr = eth_validate_addr,
368};
369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370/*
371 * Function netwave_attach (void)
372 *
373 * Creates an "instance" of the driver, allocating local data
374 * structures for one device. The device is registered with Card
375 * Services.
376 *
377 * The dev_link structure is initialized, but we don't actually
378 * configure the card at this point -- we wait until we receive a
379 * card insertion event.
380 */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200381static int netwave_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 struct net_device *dev;
384 netwave_private *priv;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 DEBUG(0, "netwave_attach()\n");
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100387
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200388 /* Initialize the struct pcmcia_device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 dev = alloc_etherdev(sizeof(netwave_private));
390 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100391 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200393 priv->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 link->priv = dev;
395
396 /* The io structure describes IO port mapping */
397 link->io.NumPorts1 = 16;
398 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
399 /* link->io.NumPorts2 = 16;
400 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
401 link->io.IOAddrLines = 5;
402
403 /* Interrupt setup */
Alan Cox47cbb112008-09-23 13:53:09 +0100404 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
406 link->irq.Handler = &netwave_interrupt;
407
408 /* General socket configuration */
409 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 link->conf.IntType = INT_MEMORY_AND_IO;
411 link->conf.ConfigIndex = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
413 /* Netwave private struct init. link/dev/node already taken care of,
414 * other stuff zero'd - Jean II */
415 spin_lock_init(&priv->spinlock);
416
417 /* Netwave specific entries in the device structure */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000418 dev->netdev_ops = &netwave_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 /* wireless extensions */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000420 dev->wireless_handlers = &netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 dev->watchdog_timeo = TX_TIMEOUT;
423
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 link->irq.Instance = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200426 return netwave_pcmcia_config( link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427} /* netwave_attach */
428
429/*
430 * Function netwave_detach (link)
431 *
432 * This deletes a driver "instance". The device is de-registered
433 * with Card Services. If it has been released, all local data
434 * structures are freed. Otherwise, the structures will be freed
435 * when the device is released.
436 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200437static void netwave_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438{
Dominik Brodowskib4635812005-11-14 21:25:35 +0100439 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440
Dominik Brodowskib4635812005-11-14 21:25:35 +0100441 DEBUG(0, "netwave_detach(0x%p)\n", link);
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100442
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100443 netwave_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
Dominik Brodowskifd238232006-03-05 10:45:09 +0100445 if (link->dev_node)
Dominik Brodowskib4635812005-11-14 21:25:35 +0100446 unregister_netdev(dev);
447
448 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449} /* netwave_detach */
450
451/*
452 * Wireless Handler : get protocol name
453 */
454static int netwave_get_name(struct net_device *dev,
455 struct iw_request_info *info,
456 union iwreq_data *wrqu,
457 char *extra)
458{
459 strcpy(wrqu->name, "Netwave");
460 return 0;
461}
462
463/*
464 * Wireless Handler : set Network ID
465 */
466static int netwave_set_nwid(struct net_device *dev,
467 struct iw_request_info *info,
468 union iwreq_data *wrqu,
469 char *extra)
470{
471 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800472 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 netwave_private *priv = netdev_priv(dev);
474 u_char __iomem *ramBase = priv->ramBase;
475
476 /* Disable interrupts & save flags */
477 spin_lock_irqsave(&priv->spinlock, flags);
478
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 if(!wrqu->nwid.disabled) {
480 domain = wrqu->nwid.value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
482 (domain >> 8) & 0x01, domain & 0xff);
483 wait_WOC(iobase);
484 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
485 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
486 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
487 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
488 }
489
490 /* ReEnable interrupts & restore flags */
491 spin_unlock_irqrestore(&priv->spinlock, flags);
492
493 return 0;
494}
495
496/*
497 * Wireless Handler : get Network ID
498 */
499static int netwave_get_nwid(struct net_device *dev,
500 struct iw_request_info *info,
501 union iwreq_data *wrqu,
502 char *extra)
503{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 wrqu->nwid.value = domain;
505 wrqu->nwid.disabled = 0;
506 wrqu->nwid.fixed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 return 0;
508}
509
510/*
511 * Wireless Handler : set scramble key
512 */
513static int netwave_set_scramble(struct net_device *dev,
514 struct iw_request_info *info,
515 union iwreq_data *wrqu,
516 char *key)
517{
518 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800519 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 netwave_private *priv = netdev_priv(dev);
521 u_char __iomem *ramBase = priv->ramBase;
522
523 /* Disable interrupts & save flags */
524 spin_lock_irqsave(&priv->spinlock, flags);
525
526 scramble_key = (key[0] << 8) | key[1];
527 wait_WOC(iobase);
528 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
529 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
530 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
531 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
532
533 /* ReEnable interrupts & restore flags */
534 spin_unlock_irqrestore(&priv->spinlock, flags);
535
536 return 0;
537}
538
539/*
540 * Wireless Handler : get scramble key
541 */
542static int netwave_get_scramble(struct net_device *dev,
543 struct iw_request_info *info,
544 union iwreq_data *wrqu,
545 char *key)
546{
547 key[1] = scramble_key & 0xff;
548 key[0] = (scramble_key>>8) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 wrqu->encoding.flags = IW_ENCODE_ENABLED;
550 wrqu->encoding.length = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 return 0;
552}
553
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554/*
555 * Wireless Handler : get mode
556 */
557static int netwave_get_mode(struct net_device *dev,
558 struct iw_request_info *info,
559 union iwreq_data *wrqu,
560 char *extra)
561{
562 if(domain & 0x100)
563 wrqu->mode = IW_MODE_INFRA;
564 else
565 wrqu->mode = IW_MODE_ADHOC;
566
567 return 0;
568}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
570/*
571 * Wireless Handler : get range info
572 */
573static int netwave_get_range(struct net_device *dev,
574 struct iw_request_info *info,
575 union iwreq_data *wrqu,
576 char *extra)
577{
578 struct iw_range *range = (struct iw_range *) extra;
579 int ret = 0;
580
581 /* Set the length (very important for backward compatibility) */
582 wrqu->data.length = sizeof(struct iw_range);
583
584 /* Set all the info we don't care or don't know about to zero */
585 memset(range, 0, sizeof(struct iw_range));
586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 /* Set the Wireless Extension versions */
588 range->we_version_compiled = WIRELESS_EXT;
589 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
591 /* Set information in the range struct */
592 range->throughput = 450 * 1000; /* don't argue on this ! */
593 range->min_nwid = 0x0000;
594 range->max_nwid = 0x01FF;
595
596 range->num_channels = range->num_frequency = 0;
597
598 range->sensitivity = 0x3F;
599 range->max_qual.qual = 255;
600 range->max_qual.level = 255;
601 range->max_qual.noise = 0;
602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 range->num_bitrates = 1;
604 range->bitrate[0] = 1000000; /* 1 Mb/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 range->encoding_size[0] = 2; /* 16 bits scrambling */
607 range->num_encoding_sizes = 1;
608 range->max_encoding_tokens = 1; /* Only one key possible */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
610 return ret;
611}
612
613/*
614 * Wireless Private Handler : get snapshot
615 */
616static int netwave_get_snap(struct net_device *dev,
617 struct iw_request_info *info,
618 union iwreq_data *wrqu,
619 char *extra)
620{
621 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800622 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 netwave_private *priv = netdev_priv(dev);
624 u_char __iomem *ramBase = priv->ramBase;
625
626 /* Disable interrupts & save flags */
627 spin_lock_irqsave(&priv->spinlock, flags);
628
629 /* Take snapshot of environment */
630 netwave_snapshot( priv, ramBase, iobase);
631 wrqu->data.length = priv->nss.length;
632 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
633
634 priv->lastExec = jiffies;
635
636 /* ReEnable interrupts & restore flags */
637 spin_unlock_irqrestore(&priv->spinlock, flags);
638
639 return(0);
640}
641
642/*
643 * Structures to export the Wireless Handlers
644 * This is the stuff that are treated the wireless extensions (iwconfig)
645 */
646
647static const struct iw_priv_args netwave_private_args[] = {
648/*{ cmd, set_args, get_args, name } */
649 { SIOCGIPSNAP, 0,
650 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
651 "getsitesurvey" },
652};
653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654static const iw_handler netwave_handler[] =
655{
656 NULL, /* SIOCSIWNAME */
657 netwave_get_name, /* SIOCGIWNAME */
658 netwave_set_nwid, /* SIOCSIWNWID */
659 netwave_get_nwid, /* SIOCGIWNWID */
660 NULL, /* SIOCSIWFREQ */
661 NULL, /* SIOCGIWFREQ */
662 NULL, /* SIOCSIWMODE */
663 netwave_get_mode, /* SIOCGIWMODE */
664 NULL, /* SIOCSIWSENS */
665 NULL, /* SIOCGIWSENS */
666 NULL, /* SIOCSIWRANGE */
667 netwave_get_range, /* SIOCGIWRANGE */
668 NULL, /* SIOCSIWPRIV */
669 NULL, /* SIOCGIWPRIV */
670 NULL, /* SIOCSIWSTATS */
671 NULL, /* SIOCGIWSTATS */
672 NULL, /* SIOCSIWSPY */
673 NULL, /* SIOCGIWSPY */
674 NULL, /* -- hole -- */
675 NULL, /* -- hole -- */
676 NULL, /* SIOCSIWAP */
677 NULL, /* SIOCGIWAP */
678 NULL, /* -- hole -- */
679 NULL, /* SIOCGIWAPLIST */
680 NULL, /* -- hole -- */
681 NULL, /* -- hole -- */
682 NULL, /* SIOCSIWESSID */
683 NULL, /* SIOCGIWESSID */
684 NULL, /* SIOCSIWNICKN */
685 NULL, /* SIOCGIWNICKN */
686 NULL, /* -- hole -- */
687 NULL, /* -- hole -- */
688 NULL, /* SIOCSIWRATE */
689 NULL, /* SIOCGIWRATE */
690 NULL, /* SIOCSIWRTS */
691 NULL, /* SIOCGIWRTS */
692 NULL, /* SIOCSIWFRAG */
693 NULL, /* SIOCGIWFRAG */
694 NULL, /* SIOCSIWTXPOW */
695 NULL, /* SIOCGIWTXPOW */
696 NULL, /* SIOCSIWRETRY */
697 NULL, /* SIOCGIWRETRY */
698 netwave_set_scramble, /* SIOCSIWENCODE */
699 netwave_get_scramble, /* SIOCGIWENCODE */
700};
701
702static const iw_handler netwave_private_handler[] =
703{
704 NULL, /* SIOCIWFIRSTPRIV */
705 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
706};
707
708static const struct iw_handler_def netwave_handler_def =
709{
Denis Chengff8ac602007-09-02 18:30:18 +0800710 .num_standard = ARRAY_SIZE(netwave_handler),
711 .num_private = ARRAY_SIZE(netwave_private_handler),
712 .num_private_args = ARRAY_SIZE(netwave_private_args),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 .standard = (iw_handler *) netwave_handler,
714 .private = (iw_handler *) netwave_private_handler,
715 .private_args = (struct iw_priv_args *) netwave_private_args,
Jean Tourrilhes62337dd2005-09-02 11:39:02 -0700716 .get_wireless_stats = netwave_get_wireless_stats,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719/*
720 * Function netwave_pcmcia_config (link)
721 *
722 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
723 * event is received, to configure the PCMCIA socket, and to make the
724 * device available to the system.
725 *
726 */
727
728#define CS_CHECK(fn, ret) \
729do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
730
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200731static int netwave_pcmcia_config(struct pcmcia_device *link) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 struct net_device *dev = link->priv;
733 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 int i, j, last_ret, last_fn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 win_req_t req;
736 memreq_t mem;
737 u_char __iomem *ramBase = NULL;
738
739 DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
740
741 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 * Try allocating IO ports. This tries a few fixed addresses.
743 * If you want, you can also read the card's config table to
744 * pick addresses -- see the serial driver for an example.
745 */
746 for (i = j = 0x0; j < 0x400; j += 0x20) {
747 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200748 i = pcmcia_request_io(link, &link->io);
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200749 if (i == 0)
750 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 }
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200752 if (i != 0) {
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200753 cs_error(link, RequestIO, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 goto failed;
755 }
756
757 /*
758 * Now allocate an interrupt line. Note that this does not
759 * actually assign a handler to the interrupt.
760 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200761 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
763 /*
764 * This actually configures the PCMCIA socket -- setting up
765 * the I/O windows and the interrupt mapping.
766 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200767 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768
769 /*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200770 * Allocate a 32K memory window. Note that the struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 * structure provides space for one window handle -- if your
772 * device needs several windows, you'll need to keep track of
773 * the handles in your private data structure, dev->priv.
774 */
775 DEBUG(1, "Setting mem speed of %d\n", mem_speed);
776
777 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
778 req.Base = 0; req.Size = 0x8000;
779 req.AccessSpeed = mem_speed;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200780 CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 mem.CardOffset = 0x20000; mem.Page = 0;
782 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
783
784 /* Store base address of the common window frame */
785 ramBase = ioremap(req.Base, 0x8000);
786 priv->ramBase = ramBase;
787
788 dev->irq = link->irq.AssignedIRQ;
789 dev->base_addr = link->io.BasePort1;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200790 SET_NETDEV_DEV(dev, &handle_to_dev(link));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
792 if (register_netdev(dev) != 0) {
793 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
794 goto failed;
795 }
796
797 strcpy(priv->node.dev_name, dev->name);
Dominik Brodowskifd238232006-03-05 10:45:09 +0100798 link->dev_node = &priv->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
800 /* Reset card before reading physical address */
801 netwave_doreset(dev->base_addr, ramBase);
802
803 /* Read the ethernet address and fill in the Netwave registers. */
804 for (i = 0; i < 6; i++)
805 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
806
Joe Perches8376e7a2007-11-19 17:48:27 -0800807 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
Johannes Berge1749612008-10-27 15:59:26 -0700808 "id %c%c, hw_addr %pM\n",
Joe Perches0795af52007-10-03 17:59:30 -0700809 dev->name, dev->base_addr, dev->irq,
810 (u_long) ramBase,
811 (int) readb(ramBase+NETWAVE_EREG_NI),
812 (int) readb(ramBase+NETWAVE_EREG_NI+1),
Johannes Berge1749612008-10-27 15:59:26 -0700813 dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
815 /* get revision words */
816 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
817 get_uint16(ramBase + NETWAVE_EREG_ARW),
818 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200819 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
821cs_failed:
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200822 cs_error(link, last_fn, last_ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823failed:
824 netwave_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200825 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826} /* netwave_pcmcia_config */
827
828/*
829 * Function netwave_release (arg)
830 *
831 * After a card is removed, netwave_release() will unregister the net
832 * device, and release the PCMCIA configuration. If the device is
833 * still open, this will be postponed until it is closed.
834 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200835static void netwave_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100837 struct net_device *dev = link->priv;
838 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100840 DEBUG(0, "netwave_release(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200842 pcmcia_disable_device(link);
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100843 if (link->win)
844 iounmap(priv->ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845}
846
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200847static int netwave_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100848{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100849 struct net_device *dev = link->priv;
850
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100851 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100852 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100853
854 return 0;
855}
856
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200857static int netwave_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100858{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100859 struct net_device *dev = link->priv;
860
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100861 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100862 netwave_reset(dev);
863 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100864 }
865
866 return 0;
867}
868
869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 * Function netwave_doreset (ioBase, ramBase)
872 *
873 * Proper hardware reset of the card.
874 */
Olof Johansson906da802008-02-04 22:27:35 -0800875static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876{
877 /* Reset card */
878 wait_WOC(ioBase);
879 outb(0x80, ioBase + NETWAVE_REG_PMR);
880 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
881 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
882}
883
884/*
885 * Function netwave_reset (dev)
886 *
887 * Reset and restore all of the netwave registers
888 */
889static void netwave_reset(struct net_device *dev) {
890 /* u_char state; */
891 netwave_private *priv = netdev_priv(dev);
892 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800893 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
895 DEBUG(0, "netwave_reset: Done with hardware reset\n");
896
897 priv->timeoutCounter = 0;
898
899 /* Reset card */
900 netwave_doreset(iobase, ramBase);
901 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
902
903 /* Write a NOP to check the card */
904 wait_WOC(iobase);
905 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
906 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
907
908 /* Set receive conf */
909 wait_WOC(iobase);
910 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
911 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
912 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
913
914 /* Set transmit conf */
915 wait_WOC(iobase);
916 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
917 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
918 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
919
920 /* Now set the MU Domain */
921 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
922 wait_WOC(iobase);
923 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
924 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
925 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
926 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
927
928 /* Set scramble key */
929 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
930 wait_WOC(iobase);
931 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
932 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
933 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
934 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
935
936 /* Enable interrupts, bit 4 high to keep unused
937 * source from interrupting us, bit 2 high to
938 * set interrupt enable, 567 to enable TxDN,
939 * RxErr and RxRdy
940 */
941 wait_WOC(iobase);
942 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
943
944 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
945 * waitWOC
946 * skriv 80 til d000:3688
947 * sjekk om det ble 80
948 */
949
950 /* Enable Receiver */
951 wait_WOC(iobase);
952 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
953 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
954
955 /* Set the IENA bit in COR */
956 wait_WOC(iobase);
957 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
958}
959
960/*
961 * Function netwave_hw_xmit (data, len, dev)
962 */
963static int netwave_hw_xmit(unsigned char* data, int len,
964 struct net_device* dev) {
965 unsigned long flags;
966 unsigned int TxFreeList,
967 curBuff,
968 MaxData,
969 DataOffset;
970 int tmpcount;
971
972 netwave_private *priv = netdev_priv(dev);
973 u_char __iomem * ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800974 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
976 /* Disable interrupts & save flags */
977 spin_lock_irqsave(&priv->spinlock, flags);
978
979 /* Check if there are transmit buffers available */
980 wait_WOC(iobase);
981 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
982 /* No buffers available */
983 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
984 dev->name);
985 spin_unlock_irqrestore(&priv->spinlock, flags);
986 return 1;
987 }
988
Stephen Hemmingerf56ef162009-03-20 19:36:21 +0000989 dev->stats.tx_bytes += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
991 DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
992 readb(ramBase + NETWAVE_EREG_SPCQ),
993 readb(ramBase + NETWAVE_EREG_SPU),
994 readb(ramBase + NETWAVE_EREG_LIF),
995 readb(ramBase + NETWAVE_EREG_ISPLQ));
996
997 /* Now try to insert it into the adapters free memory */
998 wait_WOC(iobase);
999 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
1000 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
1001 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
1002
1003 DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
1004 TxFreeList, MaxData, DataOffset);
1005
1006 /* Copy packet to the adapter fragment buffers */
1007 curBuff = TxFreeList;
1008 tmpcount = 0;
1009 while (tmpcount < len) {
1010 int tmplen = len - tmpcount;
1011 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
1012 (tmplen < MaxData) ? tmplen : MaxData);
1013 tmpcount += MaxData;
1014
1015 /* Advance to next buffer */
1016 curBuff = get_uint16(ramBase + curBuff);
1017 }
1018
1019 /* Now issue transmit list */
1020 wait_WOC(iobase);
1021 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1022 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1023 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1024 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1025
1026 spin_unlock_irqrestore(&priv->spinlock, flags);
1027 return 0;
1028}
1029
Stephen Hemmingerd0cf9c02009-08-31 19:50:57 +00001030static netdev_tx_t netwave_start_xmit(struct sk_buff *skb,
1031 struct net_device *dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 /* This flag indicate that the hardware can't perform a transmission.
1033 * Theoritically, NET3 check it before sending a packet to the driver,
1034 * but in fact it never do that and pool continuously.
1035 * As the watchdog will abort too long transmissions, we are quite safe...
1036 */
1037
1038 netif_stop_queue(dev);
1039
1040 {
1041 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1042 unsigned char* buf = skb->data;
1043
1044 if (netwave_hw_xmit( buf, length, dev) == 1) {
1045 /* Some error, let's make them call us another time? */
1046 netif_start_queue(dev);
1047 }
1048 dev->trans_start = jiffies;
1049 }
1050 dev_kfree_skb(skb);
1051
Patrick McHardy6ed10652009-06-23 06:03:08 +00001052 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053} /* netwave_start_xmit */
1054
1055/*
David Howells7d12e782006-10-05 14:55:46 +01001056 * Function netwave_interrupt (irq, dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 *
1058 * This function is the interrupt handler for the Netwave card. This
1059 * routine will be called whenever:
1060 * 1. A packet is received.
1061 * 2. A packet has successfully been transferred and the unit is
1062 * ready to transmit another packet.
1063 * 3. A command has completed execution.
1064 */
David Howells7d12e782006-10-05 14:55:46 +01001065static irqreturn_t netwave_interrupt(int irq, void* dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066{
Olof Johansson906da802008-02-04 22:27:35 -08001067 unsigned int iobase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 u_char __iomem *ramBase;
1069 struct net_device *dev = (struct net_device *)dev_id;
1070 struct netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001071 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 int i;
1073
1074 if (!netif_device_present(dev))
1075 return IRQ_NONE;
1076
1077 iobase = dev->base_addr;
1078 ramBase = priv->ramBase;
1079
1080 /* Now find what caused the interrupt, check while interrupts ready */
1081 for (i = 0; i < 10; i++) {
1082 u_char status;
1083
1084 wait_WOC(iobase);
1085 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1086 break; /* None of the interrupt sources asserted (normal exit) */
1087
1088 status = inb(iobase + NETWAVE_REG_ASR);
1089
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001090 if (!pcmcia_dev_present(link)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
1092 "from removed or suspended card!\n", status);
1093 break;
1094 }
1095
1096 /* RxRdy */
1097 if (status & 0x80) {
1098 netwave_rx(dev);
1099 /* wait_WOC(iobase); */
1100 /* RxRdy cannot be reset directly by the host */
1101 }
1102 /* RxErr */
1103 if (status & 0x40) {
1104 u_char rser;
1105
1106 rser = readb(ramBase + NETWAVE_EREG_RSER);
1107
1108 if (rser & 0x04) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001109 ++dev->stats.rx_dropped;
1110 ++dev->stats.rx_crc_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 }
1112 if (rser & 0x02)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001113 ++dev->stats.rx_frame_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
1115 /* Clear the RxErr bit in RSER. RSER+4 is the
1116 * write part. Also clear the RxCRC (0x04) and
1117 * RxBig (0x02) bits if present */
1118 wait_WOC(iobase);
1119 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1120
1121 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1122 * WOC must be set first!
1123 */
1124 wait_WOC(iobase);
1125 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1126
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001127 /* Remember to count up dev->stats on error packets */
1128 ++dev->stats.rx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 }
1130 /* TxDN */
1131 if (status & 0x20) {
1132 int txStatus;
1133
1134 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
1135 DEBUG(3, "Transmit done. TSER = %x id %x\n",
1136 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1137
1138 if (txStatus & 0x20) {
1139 /* Transmitting was okay, clear bits */
1140 wait_WOC(iobase);
1141 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001142 ++dev->stats.tx_packets;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 }
1144
1145 if (txStatus & 0xd0) {
1146 if (txStatus & 0x80) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001147 ++dev->stats.collisions; /* Because of /proc/net/dev*/
1148 /* ++dev->stats.tx_aborted_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1150 }
1151 if (txStatus & 0x40)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001152 ++dev->stats.tx_carrier_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 /* 0x80 TxGU Transmit giveup - nine times and no luck
1154 * 0x40 TxNOAP No access point. Discarded packet.
1155 * 0x10 TxErr Transmit error. Always set when
1156 * TxGU and TxNOAP is set. (Those are the only ones
1157 * to set TxErr).
1158 */
1159 DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
1160 txStatus);
1161
1162 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1163 wait_WOC(iobase);
1164 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001165 ++dev->stats.tx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 }
1167 DEBUG(3, "New status is TSER %x ASR %x\n",
1168 readb(ramBase + NETWAVE_EREG_TSER),
1169 inb(iobase + NETWAVE_REG_ASR));
1170
1171 netif_wake_queue(dev);
1172 }
1173 /* TxBA, this would trigger on all error packets received */
1174 /* if (status & 0x01) {
1175 DEBUG(4, "Transmit buffers available, %x\n", status);
1176 }
1177 */
1178 }
1179 /* Handled if we looped at least one time - Jean II */
1180 return IRQ_RETVAL(i);
1181} /* netwave_interrupt */
1182
1183/*
1184 * Function netwave_watchdog (a)
1185 *
1186 * Watchdog : when we start a transmission, we set a timer in the
1187 * kernel. If the transmission complete, this timer is disabled. If
1188 * it expire, we reset the card.
1189 *
1190 */
1191static void netwave_watchdog(struct net_device *dev) {
1192
1193 DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
1194 netwave_reset(dev);
1195 dev->trans_start = jiffies;
1196 netif_wake_queue(dev);
1197} /* netwave_watchdog */
1198
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199static int netwave_rx(struct net_device *dev)
1200{
1201 netwave_private *priv = netdev_priv(dev);
1202 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -08001203 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 u_char rxStatus;
1205 struct sk_buff *skb = NULL;
1206 unsigned int curBuffer,
1207 rcvList;
1208 int rcvLen;
1209 int tmpcount = 0;
1210 int dataCount, dataOffset;
1211 int i;
1212 u_char *ptr;
1213
1214 DEBUG(3, "xinw_rx: Receiving ... \n");
1215
1216 /* Receive max 10 packets for now. */
1217 for (i = 0; i < 10; i++) {
1218 /* Any packets? */
1219 wait_WOC(iobase);
1220 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1221 if ( !( rxStatus & 0x80)) /* No more packets */
1222 break;
1223
1224 /* Check if multicast/broadcast or other */
1225 /* multicast = (rxStatus & 0x20); */
1226
1227 /* The receive list pointer and length of the packet */
1228 wait_WOC(iobase);
1229 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1230 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1231
1232 if (rcvLen < 0) {
1233 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1234 rcvLen);
1235 return 0;
1236 }
1237
1238 skb = dev_alloc_skb(rcvLen+5);
1239 if (skb == NULL) {
1240 DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
1241 "length %d\n", rcvLen);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001242 ++dev->stats.rx_dropped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 /* Tell the adapter to skip the packet */
1244 wait_WOC(iobase);
1245 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1246 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1247 return 0;
1248 }
1249
1250 skb_reserve( skb, 2); /* Align IP on 16 byte */
1251 skb_put( skb, rcvLen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
1253 /* Copy packet fragments to the skb data area */
1254 ptr = (u_char*) skb->data;
1255 curBuffer = rcvList;
1256 tmpcount = 0;
1257 while ( tmpcount < rcvLen) {
1258 /* Get length and offset of current buffer */
1259 dataCount = get_uint16( ramBase+curBuffer+2);
1260 dataOffset = get_uint16( ramBase+curBuffer+4);
1261
1262 copy_from_pc( ptr + tmpcount,
1263 ramBase+curBuffer+dataOffset, dataCount);
1264
1265 tmpcount += dataCount;
1266
1267 /* Point to next buffer */
1268 curBuffer = get_uint16(ramBase + curBuffer);
1269 }
1270
1271 skb->protocol = eth_type_trans(skb,dev);
1272 /* Queue packet for network layer */
1273 netif_rx(skb);
1274
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001275 dev->stats.rx_packets++;
1276 dev->stats.rx_bytes += rcvLen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
1278 /* Got the packet, tell the adapter to skip it */
1279 wait_WOC(iobase);
1280 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1281 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1282 DEBUG(3, "Packet reception ok\n");
1283 }
1284 return 0;
1285}
1286
1287static int netwave_open(struct net_device *dev) {
1288 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001289 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290
1291 DEBUG(1, "netwave_open: starting.\n");
1292
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001293 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 return -ENODEV;
1295
1296 link->open++;
1297
1298 netif_start_queue(dev);
1299 netwave_reset(dev);
1300
1301 return 0;
1302}
1303
1304static int netwave_close(struct net_device *dev) {
1305 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001306 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308 DEBUG(1, "netwave_close: finishing.\n");
1309
1310 link->open--;
1311 netif_stop_queue(dev);
1312
1313 return 0;
1314}
1315
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001316static struct pcmcia_device_id netwave_ids[] = {
1317 PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
1318 PCMCIA_DEVICE_NULL,
1319};
1320MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
1321
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322static struct pcmcia_driver netwave_driver = {
1323 .owner = THIS_MODULE,
1324 .drv = {
1325 .name = "netwave_cs",
1326 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001327 .probe = netwave_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001328 .remove = netwave_detach,
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001329 .id_table = netwave_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001330 .suspend = netwave_suspend,
1331 .resume = netwave_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332};
1333
1334static int __init init_netwave_cs(void)
1335{
1336 return pcmcia_register_driver(&netwave_driver);
1337}
1338
1339static void __exit exit_netwave_cs(void)
1340{
1341 pcmcia_unregister_driver(&netwave_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342}
1343
1344module_init(init_netwave_cs);
1345module_exit(exit_netwave_cs);
1346
1347/* Set or clear the multicast filter for this adaptor.
1348 num_addrs == -1 Promiscuous mode, receive all packets
1349 num_addrs == 0 Normal mode, clear multicast list
1350 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1351 best-effort filtering.
1352 */
1353static void set_multicast_list(struct net_device *dev)
1354{
Olof Johansson906da802008-02-04 22:27:35 -08001355 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 netwave_private *priv = netdev_priv(dev);
1357 u_char __iomem * ramBase = priv->ramBase;
1358 u_char rcvMode = 0;
1359
1360#ifdef PCMCIA_DEBUG
1361 if (pc_debug > 2) {
1362 static int old;
1363 if (old != dev->mc_count) {
1364 old = dev->mc_count;
1365 DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
1366 dev->name, dev->mc_count);
1367 }
1368 }
1369#endif
1370
1371 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1372 /* Multicast Mode */
1373 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1374 } else if (dev->flags & IFF_PROMISC) {
1375 /* Promiscous mode */
1376 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1377 } else {
1378 /* Normal mode */
1379 rcvMode = rxConfRxEna + rxConfBcast;
1380 }
1381
1382 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1383 /* Now set receive mode */
1384 wait_WOC(iobase);
1385 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1386 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1387 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1388}
1389MODULE_LICENSE("GPL");