blob: e61e6b9440abec403af70d32efb8c99961021af5 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149/*====================================================================*/
150
151/* Parameters that can be set with 'insmod' */
152
153/* Choose the domain, default is 0x100 */
154static u_int domain = 0x100;
155
156/* Scramble key, range from 0x0 to 0xffff.
157 * 0x0 is no scrambling.
158 */
159static u_int scramble_key = 0x0;
160
161/* Shared memory speed, in ns. The documentation states that
162 * the card should not be read faster than every 400ns.
163 * This timing should be provided by the HBA. If it becomes a
164 * problem, try setting mem_speed to 400.
165 */
166static int mem_speed;
167
168module_param(domain, int, 0);
169module_param(scramble_key, int, 0);
170module_param(mem_speed, int, 0);
171
172/*====================================================================*/
173
174/* PCMCIA (Card Services) related functions */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200175static void netwave_release(struct pcmcia_device *link); /* Card removal */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200176static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 insertion */
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100178static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
180/* Hardware configuration */
Olof Johansson906da802008-02-04 22:27:35 -0800181static void netwave_doreset(unsigned int iobase, u_char __iomem *ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182static void netwave_reset(struct net_device *dev);
183
184/* Misc device stuff */
185static int netwave_open(struct net_device *dev); /* Open the device */
186static int netwave_close(struct net_device *dev); /* Close the device */
187
188/* Packet transmission and Packet reception */
Stephen Hemmingerd0cf9c02009-08-31 19:50:57 +0000189static netdev_tx_t netwave_start_xmit( struct sk_buff *skb,
190 struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191static int netwave_rx( struct net_device *dev);
192
193/* Interrupt routines */
David Howells7d12e782006-10-05 14:55:46 +0100194static irqreturn_t netwave_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195static void netwave_watchdog(struct net_device *);
196
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197/* Wireless extensions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
200static void set_multicast_list(struct net_device *dev);
201
202/*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200203 A struct pcmcia_device structure has fields for most things that are needed
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 to keep track of a socket, but there will usually be some device
205 specific information that also needs to be kept track of. The
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200206 'priv' pointer in a struct pcmcia_device structure can be used to point to
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 a device-specific private data structure, like this.
208
209 A driver needs to provide a dev_node_t structure for each device
210 on a card. In some cases, there is only one device per card (for
211 example, ethernet cards, modems). In other cases, there may be
212 many actual or logical devices (SCSI adapters, memory cards with
213 multiple partitions). The dev_node_t structures need to be kept
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200214 in a linked list starting at the 'dev' field of a struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 structure. We allocate them in the card's private data structure,
216 because they generally can't be allocated dynamically.
217*/
218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219static const struct iw_handler_def netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
222
223#define MAX_ESA 10
224
225typedef struct net_addr {
226 u_char addr48[6];
227} net_addr;
228
229struct site_survey {
230 u_short length;
231 u_char struct_revision;
232 u_char roaming_state;
233
234 u_char sp_existsFlag;
235 u_char sp_link_quality;
236 u_char sp_max_link_quality;
237 u_char linkQualityGoodFairBoundary;
238 u_char linkQualityFairPoorBoundary;
239 u_char sp_utilization;
240 u_char sp_goodness;
241 u_char sp_hotheadcount;
242 u_char roaming_condition;
243
244 net_addr sp;
245 u_char numAPs;
246 net_addr nearByAccessPoints[MAX_ESA];
247};
248
249typedef struct netwave_private {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100250 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
252 dev_node_t node;
253 u_char __iomem *ramBase;
254 int timeoutCounter;
255 int lastExec;
256 struct timer_list watchdog; /* To avoid blocking state */
257 struct site_survey nss;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 struct iw_statistics iw_stats; /* Wireless stats */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259} netwave_private;
260
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261/*
262 * The Netwave card is little-endian, so won't work for big endian
263 * systems.
264 */
265static inline unsigned short get_uint16(u_char __iomem *staddr)
266{
267 return readw(staddr); /* Return only 16 bits */
268}
269
270static inline short get_int16(u_char __iomem * staddr)
271{
272 return readw(staddr);
273}
274
275/*
276 * Wait until the WOC (Write Operation Complete) bit in the
277 * ASR (Adapter Status Register) is asserted.
278 * This should have aborted if it takes too long time.
279 */
280static inline void wait_WOC(unsigned int iobase)
281{
282 /* Spin lock */
283 while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
284}
285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
Olof Johansson906da802008-02-04 22:27:35 -0800287 unsigned int iobase) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 u_short resultBuffer;
289
290 /* if time since last snapshot is > 1 sec. (100 jiffies?) then take
291 * new snapshot, else return cached data. This is the recommended rate.
292 */
293 if ( jiffies - priv->lastExec > 100) {
294 /* Take site survey snapshot */
295 /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies -
296 priv->lastExec); */
297 wait_WOC(iobase);
298 writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0);
299 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
300 wait_WOC(iobase);
301
302 /* Get result and copy to cach */
303 resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP);
304 copy_from_pc( &priv->nss, ramBase+resultBuffer,
305 sizeof(struct site_survey));
306 }
307}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309/*
310 * Function netwave_get_wireless_stats (dev)
311 *
312 * Wireless extensions statistics
313 *
314 */
315static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
316{
317 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800318 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 netwave_private *priv = netdev_priv(dev);
320 u_char __iomem *ramBase = priv->ramBase;
321 struct iw_statistics* wstats;
322
323 wstats = &priv->iw_stats;
324
325 spin_lock_irqsave(&priv->spinlock, flags);
326
327 netwave_snapshot( priv, ramBase, iobase);
328
329 wstats->status = priv->nss.roaming_state;
330 wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ);
331 wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ);
332 wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f;
333 wstats->discard.nwid = 0L;
334 wstats->discard.code = 0L;
335 wstats->discard.misc = 0L;
336
337 spin_unlock_irqrestore(&priv->spinlock, flags);
338
339 return &priv->iw_stats;
340}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000342static const struct net_device_ops netwave_netdev_ops = {
343 .ndo_open = netwave_open,
344 .ndo_stop = netwave_close,
345 .ndo_start_xmit = netwave_start_xmit,
346 .ndo_set_multicast_list = set_multicast_list,
347 .ndo_tx_timeout = netwave_watchdog,
348 .ndo_change_mtu = eth_change_mtu,
349 .ndo_set_mac_address = eth_mac_addr,
350 .ndo_validate_addr = eth_validate_addr,
351};
352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353/*
354 * Function netwave_attach (void)
355 *
356 * Creates an "instance" of the driver, allocating local data
357 * structures for one device. The device is registered with Card
358 * Services.
359 *
360 * The dev_link structure is initialized, but we don't actually
361 * configure the card at this point -- we wait until we receive a
362 * card insertion event.
363 */
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200364static int netwave_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 struct net_device *dev;
367 netwave_private *priv;
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100368
Dominik Brodowski2caff142009-10-24 15:53:36 +0200369 dev_dbg(&link->dev, "netwave_attach()\n");
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100370
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200371 /* Initialize the struct pcmcia_device structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 dev = alloc_etherdev(sizeof(netwave_private));
373 if (!dev)
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100374 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200376 priv->p_dev = link;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 link->priv = dev;
378
379 /* The io structure describes IO port mapping */
380 link->io.NumPorts1 = 16;
381 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
382 /* link->io.NumPorts2 = 16;
383 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
384 link->io.IOAddrLines = 5;
385
386 /* Interrupt setup */
Dominik Brodowski5fa91672009-11-08 17:24:46 +0100387 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 link->irq.Handler = &netwave_interrupt;
389
390 /* General socket configuration */
391 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 link->conf.IntType = INT_MEMORY_AND_IO;
393 link->conf.ConfigIndex = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
395 /* Netwave private struct init. link/dev/node already taken care of,
396 * other stuff zero'd - Jean II */
397 spin_lock_init(&priv->spinlock);
398
399 /* Netwave specific entries in the device structure */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000400 dev->netdev_ops = &netwave_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 /* wireless extensions */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000402 dev->wireless_handlers = &netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 dev->watchdog_timeo = TX_TIMEOUT;
405
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200406 return netwave_pcmcia_config( link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407} /* netwave_attach */
408
409/*
410 * Function netwave_detach (link)
411 *
412 * This deletes a driver "instance". The device is de-registered
413 * with Card Services. If it has been released, all local data
414 * structures are freed. Otherwise, the structures will be freed
415 * when the device is released.
416 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200417static void netwave_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418{
Dominik Brodowskib4635812005-11-14 21:25:35 +0100419 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Dominik Brodowski2caff142009-10-24 15:53:36 +0200421 dev_dbg(&link->dev, "netwave_detach\n");
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100422
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100423 netwave_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Dominik Brodowskifd238232006-03-05 10:45:09 +0100425 if (link->dev_node)
Dominik Brodowskib4635812005-11-14 21:25:35 +0100426 unregister_netdev(dev);
427
428 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429} /* netwave_detach */
430
431/*
432 * Wireless Handler : get protocol name
433 */
434static int netwave_get_name(struct net_device *dev,
435 struct iw_request_info *info,
436 union iwreq_data *wrqu,
437 char *extra)
438{
439 strcpy(wrqu->name, "Netwave");
440 return 0;
441}
442
443/*
444 * Wireless Handler : set Network ID
445 */
446static int netwave_set_nwid(struct net_device *dev,
447 struct iw_request_info *info,
448 union iwreq_data *wrqu,
449 char *extra)
450{
451 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800452 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 netwave_private *priv = netdev_priv(dev);
454 u_char __iomem *ramBase = priv->ramBase;
455
456 /* Disable interrupts & save flags */
457 spin_lock_irqsave(&priv->spinlock, flags);
458
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 if(!wrqu->nwid.disabled) {
460 domain = wrqu->nwid.value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
462 (domain >> 8) & 0x01, domain & 0xff);
463 wait_WOC(iobase);
464 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
465 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
466 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
467 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
468 }
469
470 /* ReEnable interrupts & restore flags */
471 spin_unlock_irqrestore(&priv->spinlock, flags);
472
473 return 0;
474}
475
476/*
477 * Wireless Handler : get Network ID
478 */
479static int netwave_get_nwid(struct net_device *dev,
480 struct iw_request_info *info,
481 union iwreq_data *wrqu,
482 char *extra)
483{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 wrqu->nwid.value = domain;
485 wrqu->nwid.disabled = 0;
486 wrqu->nwid.fixed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 return 0;
488}
489
490/*
491 * Wireless Handler : set scramble key
492 */
493static int netwave_set_scramble(struct net_device *dev,
494 struct iw_request_info *info,
495 union iwreq_data *wrqu,
496 char *key)
497{
498 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800499 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 netwave_private *priv = netdev_priv(dev);
501 u_char __iomem *ramBase = priv->ramBase;
502
503 /* Disable interrupts & save flags */
504 spin_lock_irqsave(&priv->spinlock, flags);
505
506 scramble_key = (key[0] << 8) | key[1];
507 wait_WOC(iobase);
508 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
509 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
510 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
511 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
512
513 /* ReEnable interrupts & restore flags */
514 spin_unlock_irqrestore(&priv->spinlock, flags);
515
516 return 0;
517}
518
519/*
520 * Wireless Handler : get scramble key
521 */
522static int netwave_get_scramble(struct net_device *dev,
523 struct iw_request_info *info,
524 union iwreq_data *wrqu,
525 char *key)
526{
527 key[1] = scramble_key & 0xff;
528 key[0] = (scramble_key>>8) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 wrqu->encoding.flags = IW_ENCODE_ENABLED;
530 wrqu->encoding.length = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 return 0;
532}
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534/*
535 * Wireless Handler : get mode
536 */
537static int netwave_get_mode(struct net_device *dev,
538 struct iw_request_info *info,
539 union iwreq_data *wrqu,
540 char *extra)
541{
542 if(domain & 0x100)
543 wrqu->mode = IW_MODE_INFRA;
544 else
545 wrqu->mode = IW_MODE_ADHOC;
546
547 return 0;
548}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550/*
551 * Wireless Handler : get range info
552 */
553static int netwave_get_range(struct net_device *dev,
554 struct iw_request_info *info,
555 union iwreq_data *wrqu,
556 char *extra)
557{
558 struct iw_range *range = (struct iw_range *) extra;
559 int ret = 0;
560
561 /* Set the length (very important for backward compatibility) */
562 wrqu->data.length = sizeof(struct iw_range);
563
564 /* Set all the info we don't care or don't know about to zero */
565 memset(range, 0, sizeof(struct iw_range));
566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* Set the Wireless Extension versions */
568 range->we_version_compiled = WIRELESS_EXT;
569 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 /* Set information in the range struct */
572 range->throughput = 450 * 1000; /* don't argue on this ! */
573 range->min_nwid = 0x0000;
574 range->max_nwid = 0x01FF;
575
576 range->num_channels = range->num_frequency = 0;
577
578 range->sensitivity = 0x3F;
579 range->max_qual.qual = 255;
580 range->max_qual.level = 255;
581 range->max_qual.noise = 0;
582
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 range->num_bitrates = 1;
584 range->bitrate[0] = 1000000; /* 1 Mb/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 range->encoding_size[0] = 2; /* 16 bits scrambling */
587 range->num_encoding_sizes = 1;
588 range->max_encoding_tokens = 1; /* Only one key possible */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590 return ret;
591}
592
593/*
594 * Wireless Private Handler : get snapshot
595 */
596static int netwave_get_snap(struct net_device *dev,
597 struct iw_request_info *info,
598 union iwreq_data *wrqu,
599 char *extra)
600{
601 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800602 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 netwave_private *priv = netdev_priv(dev);
604 u_char __iomem *ramBase = priv->ramBase;
605
606 /* Disable interrupts & save flags */
607 spin_lock_irqsave(&priv->spinlock, flags);
608
609 /* Take snapshot of environment */
610 netwave_snapshot( priv, ramBase, iobase);
611 wrqu->data.length = priv->nss.length;
612 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
613
614 priv->lastExec = jiffies;
615
616 /* ReEnable interrupts & restore flags */
617 spin_unlock_irqrestore(&priv->spinlock, flags);
618
619 return(0);
620}
621
622/*
623 * Structures to export the Wireless Handlers
624 * This is the stuff that are treated the wireless extensions (iwconfig)
625 */
626
627static const struct iw_priv_args netwave_private_args[] = {
628/*{ cmd, set_args, get_args, name } */
629 { SIOCGIPSNAP, 0,
630 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
631 "getsitesurvey" },
632};
633
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634static const iw_handler netwave_handler[] =
635{
636 NULL, /* SIOCSIWNAME */
637 netwave_get_name, /* SIOCGIWNAME */
638 netwave_set_nwid, /* SIOCSIWNWID */
639 netwave_get_nwid, /* SIOCGIWNWID */
640 NULL, /* SIOCSIWFREQ */
641 NULL, /* SIOCGIWFREQ */
642 NULL, /* SIOCSIWMODE */
643 netwave_get_mode, /* SIOCGIWMODE */
644 NULL, /* SIOCSIWSENS */
645 NULL, /* SIOCGIWSENS */
646 NULL, /* SIOCSIWRANGE */
647 netwave_get_range, /* SIOCGIWRANGE */
648 NULL, /* SIOCSIWPRIV */
649 NULL, /* SIOCGIWPRIV */
650 NULL, /* SIOCSIWSTATS */
651 NULL, /* SIOCGIWSTATS */
652 NULL, /* SIOCSIWSPY */
653 NULL, /* SIOCGIWSPY */
654 NULL, /* -- hole -- */
655 NULL, /* -- hole -- */
656 NULL, /* SIOCSIWAP */
657 NULL, /* SIOCGIWAP */
658 NULL, /* -- hole -- */
659 NULL, /* SIOCGIWAPLIST */
660 NULL, /* -- hole -- */
661 NULL, /* -- hole -- */
662 NULL, /* SIOCSIWESSID */
663 NULL, /* SIOCGIWESSID */
664 NULL, /* SIOCSIWNICKN */
665 NULL, /* SIOCGIWNICKN */
666 NULL, /* -- hole -- */
667 NULL, /* -- hole -- */
668 NULL, /* SIOCSIWRATE */
669 NULL, /* SIOCGIWRATE */
670 NULL, /* SIOCSIWRTS */
671 NULL, /* SIOCGIWRTS */
672 NULL, /* SIOCSIWFRAG */
673 NULL, /* SIOCGIWFRAG */
674 NULL, /* SIOCSIWTXPOW */
675 NULL, /* SIOCGIWTXPOW */
676 NULL, /* SIOCSIWRETRY */
677 NULL, /* SIOCGIWRETRY */
678 netwave_set_scramble, /* SIOCSIWENCODE */
679 netwave_get_scramble, /* SIOCGIWENCODE */
680};
681
682static const iw_handler netwave_private_handler[] =
683{
684 NULL, /* SIOCIWFIRSTPRIV */
685 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
686};
687
688static const struct iw_handler_def netwave_handler_def =
689{
Denis Chengff8ac602007-09-02 18:30:18 +0800690 .num_standard = ARRAY_SIZE(netwave_handler),
691 .num_private = ARRAY_SIZE(netwave_private_handler),
692 .num_private_args = ARRAY_SIZE(netwave_private_args),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 .standard = (iw_handler *) netwave_handler,
694 .private = (iw_handler *) netwave_private_handler,
695 .private_args = (struct iw_priv_args *) netwave_private_args,
Jean Tourrilhes62337dd2005-09-02 11:39:02 -0700696 .get_wireless_stats = netwave_get_wireless_stats,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698
699/*
700 * Function netwave_pcmcia_config (link)
701 *
702 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
703 * event is received, to configure the PCMCIA socket, and to make the
704 * device available to the system.
705 *
706 */
707
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200708static int netwave_pcmcia_config(struct pcmcia_device *link) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 struct net_device *dev = link->priv;
710 netwave_private *priv = netdev_priv(dev);
Dominik Brodowski2caff142009-10-24 15:53:36 +0200711 int i, j, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 win_req_t req;
713 memreq_t mem;
714 u_char __iomem *ramBase = NULL;
715
Dominik Brodowski2caff142009-10-24 15:53:36 +0200716 dev_dbg(&link->dev, "netwave_pcmcia_config\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717
718 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 * Try allocating IO ports. This tries a few fixed addresses.
720 * If you want, you can also read the card's config table to
721 * pick addresses -- see the serial driver for an example.
722 */
723 for (i = j = 0x0; j < 0x400; j += 0x20) {
724 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200725 i = pcmcia_request_io(link, &link->io);
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200726 if (i == 0)
727 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 }
Dominik Brodowski2caff142009-10-24 15:53:36 +0200729 if (i != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731
732 /*
733 * Now allocate an interrupt line. Note that this does not
734 * actually assign a handler to the interrupt.
735 */
Dominik Brodowski2caff142009-10-24 15:53:36 +0200736 ret = pcmcia_request_irq(link, &link->irq);
737 if (ret)
738 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739
740 /*
741 * This actually configures the PCMCIA socket -- setting up
742 * the I/O windows and the interrupt mapping.
743 */
Dominik Brodowski2caff142009-10-24 15:53:36 +0200744 ret = pcmcia_request_configuration(link, &link->conf);
745 if (ret)
746 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747
748 /*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200749 * Allocate a 32K memory window. Note that the struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 * structure provides space for one window handle -- if your
751 * device needs several windows, you'll need to keep track of
752 * the handles in your private data structure, dev->priv.
753 */
Dominik Brodowski2caff142009-10-24 15:53:36 +0200754 dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755
756 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
757 req.Base = 0; req.Size = 0x8000;
758 req.AccessSpeed = mem_speed;
Dominik Brodowski6838b032009-11-03 01:31:52 +0100759 ret = pcmcia_request_window(link, &req, &link->win);
Dominik Brodowski2caff142009-10-24 15:53:36 +0200760 if (ret)
761 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 mem.CardOffset = 0x20000; mem.Page = 0;
Magnus Damm868575d2006-12-13 19:46:43 +0900763 ret = pcmcia_map_mem_page(link, link->win, &mem);
Dominik Brodowski2caff142009-10-24 15:53:36 +0200764 if (ret)
765 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
767 /* Store base address of the common window frame */
768 ramBase = ioremap(req.Base, 0x8000);
769 priv->ramBase = ramBase;
770
771 dev->irq = link->irq.AssignedIRQ;
772 dev->base_addr = link->io.BasePort1;
Dominik Brodowskidd2e5a12009-11-03 10:27:34 +0100773 SET_NETDEV_DEV(dev, &link->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774
775 if (register_netdev(dev) != 0) {
776 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
777 goto failed;
778 }
779
780 strcpy(priv->node.dev_name, dev->name);
Dominik Brodowskifd238232006-03-05 10:45:09 +0100781 link->dev_node = &priv->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782
783 /* Reset card before reading physical address */
784 netwave_doreset(dev->base_addr, ramBase);
785
786 /* Read the ethernet address and fill in the Netwave registers. */
787 for (i = 0; i < 6; i++)
788 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
789
Joe Perches8376e7a2007-11-19 17:48:27 -0800790 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
Johannes Berge1749612008-10-27 15:59:26 -0700791 "id %c%c, hw_addr %pM\n",
Joe Perches0795af52007-10-03 17:59:30 -0700792 dev->name, dev->base_addr, dev->irq,
793 (u_long) ramBase,
794 (int) readb(ramBase+NETWAVE_EREG_NI),
795 (int) readb(ramBase+NETWAVE_EREG_NI+1),
Johannes Berge1749612008-10-27 15:59:26 -0700796 dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
798 /* get revision words */
799 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
800 get_uint16(ramBase + NETWAVE_EREG_ARW),
801 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200802 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804failed:
805 netwave_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200806 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807} /* netwave_pcmcia_config */
808
809/*
810 * Function netwave_release (arg)
811 *
812 * After a card is removed, netwave_release() will unregister the net
813 * device, and release the PCMCIA configuration. If the device is
814 * still open, this will be postponed until it is closed.
815 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200816static void netwave_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100818 struct net_device *dev = link->priv;
819 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
Dominik Brodowski2caff142009-10-24 15:53:36 +0200821 dev_dbg(&link->dev, "netwave_release\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200823 pcmcia_disable_device(link);
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100824 if (link->win)
825 iounmap(priv->ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826}
827
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200828static int netwave_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100829{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100830 struct net_device *dev = link->priv;
831
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100832 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100833 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100834
835 return 0;
836}
837
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200838static int netwave_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100839{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100840 struct net_device *dev = link->priv;
841
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100842 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100843 netwave_reset(dev);
844 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100845 }
846
847 return 0;
848}
849
850
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 * Function netwave_doreset (ioBase, ramBase)
853 *
854 * Proper hardware reset of the card.
855 */
Olof Johansson906da802008-02-04 22:27:35 -0800856static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857{
858 /* Reset card */
859 wait_WOC(ioBase);
860 outb(0x80, ioBase + NETWAVE_REG_PMR);
861 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
862 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
863}
864
865/*
866 * Function netwave_reset (dev)
867 *
868 * Reset and restore all of the netwave registers
869 */
870static void netwave_reset(struct net_device *dev) {
871 /* u_char state; */
872 netwave_private *priv = netdev_priv(dev);
873 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800874 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Dominik Brodowski2caff142009-10-24 15:53:36 +0200876 pr_debug("netwave_reset: Done with hardware reset\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
878 priv->timeoutCounter = 0;
879
880 /* Reset card */
881 netwave_doreset(iobase, ramBase);
882 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
883
884 /* Write a NOP to check the card */
885 wait_WOC(iobase);
886 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
887 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
888
889 /* Set receive conf */
890 wait_WOC(iobase);
891 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
892 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
893 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
894
895 /* Set transmit conf */
896 wait_WOC(iobase);
897 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
898 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
899 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
900
901 /* Now set the MU Domain */
902 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
903 wait_WOC(iobase);
904 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
905 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
906 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
907 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
908
909 /* Set scramble key */
910 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
911 wait_WOC(iobase);
912 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
913 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
914 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
915 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
916
917 /* Enable interrupts, bit 4 high to keep unused
918 * source from interrupting us, bit 2 high to
919 * set interrupt enable, 567 to enable TxDN,
920 * RxErr and RxRdy
921 */
922 wait_WOC(iobase);
923 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
924
925 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
926 * waitWOC
927 * skriv 80 til d000:3688
928 * sjekk om det ble 80
929 */
930
931 /* Enable Receiver */
932 wait_WOC(iobase);
933 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
934 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
935
936 /* Set the IENA bit in COR */
937 wait_WOC(iobase);
938 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
939}
940
941/*
942 * Function netwave_hw_xmit (data, len, dev)
943 */
944static int netwave_hw_xmit(unsigned char* data, int len,
945 struct net_device* dev) {
946 unsigned long flags;
947 unsigned int TxFreeList,
948 curBuff,
949 MaxData,
950 DataOffset;
951 int tmpcount;
952
953 netwave_private *priv = netdev_priv(dev);
954 u_char __iomem * ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800955 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
957 /* Disable interrupts & save flags */
958 spin_lock_irqsave(&priv->spinlock, flags);
959
960 /* Check if there are transmit buffers available */
961 wait_WOC(iobase);
962 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
963 /* No buffers available */
964 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
965 dev->name);
966 spin_unlock_irqrestore(&priv->spinlock, flags);
967 return 1;
968 }
969
Stephen Hemmingerf56ef162009-03-20 19:36:21 +0000970 dev->stats.tx_bytes += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
Dominik Brodowski2caff142009-10-24 15:53:36 +0200972 pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 readb(ramBase + NETWAVE_EREG_SPCQ),
974 readb(ramBase + NETWAVE_EREG_SPU),
975 readb(ramBase + NETWAVE_EREG_LIF),
976 readb(ramBase + NETWAVE_EREG_ISPLQ));
977
978 /* Now try to insert it into the adapters free memory */
979 wait_WOC(iobase);
980 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
981 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
982 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
983
Dominik Brodowski2caff142009-10-24 15:53:36 +0200984 pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 TxFreeList, MaxData, DataOffset);
986
987 /* Copy packet to the adapter fragment buffers */
988 curBuff = TxFreeList;
989 tmpcount = 0;
990 while (tmpcount < len) {
991 int tmplen = len - tmpcount;
992 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
993 (tmplen < MaxData) ? tmplen : MaxData);
994 tmpcount += MaxData;
995
996 /* Advance to next buffer */
997 curBuff = get_uint16(ramBase + curBuff);
998 }
999
1000 /* Now issue transmit list */
1001 wait_WOC(iobase);
1002 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1003 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1004 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1005 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1006
1007 spin_unlock_irqrestore(&priv->spinlock, flags);
1008 return 0;
1009}
1010
Stephen Hemmingerd0cf9c02009-08-31 19:50:57 +00001011static netdev_tx_t netwave_start_xmit(struct sk_buff *skb,
1012 struct net_device *dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 /* This flag indicate that the hardware can't perform a transmission.
1014 * Theoritically, NET3 check it before sending a packet to the driver,
1015 * but in fact it never do that and pool continuously.
1016 * As the watchdog will abort too long transmissions, we are quite safe...
1017 */
1018
1019 netif_stop_queue(dev);
1020
1021 {
1022 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1023 unsigned char* buf = skb->data;
1024
1025 if (netwave_hw_xmit( buf, length, dev) == 1) {
1026 /* Some error, let's make them call us another time? */
1027 netif_start_queue(dev);
1028 }
1029 dev->trans_start = jiffies;
1030 }
1031 dev_kfree_skb(skb);
1032
Patrick McHardy6ed10652009-06-23 06:03:08 +00001033 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034} /* netwave_start_xmit */
1035
1036/*
David Howells7d12e782006-10-05 14:55:46 +01001037 * Function netwave_interrupt (irq, dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 *
1039 * This function is the interrupt handler for the Netwave card. This
1040 * routine will be called whenever:
1041 * 1. A packet is received.
1042 * 2. A packet has successfully been transferred and the unit is
1043 * ready to transmit another packet.
1044 * 3. A command has completed execution.
1045 */
David Howells7d12e782006-10-05 14:55:46 +01001046static irqreturn_t netwave_interrupt(int irq, void* dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047{
Olof Johansson906da802008-02-04 22:27:35 -08001048 unsigned int iobase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 u_char __iomem *ramBase;
1050 struct net_device *dev = (struct net_device *)dev_id;
1051 struct netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001052 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 int i;
1054
1055 if (!netif_device_present(dev))
1056 return IRQ_NONE;
1057
1058 iobase = dev->base_addr;
1059 ramBase = priv->ramBase;
1060
1061 /* Now find what caused the interrupt, check while interrupts ready */
1062 for (i = 0; i < 10; i++) {
1063 u_char status;
1064
1065 wait_WOC(iobase);
1066 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1067 break; /* None of the interrupt sources asserted (normal exit) */
1068
1069 status = inb(iobase + NETWAVE_REG_ASR);
1070
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001071 if (!pcmcia_dev_present(link)) {
Dominik Brodowski2caff142009-10-24 15:53:36 +02001072 pr_debug("netwave_interrupt: Interrupt with status 0x%x "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 "from removed or suspended card!\n", status);
1074 break;
1075 }
1076
1077 /* RxRdy */
1078 if (status & 0x80) {
1079 netwave_rx(dev);
1080 /* wait_WOC(iobase); */
1081 /* RxRdy cannot be reset directly by the host */
1082 }
1083 /* RxErr */
1084 if (status & 0x40) {
1085 u_char rser;
1086
1087 rser = readb(ramBase + NETWAVE_EREG_RSER);
1088
1089 if (rser & 0x04) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001090 ++dev->stats.rx_dropped;
1091 ++dev->stats.rx_crc_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 }
1093 if (rser & 0x02)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001094 ++dev->stats.rx_frame_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
1096 /* Clear the RxErr bit in RSER. RSER+4 is the
1097 * write part. Also clear the RxCRC (0x04) and
1098 * RxBig (0x02) bits if present */
1099 wait_WOC(iobase);
1100 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1101
1102 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1103 * WOC must be set first!
1104 */
1105 wait_WOC(iobase);
1106 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1107
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001108 /* Remember to count up dev->stats on error packets */
1109 ++dev->stats.rx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 }
1111 /* TxDN */
1112 if (status & 0x20) {
1113 int txStatus;
1114
1115 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
Dominik Brodowski2caff142009-10-24 15:53:36 +02001116 pr_debug("Transmit done. TSER = %x id %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1118
1119 if (txStatus & 0x20) {
1120 /* Transmitting was okay, clear bits */
1121 wait_WOC(iobase);
1122 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001123 ++dev->stats.tx_packets;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 }
1125
1126 if (txStatus & 0xd0) {
1127 if (txStatus & 0x80) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001128 ++dev->stats.collisions; /* Because of /proc/net/dev*/
1129 /* ++dev->stats.tx_aborted_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1131 }
1132 if (txStatus & 0x40)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001133 ++dev->stats.tx_carrier_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 /* 0x80 TxGU Transmit giveup - nine times and no luck
1135 * 0x40 TxNOAP No access point. Discarded packet.
1136 * 0x10 TxErr Transmit error. Always set when
1137 * TxGU and TxNOAP is set. (Those are the only ones
1138 * to set TxErr).
1139 */
Dominik Brodowski2caff142009-10-24 15:53:36 +02001140 pr_debug("netwave_interrupt: TxDN with error status %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 txStatus);
1142
1143 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1144 wait_WOC(iobase);
1145 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001146 ++dev->stats.tx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 }
Dominik Brodowski2caff142009-10-24 15:53:36 +02001148 pr_debug("New status is TSER %x ASR %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 readb(ramBase + NETWAVE_EREG_TSER),
1150 inb(iobase + NETWAVE_REG_ASR));
1151
1152 netif_wake_queue(dev);
1153 }
1154 /* TxBA, this would trigger on all error packets received */
1155 /* if (status & 0x01) {
Dominik Brodowski2caff142009-10-24 15:53:36 +02001156 pr_debug("Transmit buffers available, %x\n", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 }
1158 */
1159 }
1160 /* Handled if we looped at least one time - Jean II */
1161 return IRQ_RETVAL(i);
1162} /* netwave_interrupt */
1163
1164/*
1165 * Function netwave_watchdog (a)
1166 *
1167 * Watchdog : when we start a transmission, we set a timer in the
1168 * kernel. If the transmission complete, this timer is disabled. If
1169 * it expire, we reset the card.
1170 *
1171 */
1172static void netwave_watchdog(struct net_device *dev) {
1173
Dominik Brodowski2caff142009-10-24 15:53:36 +02001174 pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 netwave_reset(dev);
1176 dev->trans_start = jiffies;
1177 netif_wake_queue(dev);
1178} /* netwave_watchdog */
1179
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180static int netwave_rx(struct net_device *dev)
1181{
1182 netwave_private *priv = netdev_priv(dev);
1183 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -08001184 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 u_char rxStatus;
1186 struct sk_buff *skb = NULL;
1187 unsigned int curBuffer,
1188 rcvList;
1189 int rcvLen;
1190 int tmpcount = 0;
1191 int dataCount, dataOffset;
1192 int i;
1193 u_char *ptr;
1194
Dominik Brodowski2caff142009-10-24 15:53:36 +02001195 pr_debug("xinw_rx: Receiving ... \n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
1197 /* Receive max 10 packets for now. */
1198 for (i = 0; i < 10; i++) {
1199 /* Any packets? */
1200 wait_WOC(iobase);
1201 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1202 if ( !( rxStatus & 0x80)) /* No more packets */
1203 break;
1204
1205 /* Check if multicast/broadcast or other */
1206 /* multicast = (rxStatus & 0x20); */
1207
1208 /* The receive list pointer and length of the packet */
1209 wait_WOC(iobase);
1210 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1211 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1212
1213 if (rcvLen < 0) {
1214 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1215 rcvLen);
1216 return 0;
1217 }
1218
1219 skb = dev_alloc_skb(rcvLen+5);
1220 if (skb == NULL) {
Dominik Brodowski2caff142009-10-24 15:53:36 +02001221 pr_debug("netwave_rx: Could not allocate an sk_buff of "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 "length %d\n", rcvLen);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001223 ++dev->stats.rx_dropped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 /* Tell the adapter to skip the packet */
1225 wait_WOC(iobase);
1226 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1227 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1228 return 0;
1229 }
1230
1231 skb_reserve( skb, 2); /* Align IP on 16 byte */
1232 skb_put( skb, rcvLen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233
1234 /* Copy packet fragments to the skb data area */
1235 ptr = (u_char*) skb->data;
1236 curBuffer = rcvList;
1237 tmpcount = 0;
1238 while ( tmpcount < rcvLen) {
1239 /* Get length and offset of current buffer */
1240 dataCount = get_uint16( ramBase+curBuffer+2);
1241 dataOffset = get_uint16( ramBase+curBuffer+4);
1242
1243 copy_from_pc( ptr + tmpcount,
1244 ramBase+curBuffer+dataOffset, dataCount);
1245
1246 tmpcount += dataCount;
1247
1248 /* Point to next buffer */
1249 curBuffer = get_uint16(ramBase + curBuffer);
1250 }
1251
1252 skb->protocol = eth_type_trans(skb,dev);
1253 /* Queue packet for network layer */
1254 netif_rx(skb);
1255
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001256 dev->stats.rx_packets++;
1257 dev->stats.rx_bytes += rcvLen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258
1259 /* Got the packet, tell the adapter to skip it */
1260 wait_WOC(iobase);
1261 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1262 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
Dominik Brodowski2caff142009-10-24 15:53:36 +02001263 pr_debug("Packet reception ok\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 }
1265 return 0;
1266}
1267
1268static int netwave_open(struct net_device *dev) {
1269 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001270 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271
Dominik Brodowski2caff142009-10-24 15:53:36 +02001272 dev_dbg(&link->dev, "netwave_open: starting.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001274 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 return -ENODEV;
1276
1277 link->open++;
1278
1279 netif_start_queue(dev);
1280 netwave_reset(dev);
1281
1282 return 0;
1283}
1284
1285static int netwave_close(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
Dominik Brodowski2caff142009-10-24 15:53:36 +02001289 dev_dbg(&link->dev, "netwave_close: finishing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290
1291 link->open--;
1292 netif_stop_queue(dev);
1293
1294 return 0;
1295}
1296
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001297static struct pcmcia_device_id netwave_ids[] = {
1298 PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
1299 PCMCIA_DEVICE_NULL,
1300};
1301MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
1302
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303static struct pcmcia_driver netwave_driver = {
1304 .owner = THIS_MODULE,
1305 .drv = {
1306 .name = "netwave_cs",
1307 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001308 .probe = netwave_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001309 .remove = netwave_detach,
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001310 .id_table = netwave_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001311 .suspend = netwave_suspend,
1312 .resume = netwave_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313};
1314
1315static int __init init_netwave_cs(void)
1316{
1317 return pcmcia_register_driver(&netwave_driver);
1318}
1319
1320static void __exit exit_netwave_cs(void)
1321{
1322 pcmcia_unregister_driver(&netwave_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323}
1324
1325module_init(init_netwave_cs);
1326module_exit(exit_netwave_cs);
1327
1328/* Set or clear the multicast filter for this adaptor.
1329 num_addrs == -1 Promiscuous mode, receive all packets
1330 num_addrs == 0 Normal mode, clear multicast list
1331 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1332 best-effort filtering.
1333 */
1334static void set_multicast_list(struct net_device *dev)
1335{
Olof Johansson906da802008-02-04 22:27:35 -08001336 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 netwave_private *priv = netdev_priv(dev);
1338 u_char __iomem * ramBase = priv->ramBase;
1339 u_char rcvMode = 0;
1340
1341#ifdef PCMCIA_DEBUG
Dominik Brodowski2caff142009-10-24 15:53:36 +02001342 {
1343 xstatic int old;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 if (old != dev->mc_count) {
1345 old = dev->mc_count;
Dominik Brodowski2caff142009-10-24 15:53:36 +02001346 pr_debug("%s: setting Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 dev->name, dev->mc_count);
1348 }
1349 }
1350#endif
1351
1352 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1353 /* Multicast Mode */
1354 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1355 } else if (dev->flags & IFF_PROMISC) {
1356 /* Promiscous mode */
1357 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1358 } else {
1359 /* Normal mode */
1360 rcvMode = rxConfRxEna + rxConfBcast;
1361 }
1362
1363 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1364 /* Now set receive mode */
1365 wait_WOC(iobase);
1366 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1367 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1368 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1369}
1370MODULE_LICENSE("GPL");