blob: cbd85de0c601b4aaee6590fff23bfa79f59da874 [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 */
Alan Cox47cbb112008-09-23 13:53:09 +0100387 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
389 link->irq.Handler = &netwave_interrupt;
390
391 /* General socket configuration */
392 link->conf.Attributes = CONF_ENABLE_IRQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 link->conf.IntType = INT_MEMORY_AND_IO;
394 link->conf.ConfigIndex = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
396 /* Netwave private struct init. link/dev/node already taken care of,
397 * other stuff zero'd - Jean II */
398 spin_lock_init(&priv->spinlock);
399
400 /* Netwave specific entries in the device structure */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000401 dev->netdev_ops = &netwave_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 /* wireless extensions */
Stephen Hemminger1964e0d2009-03-20 19:36:22 +0000403 dev->wireless_handlers = &netwave_handler_def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 dev->watchdog_timeo = TX_TIMEOUT;
406
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 link->irq.Instance = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200409 return netwave_pcmcia_config( link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410} /* netwave_attach */
411
412/*
413 * Function netwave_detach (link)
414 *
415 * This deletes a driver "instance". The device is de-registered
416 * with Card Services. If it has been released, all local data
417 * structures are freed. Otherwise, the structures will be freed
418 * when the device is released.
419 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200420static void netwave_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421{
Dominik Brodowskib4635812005-11-14 21:25:35 +0100422 struct net_device *dev = link->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Dominik Brodowski2caff142009-10-24 15:53:36 +0200424 dev_dbg(&link->dev, "netwave_detach\n");
Dominik Brodowskicc3b4862005-11-14 21:23:14 +0100425
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100426 netwave_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
Dominik Brodowskifd238232006-03-05 10:45:09 +0100428 if (link->dev_node)
Dominik Brodowskib4635812005-11-14 21:25:35 +0100429 unregister_netdev(dev);
430
431 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432} /* netwave_detach */
433
434/*
435 * Wireless Handler : get protocol name
436 */
437static int netwave_get_name(struct net_device *dev,
438 struct iw_request_info *info,
439 union iwreq_data *wrqu,
440 char *extra)
441{
442 strcpy(wrqu->name, "Netwave");
443 return 0;
444}
445
446/*
447 * Wireless Handler : set Network ID
448 */
449static int netwave_set_nwid(struct net_device *dev,
450 struct iw_request_info *info,
451 union iwreq_data *wrqu,
452 char *extra)
453{
454 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800455 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 netwave_private *priv = netdev_priv(dev);
457 u_char __iomem *ramBase = priv->ramBase;
458
459 /* Disable interrupts & save flags */
460 spin_lock_irqsave(&priv->spinlock, flags);
461
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 if(!wrqu->nwid.disabled) {
463 domain = wrqu->nwid.value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
465 (domain >> 8) & 0x01, domain & 0xff);
466 wait_WOC(iobase);
467 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
468 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
469 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
470 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
471 }
472
473 /* ReEnable interrupts & restore flags */
474 spin_unlock_irqrestore(&priv->spinlock, flags);
475
476 return 0;
477}
478
479/*
480 * Wireless Handler : get Network ID
481 */
482static int netwave_get_nwid(struct net_device *dev,
483 struct iw_request_info *info,
484 union iwreq_data *wrqu,
485 char *extra)
486{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 wrqu->nwid.value = domain;
488 wrqu->nwid.disabled = 0;
489 wrqu->nwid.fixed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 return 0;
491}
492
493/*
494 * Wireless Handler : set scramble key
495 */
496static int netwave_set_scramble(struct net_device *dev,
497 struct iw_request_info *info,
498 union iwreq_data *wrqu,
499 char *key)
500{
501 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800502 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 netwave_private *priv = netdev_priv(dev);
504 u_char __iomem *ramBase = priv->ramBase;
505
506 /* Disable interrupts & save flags */
507 spin_lock_irqsave(&priv->spinlock, flags);
508
509 scramble_key = (key[0] << 8) | key[1];
510 wait_WOC(iobase);
511 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
512 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
513 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
514 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
515
516 /* ReEnable interrupts & restore flags */
517 spin_unlock_irqrestore(&priv->spinlock, flags);
518
519 return 0;
520}
521
522/*
523 * Wireless Handler : get scramble key
524 */
525static int netwave_get_scramble(struct net_device *dev,
526 struct iw_request_info *info,
527 union iwreq_data *wrqu,
528 char *key)
529{
530 key[1] = scramble_key & 0xff;
531 key[0] = (scramble_key>>8) & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 wrqu->encoding.flags = IW_ENCODE_ENABLED;
533 wrqu->encoding.length = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 return 0;
535}
536
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537/*
538 * Wireless Handler : get mode
539 */
540static int netwave_get_mode(struct net_device *dev,
541 struct iw_request_info *info,
542 union iwreq_data *wrqu,
543 char *extra)
544{
545 if(domain & 0x100)
546 wrqu->mode = IW_MODE_INFRA;
547 else
548 wrqu->mode = IW_MODE_ADHOC;
549
550 return 0;
551}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
553/*
554 * Wireless Handler : get range info
555 */
556static int netwave_get_range(struct net_device *dev,
557 struct iw_request_info *info,
558 union iwreq_data *wrqu,
559 char *extra)
560{
561 struct iw_range *range = (struct iw_range *) extra;
562 int ret = 0;
563
564 /* Set the length (very important for backward compatibility) */
565 wrqu->data.length = sizeof(struct iw_range);
566
567 /* Set all the info we don't care or don't know about to zero */
568 memset(range, 0, sizeof(struct iw_range));
569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 /* Set the Wireless Extension versions */
571 range->we_version_compiled = WIRELESS_EXT;
572 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
574 /* Set information in the range struct */
575 range->throughput = 450 * 1000; /* don't argue on this ! */
576 range->min_nwid = 0x0000;
577 range->max_nwid = 0x01FF;
578
579 range->num_channels = range->num_frequency = 0;
580
581 range->sensitivity = 0x3F;
582 range->max_qual.qual = 255;
583 range->max_qual.level = 255;
584 range->max_qual.noise = 0;
585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 range->num_bitrates = 1;
587 range->bitrate[0] = 1000000; /* 1 Mb/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 range->encoding_size[0] = 2; /* 16 bits scrambling */
590 range->num_encoding_sizes = 1;
591 range->max_encoding_tokens = 1; /* Only one key possible */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592
593 return ret;
594}
595
596/*
597 * Wireless Private Handler : get snapshot
598 */
599static int netwave_get_snap(struct net_device *dev,
600 struct iw_request_info *info,
601 union iwreq_data *wrqu,
602 char *extra)
603{
604 unsigned long flags;
Olof Johansson906da802008-02-04 22:27:35 -0800605 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 netwave_private *priv = netdev_priv(dev);
607 u_char __iomem *ramBase = priv->ramBase;
608
609 /* Disable interrupts & save flags */
610 spin_lock_irqsave(&priv->spinlock, flags);
611
612 /* Take snapshot of environment */
613 netwave_snapshot( priv, ramBase, iobase);
614 wrqu->data.length = priv->nss.length;
615 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
616
617 priv->lastExec = jiffies;
618
619 /* ReEnable interrupts & restore flags */
620 spin_unlock_irqrestore(&priv->spinlock, flags);
621
622 return(0);
623}
624
625/*
626 * Structures to export the Wireless Handlers
627 * This is the stuff that are treated the wireless extensions (iwconfig)
628 */
629
630static const struct iw_priv_args netwave_private_args[] = {
631/*{ cmd, set_args, get_args, name } */
632 { SIOCGIPSNAP, 0,
633 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
634 "getsitesurvey" },
635};
636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637static const iw_handler netwave_handler[] =
638{
639 NULL, /* SIOCSIWNAME */
640 netwave_get_name, /* SIOCGIWNAME */
641 netwave_set_nwid, /* SIOCSIWNWID */
642 netwave_get_nwid, /* SIOCGIWNWID */
643 NULL, /* SIOCSIWFREQ */
644 NULL, /* SIOCGIWFREQ */
645 NULL, /* SIOCSIWMODE */
646 netwave_get_mode, /* SIOCGIWMODE */
647 NULL, /* SIOCSIWSENS */
648 NULL, /* SIOCGIWSENS */
649 NULL, /* SIOCSIWRANGE */
650 netwave_get_range, /* SIOCGIWRANGE */
651 NULL, /* SIOCSIWPRIV */
652 NULL, /* SIOCGIWPRIV */
653 NULL, /* SIOCSIWSTATS */
654 NULL, /* SIOCGIWSTATS */
655 NULL, /* SIOCSIWSPY */
656 NULL, /* SIOCGIWSPY */
657 NULL, /* -- hole -- */
658 NULL, /* -- hole -- */
659 NULL, /* SIOCSIWAP */
660 NULL, /* SIOCGIWAP */
661 NULL, /* -- hole -- */
662 NULL, /* SIOCGIWAPLIST */
663 NULL, /* -- hole -- */
664 NULL, /* -- hole -- */
665 NULL, /* SIOCSIWESSID */
666 NULL, /* SIOCGIWESSID */
667 NULL, /* SIOCSIWNICKN */
668 NULL, /* SIOCGIWNICKN */
669 NULL, /* -- hole -- */
670 NULL, /* -- hole -- */
671 NULL, /* SIOCSIWRATE */
672 NULL, /* SIOCGIWRATE */
673 NULL, /* SIOCSIWRTS */
674 NULL, /* SIOCGIWRTS */
675 NULL, /* SIOCSIWFRAG */
676 NULL, /* SIOCGIWFRAG */
677 NULL, /* SIOCSIWTXPOW */
678 NULL, /* SIOCGIWTXPOW */
679 NULL, /* SIOCSIWRETRY */
680 NULL, /* SIOCGIWRETRY */
681 netwave_set_scramble, /* SIOCSIWENCODE */
682 netwave_get_scramble, /* SIOCGIWENCODE */
683};
684
685static const iw_handler netwave_private_handler[] =
686{
687 NULL, /* SIOCIWFIRSTPRIV */
688 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
689};
690
691static const struct iw_handler_def netwave_handler_def =
692{
Denis Chengff8ac602007-09-02 18:30:18 +0800693 .num_standard = ARRAY_SIZE(netwave_handler),
694 .num_private = ARRAY_SIZE(netwave_private_handler),
695 .num_private_args = ARRAY_SIZE(netwave_private_args),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 .standard = (iw_handler *) netwave_handler,
697 .private = (iw_handler *) netwave_private_handler,
698 .private_args = (struct iw_priv_args *) netwave_private_args,
Jean Tourrilhes62337dd2005-09-02 11:39:02 -0700699 .get_wireless_stats = netwave_get_wireless_stats,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
702/*
703 * Function netwave_pcmcia_config (link)
704 *
705 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
706 * event is received, to configure the PCMCIA socket, and to make the
707 * device available to the system.
708 *
709 */
710
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200711static int netwave_pcmcia_config(struct pcmcia_device *link) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 struct net_device *dev = link->priv;
713 netwave_private *priv = netdev_priv(dev);
Dominik Brodowski2caff142009-10-24 15:53:36 +0200714 int i, j, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 win_req_t req;
716 memreq_t mem;
717 u_char __iomem *ramBase = NULL;
718
Dominik Brodowski2caff142009-10-24 15:53:36 +0200719 dev_dbg(&link->dev, "netwave_pcmcia_config\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 * Try allocating IO ports. This tries a few fixed addresses.
723 * If you want, you can also read the card's config table to
724 * pick addresses -- see the serial driver for an example.
725 */
726 for (i = j = 0x0; j < 0x400; j += 0x20) {
727 link->io.BasePort1 = j ^ 0x300;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200728 i = pcmcia_request_io(link, &link->io);
Dominik Brodowski4c89e882008-08-03 10:07:45 +0200729 if (i == 0)
730 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 }
Dominik Brodowski2caff142009-10-24 15:53:36 +0200732 if (i != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
735 /*
736 * Now allocate an interrupt line. Note that this does not
737 * actually assign a handler to the interrupt.
738 */
Dominik Brodowski2caff142009-10-24 15:53:36 +0200739 ret = pcmcia_request_irq(link, &link->irq);
740 if (ret)
741 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742
743 /*
744 * This actually configures the PCMCIA socket -- setting up
745 * the I/O windows and the interrupt mapping.
746 */
Dominik Brodowski2caff142009-10-24 15:53:36 +0200747 ret = pcmcia_request_configuration(link, &link->conf);
748 if (ret)
749 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
751 /*
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200752 * Allocate a 32K memory window. Note that the struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 * structure provides space for one window handle -- if your
754 * device needs several windows, you'll need to keep track of
755 * the handles in your private data structure, dev->priv.
756 */
Dominik Brodowski2caff142009-10-24 15:53:36 +0200757 dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758
759 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
760 req.Base = 0; req.Size = 0x8000;
761 req.AccessSpeed = mem_speed;
Dominik Brodowski2caff142009-10-24 15:53:36 +0200762 ret = pcmcia_request_window(&link, &req, &link->win);
763 if (ret)
764 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 mem.CardOffset = 0x20000; mem.Page = 0;
Dominik Brodowski2caff142009-10-24 15:53:36 +0200766 ret = pcmcia_map_mem_page(link->win, &mem);
767 if (ret)
768 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769
770 /* Store base address of the common window frame */
771 ramBase = ioremap(req.Base, 0x8000);
772 priv->ramBase = ramBase;
773
774 dev->irq = link->irq.AssignedIRQ;
775 dev->base_addr = link->io.BasePort1;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200776 SET_NETDEV_DEV(dev, &handle_to_dev(link));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777
778 if (register_netdev(dev) != 0) {
779 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
780 goto failed;
781 }
782
783 strcpy(priv->node.dev_name, dev->name);
Dominik Brodowskifd238232006-03-05 10:45:09 +0100784 link->dev_node = &priv->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786 /* Reset card before reading physical address */
787 netwave_doreset(dev->base_addr, ramBase);
788
789 /* Read the ethernet address and fill in the Netwave registers. */
790 for (i = 0; i < 6; i++)
791 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
792
Joe Perches8376e7a2007-11-19 17:48:27 -0800793 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
Johannes Berge1749612008-10-27 15:59:26 -0700794 "id %c%c, hw_addr %pM\n",
Joe Perches0795af52007-10-03 17:59:30 -0700795 dev->name, dev->base_addr, dev->irq,
796 (u_long) ramBase,
797 (int) readb(ramBase+NETWAVE_EREG_NI),
798 (int) readb(ramBase+NETWAVE_EREG_NI+1),
Johannes Berge1749612008-10-27 15:59:26 -0700799 dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 /* get revision words */
802 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
803 get_uint16(ramBase + NETWAVE_EREG_ARW),
804 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200805 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807failed:
808 netwave_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200809 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810} /* netwave_pcmcia_config */
811
812/*
813 * Function netwave_release (arg)
814 *
815 * After a card is removed, netwave_release() will unregister the net
816 * device, and release the PCMCIA configuration. If the device is
817 * still open, this will be postponed until it is closed.
818 */
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200819static void netwave_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820{
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100821 struct net_device *dev = link->priv;
822 netwave_private *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
Dominik Brodowski2caff142009-10-24 15:53:36 +0200824 dev_dbg(&link->dev, "netwave_release\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200826 pcmcia_disable_device(link);
Dominik Brodowski5f2a71f2006-01-15 09:32:39 +0100827 if (link->win)
828 iounmap(priv->ramBase);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829}
830
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200831static int netwave_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100832{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100833 struct net_device *dev = link->priv;
834
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100835 if (link->open)
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100836 netif_device_detach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100837
838 return 0;
839}
840
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200841static int netwave_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100842{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100843 struct net_device *dev = link->priv;
844
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100845 if (link->open) {
Dominik Brodowski8661bb52006-03-02 00:02:33 +0100846 netwave_reset(dev);
847 netif_device_attach(dev);
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100848 }
849
850 return 0;
851}
852
853
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 * Function netwave_doreset (ioBase, ramBase)
856 *
857 * Proper hardware reset of the card.
858 */
Olof Johansson906da802008-02-04 22:27:35 -0800859static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860{
861 /* Reset card */
862 wait_WOC(ioBase);
863 outb(0x80, ioBase + NETWAVE_REG_PMR);
864 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
865 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
866}
867
868/*
869 * Function netwave_reset (dev)
870 *
871 * Reset and restore all of the netwave registers
872 */
873static void netwave_reset(struct net_device *dev) {
874 /* u_char state; */
875 netwave_private *priv = netdev_priv(dev);
876 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800877 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878
Dominik Brodowski2caff142009-10-24 15:53:36 +0200879 pr_debug("netwave_reset: Done with hardware reset\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880
881 priv->timeoutCounter = 0;
882
883 /* Reset card */
884 netwave_doreset(iobase, ramBase);
885 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
886
887 /* Write a NOP to check the card */
888 wait_WOC(iobase);
889 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
890 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
891
892 /* Set receive conf */
893 wait_WOC(iobase);
894 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
895 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
896 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
897
898 /* Set transmit conf */
899 wait_WOC(iobase);
900 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
901 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
902 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
903
904 /* Now set the MU Domain */
905 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
906 wait_WOC(iobase);
907 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
908 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
909 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
910 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
911
912 /* Set scramble key */
913 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
914 wait_WOC(iobase);
915 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
916 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
917 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
918 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
919
920 /* Enable interrupts, bit 4 high to keep unused
921 * source from interrupting us, bit 2 high to
922 * set interrupt enable, 567 to enable TxDN,
923 * RxErr and RxRdy
924 */
925 wait_WOC(iobase);
926 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
927
928 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
929 * waitWOC
930 * skriv 80 til d000:3688
931 * sjekk om det ble 80
932 */
933
934 /* Enable Receiver */
935 wait_WOC(iobase);
936 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
937 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
938
939 /* Set the IENA bit in COR */
940 wait_WOC(iobase);
941 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
942}
943
944/*
945 * Function netwave_hw_xmit (data, len, dev)
946 */
947static int netwave_hw_xmit(unsigned char* data, int len,
948 struct net_device* dev) {
949 unsigned long flags;
950 unsigned int TxFreeList,
951 curBuff,
952 MaxData,
953 DataOffset;
954 int tmpcount;
955
956 netwave_private *priv = netdev_priv(dev);
957 u_char __iomem * ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -0800958 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960 /* Disable interrupts & save flags */
961 spin_lock_irqsave(&priv->spinlock, flags);
962
963 /* Check if there are transmit buffers available */
964 wait_WOC(iobase);
965 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
966 /* No buffers available */
967 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
968 dev->name);
969 spin_unlock_irqrestore(&priv->spinlock, flags);
970 return 1;
971 }
972
Stephen Hemmingerf56ef162009-03-20 19:36:21 +0000973 dev->stats.tx_bytes += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
Dominik Brodowski2caff142009-10-24 15:53:36 +0200975 pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 readb(ramBase + NETWAVE_EREG_SPCQ),
977 readb(ramBase + NETWAVE_EREG_SPU),
978 readb(ramBase + NETWAVE_EREG_LIF),
979 readb(ramBase + NETWAVE_EREG_ISPLQ));
980
981 /* Now try to insert it into the adapters free memory */
982 wait_WOC(iobase);
983 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
984 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
985 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
986
Dominik Brodowski2caff142009-10-24 15:53:36 +0200987 pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 TxFreeList, MaxData, DataOffset);
989
990 /* Copy packet to the adapter fragment buffers */
991 curBuff = TxFreeList;
992 tmpcount = 0;
993 while (tmpcount < len) {
994 int tmplen = len - tmpcount;
995 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
996 (tmplen < MaxData) ? tmplen : MaxData);
997 tmpcount += MaxData;
998
999 /* Advance to next buffer */
1000 curBuff = get_uint16(ramBase + curBuff);
1001 }
1002
1003 /* Now issue transmit list */
1004 wait_WOC(iobase);
1005 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1006 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1007 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1008 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1009
1010 spin_unlock_irqrestore(&priv->spinlock, flags);
1011 return 0;
1012}
1013
Stephen Hemmingerd0cf9c02009-08-31 19:50:57 +00001014static netdev_tx_t netwave_start_xmit(struct sk_buff *skb,
1015 struct net_device *dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 /* This flag indicate that the hardware can't perform a transmission.
1017 * Theoritically, NET3 check it before sending a packet to the driver,
1018 * but in fact it never do that and pool continuously.
1019 * As the watchdog will abort too long transmissions, we are quite safe...
1020 */
1021
1022 netif_stop_queue(dev);
1023
1024 {
1025 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1026 unsigned char* buf = skb->data;
1027
1028 if (netwave_hw_xmit( buf, length, dev) == 1) {
1029 /* Some error, let's make them call us another time? */
1030 netif_start_queue(dev);
1031 }
1032 dev->trans_start = jiffies;
1033 }
1034 dev_kfree_skb(skb);
1035
Patrick McHardy6ed10652009-06-23 06:03:08 +00001036 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037} /* netwave_start_xmit */
1038
1039/*
David Howells7d12e782006-10-05 14:55:46 +01001040 * Function netwave_interrupt (irq, dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 *
1042 * This function is the interrupt handler for the Netwave card. This
1043 * routine will be called whenever:
1044 * 1. A packet is received.
1045 * 2. A packet has successfully been transferred and the unit is
1046 * ready to transmit another packet.
1047 * 3. A command has completed execution.
1048 */
David Howells7d12e782006-10-05 14:55:46 +01001049static irqreturn_t netwave_interrupt(int irq, void* dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050{
Olof Johansson906da802008-02-04 22:27:35 -08001051 unsigned int iobase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 u_char __iomem *ramBase;
1053 struct net_device *dev = (struct net_device *)dev_id;
1054 struct netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001055 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 int i;
1057
1058 if (!netif_device_present(dev))
1059 return IRQ_NONE;
1060
1061 iobase = dev->base_addr;
1062 ramBase = priv->ramBase;
1063
1064 /* Now find what caused the interrupt, check while interrupts ready */
1065 for (i = 0; i < 10; i++) {
1066 u_char status;
1067
1068 wait_WOC(iobase);
1069 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1070 break; /* None of the interrupt sources asserted (normal exit) */
1071
1072 status = inb(iobase + NETWAVE_REG_ASR);
1073
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001074 if (!pcmcia_dev_present(link)) {
Dominik Brodowski2caff142009-10-24 15:53:36 +02001075 pr_debug("netwave_interrupt: Interrupt with status 0x%x "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 "from removed or suspended card!\n", status);
1077 break;
1078 }
1079
1080 /* RxRdy */
1081 if (status & 0x80) {
1082 netwave_rx(dev);
1083 /* wait_WOC(iobase); */
1084 /* RxRdy cannot be reset directly by the host */
1085 }
1086 /* RxErr */
1087 if (status & 0x40) {
1088 u_char rser;
1089
1090 rser = readb(ramBase + NETWAVE_EREG_RSER);
1091
1092 if (rser & 0x04) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001093 ++dev->stats.rx_dropped;
1094 ++dev->stats.rx_crc_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 }
1096 if (rser & 0x02)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001097 ++dev->stats.rx_frame_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
1099 /* Clear the RxErr bit in RSER. RSER+4 is the
1100 * write part. Also clear the RxCRC (0x04) and
1101 * RxBig (0x02) bits if present */
1102 wait_WOC(iobase);
1103 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1104
1105 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1106 * WOC must be set first!
1107 */
1108 wait_WOC(iobase);
1109 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1110
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001111 /* Remember to count up dev->stats on error packets */
1112 ++dev->stats.rx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 }
1114 /* TxDN */
1115 if (status & 0x20) {
1116 int txStatus;
1117
1118 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
Dominik Brodowski2caff142009-10-24 15:53:36 +02001119 pr_debug("Transmit done. TSER = %x id %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1121
1122 if (txStatus & 0x20) {
1123 /* Transmitting was okay, clear bits */
1124 wait_WOC(iobase);
1125 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001126 ++dev->stats.tx_packets;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 }
1128
1129 if (txStatus & 0xd0) {
1130 if (txStatus & 0x80) {
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001131 ++dev->stats.collisions; /* Because of /proc/net/dev*/
1132 /* ++dev->stats.tx_aborted_errors; */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1134 }
1135 if (txStatus & 0x40)
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001136 ++dev->stats.tx_carrier_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 /* 0x80 TxGU Transmit giveup - nine times and no luck
1138 * 0x40 TxNOAP No access point. Discarded packet.
1139 * 0x10 TxErr Transmit error. Always set when
1140 * TxGU and TxNOAP is set. (Those are the only ones
1141 * to set TxErr).
1142 */
Dominik Brodowski2caff142009-10-24 15:53:36 +02001143 pr_debug("netwave_interrupt: TxDN with error status %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 txStatus);
1145
1146 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1147 wait_WOC(iobase);
1148 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001149 ++dev->stats.tx_errors;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 }
Dominik Brodowski2caff142009-10-24 15:53:36 +02001151 pr_debug("New status is TSER %x ASR %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 readb(ramBase + NETWAVE_EREG_TSER),
1153 inb(iobase + NETWAVE_REG_ASR));
1154
1155 netif_wake_queue(dev);
1156 }
1157 /* TxBA, this would trigger on all error packets received */
1158 /* if (status & 0x01) {
Dominik Brodowski2caff142009-10-24 15:53:36 +02001159 pr_debug("Transmit buffers available, %x\n", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 }
1161 */
1162 }
1163 /* Handled if we looped at least one time - Jean II */
1164 return IRQ_RETVAL(i);
1165} /* netwave_interrupt */
1166
1167/*
1168 * Function netwave_watchdog (a)
1169 *
1170 * Watchdog : when we start a transmission, we set a timer in the
1171 * kernel. If the transmission complete, this timer is disabled. If
1172 * it expire, we reset the card.
1173 *
1174 */
1175static void netwave_watchdog(struct net_device *dev) {
1176
Dominik Brodowski2caff142009-10-24 15:53:36 +02001177 pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 netwave_reset(dev);
1179 dev->trans_start = jiffies;
1180 netif_wake_queue(dev);
1181} /* netwave_watchdog */
1182
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183static int netwave_rx(struct net_device *dev)
1184{
1185 netwave_private *priv = netdev_priv(dev);
1186 u_char __iomem *ramBase = priv->ramBase;
Olof Johansson906da802008-02-04 22:27:35 -08001187 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 u_char rxStatus;
1189 struct sk_buff *skb = NULL;
1190 unsigned int curBuffer,
1191 rcvList;
1192 int rcvLen;
1193 int tmpcount = 0;
1194 int dataCount, dataOffset;
1195 int i;
1196 u_char *ptr;
1197
Dominik Brodowski2caff142009-10-24 15:53:36 +02001198 pr_debug("xinw_rx: Receiving ... \n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
1200 /* Receive max 10 packets for now. */
1201 for (i = 0; i < 10; i++) {
1202 /* Any packets? */
1203 wait_WOC(iobase);
1204 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1205 if ( !( rxStatus & 0x80)) /* No more packets */
1206 break;
1207
1208 /* Check if multicast/broadcast or other */
1209 /* multicast = (rxStatus & 0x20); */
1210
1211 /* The receive list pointer and length of the packet */
1212 wait_WOC(iobase);
1213 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1214 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1215
1216 if (rcvLen < 0) {
1217 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1218 rcvLen);
1219 return 0;
1220 }
1221
1222 skb = dev_alloc_skb(rcvLen+5);
1223 if (skb == NULL) {
Dominik Brodowski2caff142009-10-24 15:53:36 +02001224 pr_debug("netwave_rx: Could not allocate an sk_buff of "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 "length %d\n", rcvLen);
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001226 ++dev->stats.rx_dropped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 /* Tell the adapter to skip the packet */
1228 wait_WOC(iobase);
1229 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1230 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1231 return 0;
1232 }
1233
1234 skb_reserve( skb, 2); /* Align IP on 16 byte */
1235 skb_put( skb, rcvLen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236
1237 /* Copy packet fragments to the skb data area */
1238 ptr = (u_char*) skb->data;
1239 curBuffer = rcvList;
1240 tmpcount = 0;
1241 while ( tmpcount < rcvLen) {
1242 /* Get length and offset of current buffer */
1243 dataCount = get_uint16( ramBase+curBuffer+2);
1244 dataOffset = get_uint16( ramBase+curBuffer+4);
1245
1246 copy_from_pc( ptr + tmpcount,
1247 ramBase+curBuffer+dataOffset, dataCount);
1248
1249 tmpcount += dataCount;
1250
1251 /* Point to next buffer */
1252 curBuffer = get_uint16(ramBase + curBuffer);
1253 }
1254
1255 skb->protocol = eth_type_trans(skb,dev);
1256 /* Queue packet for network layer */
1257 netif_rx(skb);
1258
Stephen Hemmingerf56ef162009-03-20 19:36:21 +00001259 dev->stats.rx_packets++;
1260 dev->stats.rx_bytes += rcvLen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261
1262 /* Got the packet, tell the adapter to skip it */
1263 wait_WOC(iobase);
1264 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1265 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
Dominik Brodowski2caff142009-10-24 15:53:36 +02001266 pr_debug("Packet reception ok\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 }
1268 return 0;
1269}
1270
1271static int netwave_open(struct net_device *dev) {
1272 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001273 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
Dominik Brodowski2caff142009-10-24 15:53:36 +02001275 dev_dbg(&link->dev, "netwave_open: starting.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276
Dominik Brodowski9940ec32006-03-05 11:04:33 +01001277 if (!pcmcia_dev_present(link))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 return -ENODEV;
1279
1280 link->open++;
1281
1282 netif_start_queue(dev);
1283 netwave_reset(dev);
1284
1285 return 0;
1286}
1287
1288static int netwave_close(struct net_device *dev) {
1289 netwave_private *priv = netdev_priv(dev);
Dominik Brodowskifba395e2006-03-31 17:21:06 +02001290 struct pcmcia_device *link = priv->p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
Dominik Brodowski2caff142009-10-24 15:53:36 +02001292 dev_dbg(&link->dev, "netwave_close: finishing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293
1294 link->open--;
1295 netif_stop_queue(dev);
1296
1297 return 0;
1298}
1299
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001300static struct pcmcia_device_id netwave_ids[] = {
1301 PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
1302 PCMCIA_DEVICE_NULL,
1303};
1304MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
1305
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306static struct pcmcia_driver netwave_driver = {
1307 .owner = THIS_MODULE,
1308 .drv = {
1309 .name = "netwave_cs",
1310 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +02001311 .probe = netwave_probe,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001312 .remove = netwave_detach,
Dominik Brodowski5d402e92005-06-27 16:28:23 -07001313 .id_table = netwave_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01001314 .suspend = netwave_suspend,
1315 .resume = netwave_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316};
1317
1318static int __init init_netwave_cs(void)
1319{
1320 return pcmcia_register_driver(&netwave_driver);
1321}
1322
1323static void __exit exit_netwave_cs(void)
1324{
1325 pcmcia_unregister_driver(&netwave_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326}
1327
1328module_init(init_netwave_cs);
1329module_exit(exit_netwave_cs);
1330
1331/* Set or clear the multicast filter for this adaptor.
1332 num_addrs == -1 Promiscuous mode, receive all packets
1333 num_addrs == 0 Normal mode, clear multicast list
1334 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1335 best-effort filtering.
1336 */
1337static void set_multicast_list(struct net_device *dev)
1338{
Olof Johansson906da802008-02-04 22:27:35 -08001339 unsigned int iobase = dev->base_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 netwave_private *priv = netdev_priv(dev);
1341 u_char __iomem * ramBase = priv->ramBase;
1342 u_char rcvMode = 0;
1343
1344#ifdef PCMCIA_DEBUG
Dominik Brodowski2caff142009-10-24 15:53:36 +02001345 {
1346 xstatic int old;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 if (old != dev->mc_count) {
1348 old = dev->mc_count;
Dominik Brodowski2caff142009-10-24 15:53:36 +02001349 pr_debug("%s: setting Rx mode to %d addresses.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 dev->name, dev->mc_count);
1351 }
1352 }
1353#endif
1354
1355 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1356 /* Multicast Mode */
1357 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1358 } else if (dev->flags & IFF_PROMISC) {
1359 /* Promiscous mode */
1360 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1361 } else {
1362 /* Normal mode */
1363 rcvMode = rxConfRxEna + rxConfBcast;
1364 }
1365
1366 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1367 /* Now set receive mode */
1368 wait_WOC(iobase);
1369 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1370 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1371 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1372}
1373MODULE_LICENSE("GPL");