File: /usr/src/linux/drivers/net/wireless/orinoco.c
1 /* orinoco.c 0.07 - (formerly known as dldwd_cs.c and orinoco_cs.c)
2 *
3 * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
4 * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
5 * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
6 * It should also be usable on various Prism II based cards such as the
7 * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
8 * cards such as the 3Com AirConnect and Ericsson WLAN.
9 *
10 * Copyright (C) 2000 David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
11 * With some help from :
12 * Copyright (C) 2001 Jean Tourrilhes, HP Labs <jt@hpl.hp.com>
13 * Copyright (C) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
14 *
15 * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
16 *
17 * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy@fasta.fh-dortmund.de>
18 * http://www.fasta.fh-dortmund.de/users/andy/wvlan/
19 *
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License
23 * at http://www.mozilla.org/MPL/
24 *
25 * Software distributed under the License is distributed on an "AS IS"
26 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
27 * the License for the specific language governing rights and
28 * limitations under the License.
29 *
30 * The initial developer of the original code is David A. Hinds
31 * <dahinds@users.sourceforge.net>. Portions created by David
32 * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
33 * Reserved.
34 *
35 * Alternatively, the contents of this file may be used under the
36 * terms of the GNU General Public License version 2 (the "GPL"), in
37 * which case the provisions of the GPL are applicable instead of the
38 * above. If you wish to allow the use of your version of this file
39 * only under the terms of the GPL and not to allow others to use your
40 * version of this file under the MPL, indicate your decision by
41 * deleting the provisions above and replace them with the notice and
42 * other provisions required by the GPL. If you do not delete the
43 * provisions above, a recipient may use your version of this file
44 * under either the MPL or the GPL.
45 */
46
47 /* Notes on locking:
48 *
49 * The basic principle of operation is that everything except the
50 * interrupt handler is serialized through a single spinlock in the
51 * dldwd_priv_t structure, using dldwd_lock() and
52 * dldwd_unlock() (which in turn use spin_lock_bh() and spin_unlock_bh()).
53 *
54 * The kernel's IRQ handling stuff ensures that the interrupt handler
55 * does not re-enter itself. The interrupt handler is written such
56 * that everything it does is safe without a lock: chiefly this means
57 * that the Rx path uses one of the Hermes chipset's BAPs while
58 * everything else uses the other.
59 *
60 * For the moment access to the device statistics from the interrupt
61 * handler is unsafe - we just put up with any resulting errors in the
62 * statisics. FIXME: This should probably be changed to store the
63 * stats in atomic types.
64 *
65 * EXCEPT that we don't want the irq handler running when we actually
66 * reset or shut down the card, because strange things might happen
67 * (probably the worst would be one packet of garbage, but you can't
68 * be too careful). For this we use __dldwd_stop_irqs() which will set
69 * a flag to disable the interrupt handler, and wait for any
70 * outstanding instances of the handler to complete. THIS WILL LOSE
71 * INTERRUPTS! so it shouldn't be used except for resets, when we
72 * don't care about that.*/
73
74 /*
75 * Tentative changelog...
76 *
77 * v0.01 -> v0.02 - 21/3/2001 - Jean II
78 * o Allow to use regular ethX device name instead of dldwdX
79 * o Warning on IBSS with ESSID=any for firmware 6.06
80 * o Put proper range.throughput values (optimistic)
81 * o IWSPY support (IOCTL and stat gather in Rx path)
82 * o Allow setting frequency in Ad-Hoc mode
83 * o Disable WEP setting if !has_wep to work on old firmware
84 * o Fix txpower range
85 * o Start adding support for Samsung/Compaq firmware
86 *
87 * v0.02 -> v0.03 - 23/3/2001 - Jean II
88 * o Start adding Symbol support - need to check all that
89 * o Fix Prism2/Symbol WEP to accept 128 bits keys
90 * o Add Symbol WEP (add authentication type)
91 * o Add Prism2/Symbol rate
92 * o Add PM timeout (holdover duration)
93 * o Enable "iwconfig eth0 key off" and friends (toggle flags)
94 * o Enable "iwconfig eth0 power unicast/all" (toggle flags)
95 * o Try with an intel card. It report firmware 1.01, behave like
96 * an antiquated firmware, however on windows it says 2.00. Yuck !
97 * o Workaround firmware bug in allocate buffer (Intel 1.01)
98 * o Finish external renaming to orinoco...
99 * o Testing with various Wavelan firmwares
100 *
101 * v0.03 -> v0.04 - 30/3/2001 - Jean II
102 * o Update to Wireless 11 -> add retry limit/lifetime support
103 * o Tested with a D-Link DWL 650 card, fill in firmware support
104 * o Warning on Vcc mismatch (D-Link 3.3v card in Lucent 5v only slot)
105 * o Fixed the Prims2 WEP bugs that I introduced in v0.03 :-(
106 * It work on D-Link *only* after a tcpdump. Weird...
107 * And still doesn't work on Intel card. Grrrr...
108 * o Update the mode after a setport3
109 * o Add preamble setting for Symbol cards (not yet enabled)
110 * o Don't complain as much about Symbol cards...
111 *
112 * v0.04 -> v0.04b - 22/4/2001 - David Gibson
113 * o Removed the 'eth' parameter - always use ethXX as the
114 * interface name instead of dldwdXX. The other was racy
115 * anyway.
116 * o Clean up RID definitions in hermes.h, other cleanups
117 *
118 * v0.04b -> v0.04c - 24/4/2001 - Jean II
119 * o Tim Hurley <timster@seiki.bliztech.com> reported a D-Link card
120 * with vendor 02 and firmware 0.08. Added in the capabilities...
121 * o Tested Lucent firmware 7.28, everything works...
122 *
123 * v0.04c -> v0.05 - 3/5/2001 - Benjamin Herrenschmidt
124 * o Spin-off Pcmcia code. This file is renamed orinoco.c,
125 * and orinoco_cs.c now contains only the Pcmcia specific stuff
126 * o Add Airport driver support on top of orinoco.c (see airport.c)
127 *
128 * v0.05 -> v0.05a - 4/5/2001 - Jean II
129 * o Revert to old Pcmcia code to fix breakage of Ben's changes...
130 *
131 * v0.05a -> v0.05b - 4/5/2001 - Jean II
132 * o add module parameter 'ignore_cis_vcc' for D-Link @ 5V
133 * o D-Link firmware doesn't support multicast. We just print a few
134 * error messages, but otherwise everything works...
135 * o For David : set/getport3 works fine, just upgrade iwpriv...
136 *
137 * v0.05b -> v0.05c - 5/5/2001 - Benjamin Herrenschmidt
138 * o Adapt airport.c to latest changes in orinoco.c
139 * o Remove deferred power enabling code
140 *
141 * v0.05c -> v0.05d - 5/5/2001 - Jean II
142 * o Workaround to SNAP decapsulate frame from LinkSys AP
143 * original patch from : Dong Liu <dliu@research.bell-labs.com>
144 * (note : the memcmp bug was mine - fixed)
145 * o Remove set_retry stuff, no firmware support it (bloat--).
146 *
147 * v0.05d -> v0.06 - 25/5/2001 - Jean II
148 * Original patch from "Hong Lin" <alin@redhat.com>,
149 * "Ian Kinner" <ikinner@redhat.com>
150 * and "David Smith" <dsmith@redhat.com>
151 * o Init of priv->tx_rate_ctrl in firmware specific section.
152 * o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
153 * o Spectrum card always need cor_reset (for every reset)
154 * o Fix cor_reset to not loose bit 7 in the register
155 * o flush_stale_links to remove zombie Pcmcia instances
156 * o Ack previous hermes event before reset
157 * Me (with my little hands)
158 * o Allow orinoco.c to call cor_reset via priv->card_reset_handler
159 * o Add priv->need_card_reset to toggle this feature
160 * o Fix various buglets when setting WEP in Symbol firmware
161 * Now, encryption is fully functional on Symbol cards. Youpi !
162 *
163 * v0.06 -> v0.06b - 25/5/2001 - Jean II
164 * o IBSS on Symbol use port_mode = 4. Please don't ask...
165 *
166 * v0.06b -> v0.06c - 29/5/2001 - Jean II
167 * o Show first spy address in /proc/net/wireless for IBSS mode as well
168 *
169 * v0.06c -> v0.06d - 6/7/2001 - David Gibson
170 * o Change a bunch of KERN_INFO messages to KERN_DEBUG, as per Linus'
171 * wishes to reduce the number of unecessary messages.
172 * o Removed bogus message on CRC error.
173 * o Merged fixeds for v0.08 Prism 2 firmware from William Waghorn
174 * <willwaghorn@yahoo.co.uk>
175 * o Slight cleanup/re-arrangement of firmware detection code.
176 *
177 * v0.06d -> v0.06e - 1/8/2001 - David Gibson
178 * o Removed some redundant global initializers (orinoco_cs.c).
179 * o Added some module metadataa
180 *
181 * v0.06e -> v0.06f - 14/8/2001 - David Gibson
182 * o Wording fix to license
183 * o Added a 'use_alternate_encaps' module parameter for APs which need an oui of
184 * 00:00:00. We really need a better way of handling this, but the module flag
185 * is better than nothing for now.
186 *
187 * v0.06f -> v0.07 - 20/8/2001 - David Gibson
188 * o Removed BAP error retries from hermes_bap_seek(). For Tx we now
189 * let the upper layers handle the retry, we retry explicitly in the
190 * Rx path, but don't make as much noise about it.
191 * o Firmware detection cleanups.
192 *
193 *
194 * TODO - Jean II
195 * o inline functions (lot's of candidate, need to reorder code)
196 * o Test PrismII/Symbol cards & firmware versions
197 * o Mini-PCI support (some people have reported success - JII)
198 */
199
200 #include <linux/module.h>
201 #include <linux/kernel.h>
202 #include <linux/init.h>
203 #include <linux/sched.h>
204 #include <linux/ptrace.h>
205 #include <linux/slab.h>
206 #include <linux/string.h>
207 #include <linux/timer.h>
208 #include <linux/ioport.h>
209 #include <asm/uaccess.h>
210 #include <asm/io.h>
211 #include <asm/system.h>
212 #include <linux/proc_fs.h>
213 #include <linux/netdevice.h>
214 #include <linux/if_arp.h>
215 #include <linux/etherdevice.h>
216 #include <linux/wireless.h>
217 #include <linux/list.h>
218
219 #include <pcmcia/version.h>
220 #include <pcmcia/cs_types.h>
221 #include <pcmcia/cs.h>
222 #include <pcmcia/cistpl.h>
223 #include <pcmcia/cisreg.h>
224 #include <pcmcia/ds.h>
225 #include <pcmcia/bus_ops.h>
226
227 #include "hermes.h"
228 #include "orinoco.h"
229
230 static char version[] __initdata = "orinoco.c 0.07 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
231 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
232 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
233 MODULE_LICENSE("Dual MPL/GPL");
234
235 /* Level of debugging. Used in the macros in orinoco.h */
236 #ifdef ORINOCO_DEBUG
237 int dldwd_debug = ORINOCO_DEBUG;
238 MODULE_PARM(dldwd_debug, "i");
239 #endif
240
241 /* FIXME: We need a better way of handling this */
242 /* Set this flag to use 00:00:00 for the encapsulation oui instead of 00:00:F8 */
243 static int use_alternate_encaps; /* =0 */
244 MODULE_PARM(use_alternate_encaps, "i");
245
246 const long channel_frequency[] = {
247 2412, 2417, 2422, 2427, 2432, 2437, 2442,
248 2447, 2452, 2457, 2462, 2467, 2472, 2484
249 };
250
251 #define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
252
253 /* This tables gives the actual meanings of the bitrate IDs returned by the firmware.
254 It gives the rate in halfMb/s, negative indicates auto mode */
255 const int rate_list[] = { 0, 2, 4, -22, 11, 22, -4, -11, 0, 0, 0, 0};
256
257 #define NUM_RATES (sizeof(rate_list) / sizeof(rate_list[0]))
258
259 struct p80211_hdr {
260 uint16_t frame_ctl;
261 uint16_t duration_id;
262 uint8_t addr1[ETH_ALEN];
263 uint8_t addr2[ETH_ALEN];
264 uint8_t addr3[ETH_ALEN];
265 uint16_t seq_ctl;
266 uint8_t addr4[ETH_ALEN];
267 uint16_t data_len;
268 } __attribute__ ((packed));
269
270 /* Frame control field constants */
271 #define DLDWD_FCTL_VERS 0x0002
272 #define DLDWD_FCTL_FTYPE 0x000c
273 #define DLDWD_FCTL_STYPE 0x00f0
274 #define DLDWD_FCTL_TODS 0x0100
275 #define DLDWD_FCTL_FROMDS 0x0200
276 #define DLDWD_FCTL_MOREFRAGS 0x0400
277 #define DLDWD_FCTL_RETRY 0x0800
278 #define DLDWD_FCTL_PM 0x1000
279 #define DLDWD_FCTL_MOREDATA 0x2000
280 #define DLDWD_FCTL_WEP 0x4000
281 #define DLDWD_FCTL_ORDER 0x8000
282
283 #define DLDWD_FTYPE_MGMT 0x0000
284 #define DLDWD_FTYPE_CTL 0x0004
285 #define DLDWD_FTYPE_DATA 0x0008
286
287 #define __PACKED__ __attribute__ ((packed))
288
289 struct p8022_hdr {
290 uint8_t dsap __PACKED__;
291 uint8_t ssap __PACKED__;
292 uint8_t ctrl __PACKED__;
293 uint8_t oui[3] __PACKED__;
294 };
295
296 struct dldwd_frame_hdr {
297 hermes_frame_desc_t desc __PACKED__;
298 struct p80211_hdr p80211 __PACKED__;
299 struct ethhdr p8023 __PACKED__;
300 struct p8022_hdr p8022 __PACKED__;
301 uint16_t ethertype __PACKED__;
302 };
303
304 #define P8023_OFFSET (sizeof(hermes_frame_desc_t) + \
305 sizeof(struct p80211_hdr))
306 #define ENCAPS_OVERHEAD (sizeof(struct p8022_hdr) + 2)
307
308 /* 802.2 LLL header SNAP used for SNAP encapsulation over 802.11 */
309 struct p8022_hdr encaps_hdr = {
310 0xaa, 0xaa, 0x03, {0x00, 0x00, 0xf8}
311 };
312 struct p8022_hdr alternate_encaps_hdr = {
313 0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}
314 };
315
316 /* How many times to retry if we get an EIO reading the BAP in the Rx path */
317 #define RX_EIO_RETRY 10
318
319 typedef struct dldwd_commsqual {
320 uint16_t qual, signal, noise;
321 } __PACKED__ dldwd_commsqual_t;
322
323
324 /*
325 * Function prototypes
326 */
327
328 static void dldwd_stat_gather(struct net_device *dev,
329 struct sk_buff *skb,
330 struct dldwd_frame_hdr *hdr);
331
332 static struct net_device_stats *dldwd_get_stats(struct net_device *dev);
333 static struct iw_statistics *dldwd_get_wireless_stats(struct net_device *dev);
334
335 /* Hardware control routines */
336
337 static int __dldwd_hw_reset(dldwd_priv_t *priv);
338 static int __dldwd_hw_setup_wep(dldwd_priv_t *priv);
339 static int dldwd_hw_get_bssid(dldwd_priv_t *priv, char buf[ETH_ALEN]);
340 static int dldwd_hw_get_essid(dldwd_priv_t *priv, int *active, char buf[IW_ESSID_MAX_SIZE+1]);
341 static long dldwd_hw_get_freq(dldwd_priv_t *priv);
342 static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,
343 int32_t *rates, int max);
344
345 /* Interrupt handling routines */
346 static void __dldwd_ev_tick(dldwd_priv_t *priv, hermes_t *hw);
347 static void __dldwd_ev_wterr(dldwd_priv_t *priv, hermes_t *hw);
348 static void __dldwd_ev_infdrop(dldwd_priv_t *priv, hermes_t *hw);
349 static void __dldwd_ev_info(dldwd_priv_t *priv, hermes_t *hw);
350 static void __dldwd_ev_rx(dldwd_priv_t *priv, hermes_t *hw);
351 static void __dldwd_ev_txexc(dldwd_priv_t *priv, hermes_t *hw);
352 static void __dldwd_ev_tx(dldwd_priv_t *priv, hermes_t *hw);
353 static void __dldwd_ev_alloc(dldwd_priv_t *priv, hermes_t *hw);
354
355 static int dldwd_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq);
356 static int dldwd_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq);
357 static int dldwd_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq);
358 static int dldwd_ioctl_setessid(struct net_device *dev, struct iw_point *erq);
359 static int dldwd_ioctl_getessid(struct net_device *dev, struct iw_point *erq);
360 static int dldwd_ioctl_setnick(struct net_device *dev, struct iw_point *nrq);
361 static int dldwd_ioctl_getnick(struct net_device *dev, struct iw_point *nrq);
362 static int dldwd_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq);
363 static int dldwd_ioctl_getsens(struct net_device *dev, struct iw_param *srq);
364 static int dldwd_ioctl_setsens(struct net_device *dev, struct iw_param *srq);
365 static int dldwd_ioctl_setrts(struct net_device *dev, struct iw_param *rrq);
366 static int dldwd_ioctl_setfrag(struct net_device *dev, struct iw_param *frq);
367 static int dldwd_ioctl_getfrag(struct net_device *dev, struct iw_param *frq);
368 static int dldwd_ioctl_setrate(struct net_device *dev, struct iw_param *frq);
369 static int dldwd_ioctl_getrate(struct net_device *dev, struct iw_param *frq);
370 static int dldwd_ioctl_setpower(struct net_device *dev, struct iw_param *prq);
371 static int dldwd_ioctl_getpower(struct net_device *dev, struct iw_param *prq);
372 static int dldwd_ioctl_setport3(struct net_device *dev, struct iwreq *wrq);
373 static int dldwd_ioctl_getport3(struct net_device *dev, struct iwreq *wrq);
374 static void __dldwd_set_multicast_list(struct net_device *dev);
375
376 /* /proc debugging stuff */
377 static int dldwd_proc_init(void);
378 static void dldwd_proc_cleanup(void);
379
380 /*
381 * Inline functions
382 */
383 static inline void
384 dldwd_lock(dldwd_priv_t *priv)
385 {
386 spin_lock_bh(&priv->lock);
387 }
388
389 static inline void
390 dldwd_unlock(dldwd_priv_t *priv)
391 {
392 spin_unlock_bh(&priv->lock);
393 }
394
395 static inline int
396 dldwd_irqs_allowed(dldwd_priv_t *priv)
397 {
398 return test_bit(DLDWD_STATE_DOIRQ, &priv->state);
399 }
400
401 static inline void
402 __dldwd_stop_irqs(dldwd_priv_t *priv)
403 {
404 hermes_t *hw = &priv->hw;
405
406 hermes_set_irqmask(hw, 0);
407 clear_bit(DLDWD_STATE_DOIRQ, &priv->state);
408 while (test_bit(DLDWD_STATE_INIRQ, &priv->state))
409 ;
410 }
411
412 static inline void
413 __dldwd_start_irqs(dldwd_priv_t *priv, uint16_t irqmask)
414 {
415 hermes_t *hw = &priv->hw;
416
417 TRACE_ENTER(priv->ndev.name);
418
419 __cli();
420 set_bit(DLDWD_STATE_DOIRQ, &priv->state);
421 hermes_set_irqmask(hw, irqmask);
422 __sti();
423
424 TRACE_EXIT(priv->ndev.name);
425 }
426
427 static inline void
428 set_port_type(dldwd_priv_t *priv)
429 {
430 switch (priv->iw_mode) {
431 case IW_MODE_INFRA:
432 priv->port_type = 1;
433 priv->allow_ibss = 0;
434 break;
435 case IW_MODE_ADHOC:
436 if (priv->prefer_port3) {
437 priv->port_type = 3;
438 priv->allow_ibss = 0;
439 } else {
440 priv->port_type = priv->ibss_port;
441 priv->allow_ibss = 1;
442 }
443 break;
444 default:
445 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
446 priv->ndev.name);
447 }
448 }
449
450 extern void
451 dldwd_set_multicast_list(struct net_device *dev)
452 {
453 dldwd_priv_t *priv = dev->priv;
454
455 dldwd_lock(priv);
456 __dldwd_set_multicast_list(dev);
457 dldwd_unlock(priv);
458 }
459
460 /*
461 * Hardware control routines
462 */
463
464 static int
465 __dldwd_hw_reset(dldwd_priv_t *priv)
466 {
467 hermes_t *hw = &priv->hw;
468 int err;
469
470 if (! priv->broken_reset)
471 return hermes_reset(hw);
472 else {
473 hw->inten = 0;
474 hermes_write_regn(hw, INTEN, 0);
475 err = hermes_disable_port(hw, 0);
476 hermes_write_regn(hw, EVACK, 0xffff);
477 return err;
478 }
479 }
480
481 void
482 dldwd_shutdown(dldwd_priv_t *priv)
483 {
484 /* hermes_t *hw = &priv->hw; */
485 int err = 0;
486
487 TRACE_ENTER(priv->ndev.name);
488
489 dldwd_lock(priv);
490 __dldwd_stop_irqs(priv);
491
492 err = __dldwd_hw_reset(priv);
493 if (err && err != -ENODEV) /* If the card is gone, we don't care about shutting it down */
494 printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev.name, err);
495
496 dldwd_unlock(priv);
497
498 TRACE_EXIT(priv->ndev.name);
499 }
500
501 int
502 dldwd_reset(dldwd_priv_t *priv)
503 {
504 struct net_device *dev = &priv->ndev;
505 hermes_t *hw = &priv->hw;
506 int err = 0;
507 hermes_id_t idbuf;
508 int frame_size;
509
510 TRACE_ENTER(priv->ndev.name);
511
512 /* Stop other people bothering us */
513 dldwd_lock(priv);
514 __dldwd_stop_irqs(priv);
515
516 /* Check if we need a card reset */
517 if((priv->need_card_reset) && (priv->card_reset_handler != NULL))
518 priv->card_reset_handler(priv);
519
520 /* Do standard firmware reset if we can */
521 err = __dldwd_hw_reset(priv);
522 if (err)
523 goto out;
524
525 frame_size = TX_NICBUF_SIZE;
526 /* This stupid bug is present in Intel firmware 1.10, and
527 * may be fixed in later firmwares - Jean II */
528 if(priv->broken_allocate)
529 frame_size = TX_NICBUF_SIZE_BUG;
530 err = hermes_allocate(hw, frame_size, &priv->txfid);
531 if (err)
532 goto out;
533
534 /* Now set up all the parameters on the card */
535
536 /* Set up the link mode */
537
538 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PORTTYPE, priv->port_type);
539 if (err)
540 goto out;
541 if (priv->has_ibss) {
542 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_CREATEIBSS,
543 priv->allow_ibss);
544 if (err)
545 goto out;
546 if((strlen(priv->desired_essid) == 0) && (priv->allow_ibss)
547 && (!priv->has_ibss_any)) {
548 printk(KERN_WARNING "%s: This firmware requires an \
549 ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
550 /* With wvlan_cs, in this case, we would crash.
551 * hopefully, this driver will behave better...
552 * Jean II */
553 }
554 }
555
556 /* Set up encryption */
557 if (priv->has_wep) {
558 err = __dldwd_hw_setup_wep(priv);
559 if (err)
560 goto out;
561 }
562
563 /* Set the desired ESSID */
564 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
565 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
566 err = hermes_write_ltv(hw, USER_BAP, (priv->port_type == 3) ?
567 HERMES_RID_CNF_OWN_SSID : HERMES_RID_CNF_DESIRED_SSID,
568 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
569 &idbuf);
570 if (err)
571 goto out;
572
573 /* Set the station name */
574 idbuf.len = cpu_to_le16(strlen(priv->nick));
575 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
576 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNF_NICKNAME,
577 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
578 &idbuf);
579 if (err)
580 goto out;
581
582 /* Set the channel/frequency */
583 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_CHANNEL, priv->channel);
584 if (err)
585 goto out;
586
587 /* Set AP density */
588 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, priv->ap_density);
589 if (err)
590 goto out;
591
592 /* Set RTS threshold */
593 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_RTS_THRESH, priv->rts_thresh);
594 if (err)
595 goto out;
596
597 /* Set fragmentation threshold or MWO robustness */
598 if (priv->has_mwo)
599 err = hermes_write_wordrec(hw, USER_BAP,
600 HERMES_RID_CNF_MWO_ROBUST, priv->mwo_robust);
601 else
602 err = hermes_write_wordrec(hw, USER_BAP,
603 HERMES_RID_CNF_FRAG_THRESH, priv->frag_thresh);
604 if (err)
605 goto out;
606
607 /* Set bitrate */
608 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_RATE_CTRL,
609 priv->tx_rate_ctrl);
610 if (err)
611 goto out;
612
613 /* Set power management */
614 if (priv->has_pm) {
615 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_ENABLE,
616 priv->pm_on);
617 if (err)
618 goto out;
619 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_MCAST_RX,
620 priv->pm_mcast);
621 if (err)
622 goto out;
623 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD,
624 priv->pm_period);
625 if (err)
626 goto out;
627 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER,
628 priv->pm_timeout);
629 if (err)
630 goto out;
631 }
632
633 /* Set preamble - only for Symbol so far... */
634 if (priv->has_preamble) {
635 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_PREAMBLE,
636 priv->preamble);
637 if (err) {
638 printk(KERN_WARNING "%s: Can't set preamble!\n", dev->name);
639 goto out;
640 }
641 }
642
643 /* Set promiscuity / multicast*/
644 priv->promiscuous = 0;
645 priv->allmulti = 0;
646 priv->mc_count = 0;
647 __dldwd_set_multicast_list(dev);
648
649 err = hermes_enable_port(hw, DLDWD_MACPORT);
650 if (err)
651 goto out;
652
653 __dldwd_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |
654 HERMES_EV_TX | HERMES_EV_TXEXC |
655 HERMES_EV_WTERR | HERMES_EV_INFO |
656 HERMES_EV_INFDROP);
657
658 out:
659 dldwd_unlock(priv);
660
661 TRACE_EXIT(priv->ndev.name);
662
663 return err;
664 }
665
666 static int __dldwd_hw_setup_wep(dldwd_priv_t *priv)
667 {
668 hermes_t *hw = &priv->hw;
669 int err = 0;
670 int master_wep_flag;
671 int auth_flag;
672
673 switch (priv->firmware_type) {
674 case FIRMWARE_TYPE_LUCENT: /* Lucent style WEP */
675 if (priv->wep_on) {
676 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_KEY, priv->tx_key);
677 if (err)
678 return err;
679
680 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNF_KEYS, &priv->keys);
681 if (err)
682 return err;
683 }
684 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_WEP_ON, priv->wep_on);
685 if (err)
686 return err;
687 break;
688
689 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
690 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
691 master_wep_flag = 0; /* Off */
692 if (priv->wep_on) {
693 char keybuf[LARGE_KEY_SIZE+1];
694 int keylen;
695 int i;
696
697 /* Fudge around firmware weirdness */
698 keylen = priv->keys[priv->tx_key].len;
699
700 /* Write all 4 keys */
701 for(i = 0; i < MAX_KEYS; i++) {
702 memset(keybuf, 0, sizeof(keybuf));
703 memcpy(keybuf, priv->keys[i].data,
704 priv->keys[i].len);
705 err = hermes_write_ltv(hw, USER_BAP,
706 HERMES_RID_CNF_PRISM2_KEY0 + i,
707 HERMES_BYTES_TO_RECLEN(keylen),
708 keybuf);
709 if (err)
710 return err;
711 }
712
713 /* Write the index of the key used in transmission */
714 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_TX_KEY,
715 priv->tx_key);
716 if (err)
717 return err;
718
719 /* Authentication is where Intersil and Symbol
720 * firmware differ... */
721 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) {
722 /* Symbol cards : set the authentication :
723 * 0 -> no encryption, 1 -> open,
724 * 2 -> shared key
725 * 3 -> shared key 128 -> AP only */
726 if(priv->wep_restrict)
727 auth_flag = 2;
728 else
729 auth_flag = 1;
730 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_AUTH_TYPE, auth_flag);
731 if (err)
732 return err;
733 /* Master WEP setting is always 3 */
734 master_wep_flag = 3;
735 } else {
736 /* Prism2 card : we need to modify master
737 * WEP setting */
738 if(priv->wep_restrict)
739 master_wep_flag = 3;
740 else
741 master_wep_flag = 1;
742 }
743 }
744
745 /* Master WEP setting : on/off */
746 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_WEP_ON, master_wep_flag);
747 if (err)
748 return err;
749 break;
750
751 default:
752 if (priv->wep_on) {
753 printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
754 priv->ndev.name);
755 return -EINVAL;
756 }
757 }
758
759 return 0;
760 }
761
762 static int dldwd_hw_get_bssid(dldwd_priv_t *priv, char buf[ETH_ALEN])
763 {
764 hermes_t *hw = &priv->hw;
765 int err = 0;
766
767 dldwd_lock(priv);
768
769 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_BSSID,
770 ETH_ALEN, NULL, buf);
771
772 dldwd_unlock(priv);
773
774 return err;
775 }
776
777 static int dldwd_hw_get_essid(dldwd_priv_t *priv, int *active,
778 char buf[IW_ESSID_MAX_SIZE+1])
779 {
780 hermes_t *hw = &priv->hw;
781 int err = 0;
782 hermes_id_t essidbuf;
783 char *p = (char *)(&essidbuf.val);
784 int len;
785
786 TRACE_ENTER(priv->ndev.name);
787
788 dldwd_lock(priv);
789
790 if (strlen(priv->desired_essid) > 0) {
791 /* We read the desired SSID from the hardware rather
792 than from priv->desired_essid, just in case the
793 firmware is allowed to change it on us. I'm not
794 sure about this */
795 /* My guess is that the OWN_SSID should always be whatever
796 * we set to the card, whereas CURRENT_SSID is the one that
797 * may change... - Jean II */
798 uint16_t rid;
799
800 *active = 1;
801
802 rid = (priv->port_type == 3) ? HERMES_RID_CNF_OWN_SSID :
803 HERMES_RID_CNF_DESIRED_SSID;
804
805 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
806 NULL, &essidbuf);
807 if (err)
808 goto fail_unlock;
809 } else {
810 *active = 0;
811
812 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_SSID,
813 sizeof(essidbuf), NULL, &essidbuf);
814 if (err)
815 goto fail_unlock;
816 }
817
818 len = le16_to_cpu(essidbuf.len);
819
820 memset(buf, 0, sizeof(buf));
821 memcpy(buf, p, len);
822 buf[len] = '\0';
823
824 fail_unlock:
825 dldwd_unlock(priv);
826
827 TRACE_EXIT(priv->ndev.name);
828
829 return err;
830 }
831
832 static long dldwd_hw_get_freq(dldwd_priv_t *priv)
833 {
834
835 hermes_t *hw = &priv->hw;
836 int err = 0;
837 uint16_t channel;
838 long freq = 0;
839
840 dldwd_lock(priv);
841
842 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_CHANNEL, &channel);
843 if (err)
844 goto out;
845
846 if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
847 struct net_device *dev = &priv->ndev;
848
849 printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);
850 err = -EBUSY;
851 goto out;
852
853 }
854 freq = channel_frequency[channel-1] * 100000;
855
856 out:
857 dldwd_unlock(priv);
858
859 if (err > 0)
860 err = -EBUSY;
861 return err ? err : freq;
862 }
863
864 static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,
865 int32_t *rates, int max)
866 {
867 hermes_t *hw = &priv->hw;
868 hermes_id_t list;
869 unsigned char *p = (unsigned char *)&list.val;
870 int err = 0;
871 int num;
872 int i;
873
874 dldwd_lock(priv);
875 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_DATARATES, sizeof(list),
876 NULL, &list);
877 dldwd_unlock(priv);
878
879 if (err)
880 return err;
881
882 num = le16_to_cpu(list.len);
883 *numrates = num;
884 num = MIN(num, max);
885
886 for (i = 0; i < num; i++) {
887 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
888 }
889
890 return 0;
891 }
892
893 #ifndef ORINOCO_DEBUG
894 static inline void show_rx_frame(struct dldwd_frame_hdr *frame) {}
895 #else
896 static void show_rx_frame(struct dldwd_frame_hdr *frame)
897 {
898 printk(KERN_DEBUG "RX descriptor:\n");
899 printk(KERN_DEBUG " status = 0x%04x\n", frame->desc.status);
900 printk(KERN_DEBUG " res1 = 0x%04x\n", frame->desc.res1);
901 printk(KERN_DEBUG " res2 = 0x%04x\n", frame->desc.res2);
902 printk(KERN_DEBUG " q_info = 0x%04x\n", frame->desc.q_info);
903 printk(KERN_DEBUG " res3 = 0x%04x\n", frame->desc.res3);
904 printk(KERN_DEBUG " res4 = 0x%04x\n", frame->desc.res4);
905 printk(KERN_DEBUG " tx_ctl = 0x%04x\n", frame->desc.tx_ctl);
906
907 printk(KERN_DEBUG "IEEE 802.11 header:\n");
908 printk(KERN_DEBUG " frame_ctl = 0x%04x\n",
909 frame->p80211.frame_ctl);
910 printk(KERN_DEBUG " duration_id = 0x%04x\n",
911 frame->p80211.duration_id);
912 printk(KERN_DEBUG " addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n",
913 frame->p80211.addr1[0], frame->p80211.addr1[1],
914 frame->p80211.addr1[2], frame->p80211.addr1[3],
915 frame->p80211.addr1[4], frame->p80211.addr1[5]);
916 printk(KERN_DEBUG " addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n",
917 frame->p80211.addr2[0], frame->p80211.addr2[1],
918 frame->p80211.addr2[2], frame->p80211.addr2[3],
919 frame->p80211.addr2[4], frame->p80211.addr2[5]);
920 printk(KERN_DEBUG " addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n",
921 frame->p80211.addr3[0], frame->p80211.addr3[1],
922 frame->p80211.addr3[2], frame->p80211.addr3[3],
923 frame->p80211.addr3[4], frame->p80211.addr3[5]);
924 printk(KERN_DEBUG " seq_ctl = 0x%04x\n",
925 frame->p80211.seq_ctl);
926 printk(KERN_DEBUG " addr4 = %02x:%02x:%02x:%02x:%02x:%02x\n",
927 frame->p80211.addr4[0], frame->p80211.addr4[1],
928 frame->p80211.addr4[2], frame->p80211.addr4[3],
929 frame->p80211.addr4[4], frame->p80211.addr4[5]);
930 printk(KERN_DEBUG " data_len = 0x%04x\n",
931 frame->p80211.data_len);
932
933 printk(KERN_DEBUG "IEEE 802.3 header:\n");
934 printk(KERN_DEBUG " dest = %02x:%02x:%02x:%02x:%02x:%02x\n",
935 frame->p8023.h_dest[0], frame->p8023.h_dest[1],
936 frame->p8023.h_dest[2], frame->p8023.h_dest[3],
937 frame->p8023.h_dest[4], frame->p8023.h_dest[5]);
938 printk(KERN_DEBUG " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
939 frame->p8023.h_source[0], frame->p8023.h_source[1],
940 frame->p8023.h_source[2], frame->p8023.h_source[3],
941 frame->p8023.h_source[4], frame->p8023.h_source[5]);
942 printk(KERN_DEBUG " len = 0x%04x\n", frame->p8023.h_proto);
943
944 printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");
945 printk(KERN_DEBUG " DSAP = 0x%02x\n", frame->p8022.dsap);
946 printk(KERN_DEBUG " SSAP = 0x%02x\n", frame->p8022.ssap);
947 printk(KERN_DEBUG " ctrl = 0x%02x\n", frame->p8022.ctrl);
948 printk(KERN_DEBUG " OUI = %02x:%02x:%02x\n",
949 frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
950 printk(KERN_DEBUG " ethertype = 0x%04x\n", frame->ethertype);
951 }
952 #endif
953
954 /*
955 * Interrupt handler
956 */
957 void dldwd_interrupt(int irq, void * dev_id, struct pt_regs *regs)
958 {
959 dldwd_priv_t *priv = (dldwd_priv_t *) dev_id;
960 hermes_t *hw = &priv->hw;
961 struct net_device *dev = &priv->ndev;
962 int count = IRQ_LOOP_MAX;
963 uint16_t evstat, events;
964 static int old_time = 0, timecount = 0; /* Eugh, revolting hack for now */
965
966 if (test_and_set_bit(DLDWD_STATE_INIRQ, &priv->state))
967 BUG();
968
969 if (! dldwd_irqs_allowed(priv)) {
970 clear_bit(DLDWD_STATE_INIRQ, &priv->state);
971 return;
972 }
973
974 DEBUG(3, "%s: dldwd_interrupt()\n", priv->ndev.name);
975
976 while (1) {
977 if (jiffies != old_time)
978 timecount = 0;
979 if ( (++timecount > 50) || (! count--) ) {
980 printk(KERN_CRIT "%s: IRQ handler is looping too \
981 much! Shutting down.\n",
982 dev->name);
983 /* Perform an emergency shutdown */
984 clear_bit(DLDWD_STATE_DOIRQ, &priv->state);
985 hermes_set_irqmask(hw, 0);
986 break;
987 }
988
989 evstat = hermes_read_regn(hw, EVSTAT);
990 DEBUG(3, "__dldwd_interrupt(): count=%d EVSTAT=0x%04x inten=0x%04x\n",
991 count, evstat, hw->inten);
992
993 events = evstat & hw->inten;
994
995 if (! events) {
996 if (netif_queue_stopped(dev)) {
997 /* There seems to be a firmware bug which
998 sometimes causes the card to give an
999 interrupt with no event set, when there
1000 sould be a Tx completed event. */
1001 DEBUG(3, "%s: Interrupt with no event (ALLOCFID=0x%04x)\n",
1002 dev->name, (int)hermes_read_regn(hw, ALLOCFID));
1003 events = HERMES_EV_TX | HERMES_EV_ALLOC;
1004 } else /* Nothing's happening, we're done */
1005 break;
1006 }
1007
1008 /* Check the card hasn't been removed */
1009 if (! hermes_present(hw)) {
1010 DEBUG(0, "dldwd_interrupt(): card removed\n");
1011 break;
1012 }
1013
1014 if (events & HERMES_EV_TICK)
1015 __dldwd_ev_tick(priv, hw);
1016 if (events & HERMES_EV_WTERR)
1017 __dldwd_ev_wterr(priv, hw);
1018 if (events & HERMES_EV_INFDROP)
1019 __dldwd_ev_infdrop(priv, hw);
1020 if (events & HERMES_EV_INFO)
1021 __dldwd_ev_info(priv, hw);
1022 if (events & HERMES_EV_RX)
1023 __dldwd_ev_rx(priv, hw);
1024 if (events & HERMES_EV_TXEXC)
1025 __dldwd_ev_txexc(priv, hw);
1026 if (events & HERMES_EV_TX)
1027 __dldwd_ev_tx(priv, hw);
1028 if (events & HERMES_EV_ALLOC)
1029 __dldwd_ev_alloc(priv, hw);
1030
1031 hermes_write_regn(hw, EVACK, events);
1032 }
1033
1034 clear_bit(DLDWD_STATE_INIRQ, &priv->state);
1035 }
1036
1037 static void __dldwd_ev_tick(dldwd_priv_t *priv, hermes_t *hw)
1038 {
1039 printk(KERN_DEBUG "%s: TICK\n", priv->ndev.name);
1040 }
1041
1042 static void __dldwd_ev_wterr(dldwd_priv_t *priv, hermes_t *hw)
1043 {
1044 /* This seems to happen a fair bit under load, but ignoring it
1045 seems to work fine...*/
1046 DEBUG(1, "%s: MAC controller error (WTERR). Ignoring.\n",
1047 priv->ndev.name);
1048 }
1049
1050 static void __dldwd_ev_infdrop(dldwd_priv_t *priv, hermes_t *hw)
1051 {
1052 printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev.name);
1053 }
1054
1055 static void __dldwd_ev_info(dldwd_priv_t *priv, hermes_t *hw)
1056 {
1057 DEBUG(3, "%s: Information frame received.\n", priv->ndev.name);
1058 /* We don't actually do anything about it - we assume the MAC
1059 controller can deal with it */
1060 }
1061
1062 static void __dldwd_ev_rx(dldwd_priv_t *priv, hermes_t *hw)
1063 {
1064 struct net_device *dev = &priv->ndev;
1065 struct net_device_stats *stats = &priv->stats;
1066 struct iw_statistics *wstats = &priv->wstats;
1067 struct sk_buff *skb = NULL;
1068 int l = RX_EIO_RETRY;
1069 uint16_t rxfid, status;
1070 int length, data_len, data_off;
1071 char *p;
1072 struct dldwd_frame_hdr hdr;
1073 struct ethhdr *eh;
1074 int err;
1075
1076 rxfid = hermes_read_regn(hw, RXFID);
1077 DEBUG(3, "__dldwd_ev_rx(): RXFID=0x%04x\n", rxfid);
1078
1079 /* We read in the entire frame header here. This isn't really
1080 necessary, since we ignore most of it, but it's
1081 conceptually simpler. We can tune this later if
1082 necessary. */
1083 do {
1084 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
1085 rxfid, 0);
1086 } while ( (err == -EIO) && (--l) );
1087 if (err) {
1088 if (err == -EIO)
1089 DEBUG(1, "%s: EIO reading frame header.\n", dev->name);
1090 else
1091 printk(KERN_ERR "%s: error %d reading frame header. "
1092 "Frame dropped.\n", dev->name, err);
1093 stats->rx_errors++;
1094 goto drop;
1095 }
1096 DEBUG(2, "%s: BAP read suceeded: l=%d\n", dev->name, l);
1097
1098 status = le16_to_cpu(hdr.desc.status);
1099
1100 if (status & HERMES_RXSTAT_ERR) {
1101 if ((status & HERMES_RXSTAT_ERR) == HERMES_RXSTAT_BADCRC) {
1102 stats->rx_crc_errors++;
1103 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
1104 show_rx_frame(&hdr);
1105 } else if ((status & HERMES_RXSTAT_ERR)
1106 == HERMES_RXSTAT_UNDECRYPTABLE) {
1107 wstats->discard.code++;
1108 printk(KERN_WARNING "%s: Undecryptable frame on Rx. Frame dropped.\n",
1109 dev->name);
1110 } else {
1111 wstats->discard.misc++;
1112 printk("%s: Unknown Rx error (0x%x). Frame dropped.\n",
1113 dev->name, status & HERMES_RXSTAT_ERR);
1114 }
1115 stats->rx_errors++;
1116 goto drop;
1117 }
1118
1119 length = le16_to_cpu(hdr.p80211.data_len);
1120 /* Yes, you heard right, that's le16. 802.2 and 802.3 are
1121 big-endian, but 802.11 is little-endian believe it or
1122 not. */
1123 /* Correct. 802.3 is big-endian byte order and little endian bit
1124 * order, whereas 802.11 is little endian for both byte and bit
1125 * order. That's specified in the 802.11 spec. - Jean II */
1126
1127 /* Sanity check */
1128 if (length > MAX_FRAME_SIZE) {
1129 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1130 dev->name, length);
1131 stats->rx_length_errors++;
1132 stats->rx_errors++;
1133 goto drop;
1134 }
1135
1136 /* We need space for the packet data itself, plus an ethernet
1137 header, plus 2 bytes so we can align the IP header on a
1138 32bit boundary, plus 1 byte so we can read in odd length
1139 packets from the card, which has an IO granularity of 16
1140 bits */
1141 skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1142 if (!skb) {
1143 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1144 dev->name);
1145 stats->rx_dropped++;
1146 goto drop;
1147 }
1148
1149 skb_reserve(skb, 2); /* This way the IP header is aligned */
1150
1151 /* Handle decapsulation
1152 * In most cases, the firmware tell us about SNAP frames.
1153 * For some reason, the SNAP frames sent by LinkSys APs
1154 * are not properly recognised by most firmwares.
1155 * So, check ourselves (note : only 3 bytes out of 6).
1156 */
1157 if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1158 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1159 (!memcmp(&hdr.p8022, &encaps_hdr, 3))) {
1160 /* These indicate a SNAP within 802.2 LLC within
1161 802.11 frame which we'll need to de-encapsulate to
1162 the original EthernetII frame. */
1163
1164 /* Remove SNAP header, reconstruct EthernetII frame */
1165 data_len = length - ENCAPS_OVERHEAD;
1166 data_off = sizeof(hdr);
1167
1168 eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
1169
1170 memcpy(eh, &hdr.p8023, sizeof(hdr.p8023));
1171 eh->h_proto = hdr.ethertype;
1172 } else {
1173 /* All other cases indicate a genuine 802.3 frame.
1174 * No decapsulation needed */
1175
1176 /* Otherwise, we just throw the whole thing in,
1177 * and hope the protocol layer can deal with it
1178 * as 802.3 */
1179 data_len = length;
1180 data_off = P8023_OFFSET;
1181 }
1182
1183 p = skb_put(skb, data_len);
1184 do {
1185 err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
1186 rxfid, data_off);
1187 } while ( (err == -EIO) && (--l) );
1188 if (err) {
1189 if (err == -EIO)
1190 DEBUG(1, "%s: EIO reading frame header.\n", dev->name);
1191 else
1192 printk(KERN_ERR "%s: error %d reading frame header. "
1193 "Frame dropped.\n", dev->name, err);
1194 stats->rx_errors++;
1195 goto drop;
1196 }
1197 DEBUG(2, "%s: BAP read suceeded: l=%d\n", dev->name, l);
1198
1199 dev->last_rx = jiffies;
1200 skb->dev = dev;
1201 skb->protocol = eth_type_trans(skb, dev);
1202 skb->ip_summed = CHECKSUM_NONE;
1203
1204 /* Process the wireless stats if needed */
1205 dldwd_stat_gather(dev, skb, &hdr);
1206
1207 /* Pass the packet to the networking stack */
1208 netif_rx(skb);
1209 stats->rx_packets++;
1210 stats->rx_bytes += length;
1211
1212 return;
1213
1214 drop:
1215 if (skb)
1216 dev_kfree_skb_irq(skb);
1217 return;
1218 }
1219
1220 static void __dldwd_ev_txexc(dldwd_priv_t *priv, hermes_t *hw)
1221 {
1222 struct net_device *dev = &priv->ndev;
1223 struct net_device_stats *stats = &priv->stats;
1224
1225 printk(KERN_WARNING "%s: Tx error!\n", dev->name);
1226
1227 netif_wake_queue(dev);
1228 stats->tx_errors++;
1229 }
1230
1231 static void __dldwd_ev_tx(dldwd_priv_t *priv, hermes_t *hw)
1232 {
1233 struct net_device *dev = &priv->ndev;
1234 struct net_device_stats *stats = &priv->stats;
1235
1236 DEBUG(3, "%s: Transmit completed\n", dev->name);
1237
1238 stats->tx_packets++;
1239 netif_wake_queue(dev);
1240 }
1241
1242 static void __dldwd_ev_alloc(dldwd_priv_t *priv, hermes_t *hw)
1243 {
1244 uint16_t allocfid;
1245
1246 allocfid = hermes_read_regn(hw, ALLOCFID);
1247 DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev.name, allocfid);
1248
1249 /* For some reason we don't seem to get transmit completed events properly */
1250 if (allocfid == priv->txfid)
1251 __dldwd_ev_tx(priv, hw);
1252
1253 /* hermes_write_regn(hw, ALLOCFID, 0); */
1254 }
1255
1256 static void determine_firmware(struct net_device *dev)
1257 {
1258 dldwd_priv_t *priv = dev->priv;
1259 hermes_t *hw = &priv->hw;
1260 int err;
1261 struct sta_id {
1262 uint16_t id, vendor, major, minor;
1263 } __PACKED__ sta_id;
1264 uint32_t firmver;
1265
1266 /* Get the firmware version */
1267 err = HERMES_READ_RECORD(hw, USER_BAP,
1268 HERMES_RID_STAIDENTITY, &sta_id);
1269 if (err) {
1270 printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",
1271 dev->name, err);
1272 memset(&sta_id, 0, sizeof(sta_id));
1273 }
1274 le16_to_cpus(&sta_id.id);
1275 le16_to_cpus(&sta_id.vendor);
1276 le16_to_cpus(&sta_id.major);
1277 le16_to_cpus(&sta_id.minor);
1278
1279 firmver = ((uint32_t)sta_id.major << 16) | sta_id.minor;
1280
1281 printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
1282 dev->name, sta_id.id, sta_id.vendor,
1283 sta_id.major, sta_id.minor);
1284
1285 /* Determine capabilities from the firmware version */
1286
1287 if (sta_id.vendor == 1) {
1288 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
1289 ELSE, Meloc, HP, IBM, Dell 1150 */
1290 printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
1291 "version %d.%02d\n", dev->name,
1292 sta_id.major, sta_id.minor);
1293
1294 priv->firmware_type = FIRMWARE_TYPE_LUCENT;
1295 priv->tx_rate_ctrl = 0x3; /* 11 Mb/s auto */
1296 priv->need_card_reset = 0;
1297 priv->broken_reset = 0;
1298 priv->broken_allocate = 0;
1299 priv->has_port3 = 1; /* Still works in 7.28 */
1300 priv->has_ibss = (firmver >= 0x60006);
1301 priv->has_ibss_any = (firmver >= 0x60010);
1302 priv->has_wep = (firmver >= 0x40020);
1303 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
1304 Gold cards from the others? */
1305 priv->has_mwo = (firmver >= 0x60000);
1306 priv->has_pm = (firmver >= 0x40020);
1307 priv->has_preamble = 0;
1308 priv->ibss_port = 1;
1309 /* Tested with Lucent firmware :
1310 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
1311 * Tested CableTron firmware : 4.32 => Anton */
1312 } else if ((sta_id.vendor == 2) &&
1313 ((firmver == 0x10001) || (firmver == 0x20001))) {
1314 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
1315 /* Intel MAC : 00:02:B3:* */
1316 /* 3Com MAC : 00:50:DA:* */
1317 printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
1318 "(unknown version)\n", dev->name);
1319
1320 /* FIXME : we need to get Symbol firmware revision.
1321 * I tried to use SYMBOL_***ARY_VER, but it didn't
1322 * returned anything proper... */
1323 priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
1324 priv->tx_rate_ctrl = 0xF; /* 11 Mb/s auto */
1325 priv->need_card_reset = 1;
1326 priv->broken_reset = 0;
1327 priv->broken_allocate = 1;
1328 priv->has_port3 = 1;
1329 priv->has_ibss = 1; /* FIXME */
1330 priv->has_wep = 1; /* FIXME */
1331 priv->has_big_wep = 1; /* RID_SYMBOL_KEY_LENGTH */
1332 priv->has_mwo = 0;
1333 priv->has_pm = 1; /* FIXME */
1334 priv->has_preamble = 0; /* FIXME */
1335 priv->ibss_port = 4;
1336 /* Tested with Intel firmware : v15 => Jean II */
1337 } else {
1338 printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
1339 "version %d.%02d\n", dev->name,
1340 sta_id.major, sta_id.minor);
1341
1342 priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
1343 priv->tx_rate_ctrl = 0xF; /* 11 Mb/s auto */
1344 priv->need_card_reset = 0;
1345 priv->broken_reset = 0;
1346 priv->broken_allocate = 0;
1347 priv->has_port3 = 1;
1348 priv->has_ibss = (firmver >= 0x00007); /* FIXME */
1349 priv->has_wep = (firmver >= 0x00008);
1350 priv->has_big_wep = 0;
1351 priv->has_mwo = 0;
1352 priv->has_pm = (firmver >= 0x00007);
1353 priv->has_preamble = 0;
1354
1355 if (firmver >= 0x00008)
1356 priv->ibss_port = 0;
1357 else {
1358 printk(KERN_NOTICE "%s: Intersil firmware earlier "
1359 "than v0.08 - several features not supported.",
1360 dev->name);
1361 priv->ibss_port = 1;
1362 }
1363 }
1364 }
1365
1366 /*
1367 * struct net_device methods
1368 */
1369
1370 int
1371 dldwd_init(struct net_device *dev)
1372 {
1373 dldwd_priv_t *priv = dev->priv;
1374 hermes_t *hw = &priv->hw;
1375 int err = 0;
1376 hermes_id_t nickbuf;
1377 uint16_t reclen;
1378 int len;
1379
1380 TRACE_ENTER("dldwd");
1381
1382 dldwd_lock(priv);
1383
1384 /* Do standard firmware reset */
1385 err = hermes_reset(hw);
1386 if (err != 0) {
1387 printk(KERN_ERR "%s: failed to reset hardware (err = %d)\n",
1388 dev->name, err);
1389 goto out;
1390 }
1391
1392 determine_firmware(dev);
1393
1394 if (priv->has_port3)
1395 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported.\n", dev->name);
1396 if (priv->has_ibss)
1397 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported.\n",
1398 dev->name);
1399 if (priv->has_wep) {
1400 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
1401 if (priv->has_big_wep)
1402 printk("\"128\"-bit key.\n");
1403 else
1404 printk("40-bit key.\n");
1405 }
1406
1407 /* Get the MAC address */
1408 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNF_MACADDR,
1409 ETH_ALEN, NULL, dev->dev_addr);
1410 if (err) {
1411 printk(KERN_WARNING "%s: failed to read MAC address!\n",
1412 dev->name);
1413 goto out;
1414 }
1415
1416 printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
1417 dev->name, dev->dev_addr[0], dev->dev_addr[1],
1418 dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
1419 dev->dev_addr[5]);
1420
1421 /* Get the station name */
1422 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNF_NICKNAME,
1423 sizeof(nickbuf), &reclen, &nickbuf);
1424 if (err) {
1425 printk(KERN_ERR "%s: failed to read station name!n",
1426 dev->name);
1427 goto out;
1428 }
1429 if ( nickbuf.len )
1430 len = MIN(IW_ESSID_MAX_SIZE, le16_to_cpu(nickbuf.len));
1431 else
1432 len = MIN(IW_ESSID_MAX_SIZE, 2 * reclen);
1433 memcpy(priv->nick, &nickbuf.val, len);
1434 priv->nick[len] = '\0';
1435
1436 printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
1437
1438 /* Get allowed channels */
1439 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNEL_LIST, &priv->channel_mask);
1440 if (err) {
1441 printk(KERN_ERR "%s: failed to read channel list!\n",
1442 dev->name);
1443 goto out;
1444 }
1445
1446 /* Get initial AP density */
1447 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, &priv->ap_density);
1448 if (err) {
1449 printk(KERN_ERR "%s: failed to read AP density!\n", dev->name);
1450 goto out;
1451 }
1452
1453 /* Get initial RTS threshold */
1454 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_RTS_THRESH, &priv->rts_thresh);
1455 if (err) {
1456 printk(KERN_ERR "%s: failed to read RTS threshold!\n", dev->name);
1457 goto out;
1458 }
1459
1460 /* Get initial fragmentation settings */
1461 if (priv->has_mwo)
1462 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_MWO_ROBUST,
1463 &priv->mwo_robust);
1464 else
1465 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_FRAG_THRESH,
1466 &priv->frag_thresh);
1467 if (err) {
1468 printk(KERN_ERR "%s: failed to read fragmentation settings!\n", dev->name);
1469 goto out;
1470 }
1471
1472 /* Power management setup */
1473 if (priv->has_pm) {
1474 priv->pm_on = 0;
1475 priv->pm_mcast = 1;
1476 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD,
1477 &priv->pm_period);
1478 if (err) {
1479 printk(KERN_ERR "%s: failed to read power management period!\n",
1480 dev->name);
1481 goto out;
1482 }
1483 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER,
1484 &priv->pm_timeout);
1485 if (err) {
1486 printk(KERN_ERR "%s: failed to read power management timeout!\n",
1487 dev->name);
1488 goto out;
1489 }
1490 }
1491
1492 /* Preamble setup */
1493 if (priv->has_preamble) {
1494 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_PREAMBLE, &priv->preamble);
1495 if (err)
1496 goto out;
1497 }
1498
1499 /* Set up the default configuration */
1500 priv->iw_mode = IW_MODE_INFRA;
1501 /* By default use IEEE/IBSS ad-hoc mode if we have it */
1502 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
1503 set_port_type(priv);
1504
1505 priv->promiscuous = 0;
1506 priv->allmulti = 0;
1507 priv->wep_on = 0;
1508 priv->tx_key = 0;
1509
1510 printk(KERN_DEBUG "%s: ready\n", dev->name);
1511
1512 out:
1513 dldwd_unlock(priv);
1514
1515 TRACE_EXIT("dldwd");
1516
1517 return err;
1518 }
1519
1520 struct net_device_stats *
1521 dldwd_get_stats(struct net_device *dev)
1522 {
1523 dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1524
1525 return &priv->stats;
1526 }
1527
1528 struct iw_statistics *
1529 dldwd_get_wireless_stats(struct net_device *dev)
1530 {
1531 dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1532 hermes_t *hw = &priv->hw;
1533 struct iw_statistics *wstats = &priv->wstats;
1534 int err = 0;
1535
1536 if (!priv->hw_ready)
1537 return NULL;
1538
1539 dldwd_lock(priv);
1540
1541 if (priv->iw_mode == IW_MODE_ADHOC) {
1542 memset(&wstats->qual, 0, sizeof(wstats->qual));
1543 #ifdef WIRELESS_SPY
1544 /* If a spy address is defined, we report stats of the
1545 * first spy address - Jean II */
1546 if (priv->spy_number > 0) {
1547 wstats->qual.qual = priv->spy_stat[0].qual;
1548 wstats->qual.level = priv->spy_stat[0].level;
1549 wstats->qual.noise = priv->spy_stat[0].noise;
1550 wstats->qual.updated = priv->spy_stat[0].updated;
1551 }
1552 #endif /* WIRELESS_SPY */
1553 } else {
1554 dldwd_commsqual_t cq;
1555
1556 err = HERMES_READ_RECORD(hw, USER_BAP,
1557 HERMES_RID_COMMSQUALITY, &cq);
1558
1559 le16_to_cpus(&cq.qual);
1560 le16_to_cpus(&cq.signal);
1561 le16_to_cpus(&cq.noise);
1562
1563 DEBUG(3, "%s: Global stats = %X-%X-%X\n", dev->name,
1564 cq.qual, cq.signal, cq.noise);
1565
1566 /* Why are we using MIN/MAX ? We don't really care
1567 * if the value goes above max, because we export the
1568 * raw dBm values anyway. The normalisation should be done
1569 * in user space - Jean II */
1570 wstats->qual.qual = MAX(MIN(cq.qual, 0x8b-0x2f), 0);
1571 wstats->qual.level = MAX(MIN(cq.signal, 0x8a), 0x2f) - 0x95;
1572 wstats->qual.noise = MAX(MIN(cq.noise, 0x8a), 0x2f) - 0x95;
1573 wstats->qual.updated = 7;
1574 }
1575
1576 dldwd_unlock(priv);
1577
1578 if (err)
1579 return NULL;
1580
1581 return wstats;
1582 }
1583
1584 #ifdef WIRELESS_SPY
1585 static inline void dldwd_spy_gather(struct net_device *dev,
1586 u_char *mac,
1587 dldwd_commsqual_t *cq)
1588 {
1589 dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1590 int i;
1591
1592 /* Gather wireless spy statistics: for each packet, compare the
1593 * source address with out list, and if match, get the stats... */
1594 for (i = 0; i < priv->spy_number; i++)
1595 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
1596 priv->spy_stat[i].qual = MAX(MIN(cq->qual, 0x8b-0x2f), 0);
1597 priv->spy_stat[i].level = MAX(MIN(cq->signal, 0x8a), 0x2f) - 0x95;
1598 priv->spy_stat[i].noise = MAX(MIN(cq->noise, 0x8a), 0x2f) - 0x95;
1599 priv->spy_stat[i].updated = 7;
1600 }
1601 }
1602 #endif /* WIRELESS_SPY */
1603
1604 void
1605 dldwd_stat_gather( struct net_device *dev,
1606 struct sk_buff *skb,
1607 struct dldwd_frame_hdr *hdr)
1608 {
1609 dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1610 dldwd_commsqual_t cq;
1611
1612 /* Using spy support with lots of Rx packets, like in an
1613 * infrastructure (AP), will really slow down everything, because
1614 * the MAC address must be compared to each entry of the spy list.
1615 * If the user really asks for it (set some address in the
1616 * spy list), we do it, but he will pay the price.
1617 * Note that to get here, you need both WIRELESS_SPY
1618 * compiled in AND some addresses in the list !!!
1619 */
1620 #ifdef WIRELESS_EXT
1621 /* Note : gcc will optimise the whole section away if
1622 * WIRELESS_SPY is not defined... - Jean II */
1623 if (
1624 #ifdef WIRELESS_SPY
1625 (priv->spy_number > 0) ||
1626 #endif
1627 0 )
1628 {
1629 u_char *stats = (u_char *) &(hdr->desc.q_info);
1630 /* This code may look strange. Everywhere we are using 16 bit
1631 * ints except here. I've verified that these are are the
1632 * correct values. Please check on PPC - Jean II */
1633 cq.signal = stats[1]; /* High order byte */
1634 cq.noise = stats[0]; /* Low order byte */
1635 cq.qual = stats[0] - stats[1]; /* Better than nothing */
1636
1637 DEBUG(3, "%s: Packet stats = %X-%X-%X\n", dev->name,
1638 cq.qual, cq.signal, cq.noise);
1639
1640 #ifdef WIRELESS_SPY
1641 dldwd_spy_gather(dev, skb->mac.raw + ETH_ALEN, &cq);
1642 #endif
1643 }
1644 #endif /* WIRELESS_EXT */
1645 }
1646
1647 int
1648 dldwd_xmit(struct sk_buff *skb, struct net_device *dev)
1649 {
1650 dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1651 struct net_device_stats *stats = &priv->stats;
1652 hermes_t *hw = &priv->hw;
1653 int err = 0;
1654 uint16_t txfid = priv->txfid;
1655 char *p;
1656 struct ethhdr *eh;
1657 int len, data_len, data_off;
1658 struct dldwd_frame_hdr hdr;
1659 hermes_response_t resp;
1660
1661 if (! netif_running(dev)) {
1662 printk(KERN_ERR "%s: Tx on stopped device!\n",
1663 dev->name);
1664 return 1;
1665
1666 }
1667
1668 if (netif_queue_stopped(dev)) {
1669 printk(KERN_ERR "%s: Tx while transmitter busy!\n",
1670 dev->name);
1671 return 1;
1672 }
1673
1674 dldwd_lock(priv);
1675
1676 /* Length of the packet body */
1677 len = MAX(skb->len - ETH_HLEN, ETH_ZLEN);
1678
1679 eh = (struct ethhdr *)skb->data;
1680
1681 /* Build the IEEE 802.11 header */
1682 memset(&hdr, 0, sizeof(hdr));
1683 memcpy(hdr.p80211.addr1, eh->h_dest, ETH_ALEN);
1684 memcpy(hdr.p80211.addr2, eh->h_source, ETH_ALEN);
1685 hdr.p80211.frame_ctl = DLDWD_FTYPE_DATA;
1686
1687 /* Encapsulate Ethernet-II frames */
1688 if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
1689 data_len = len;
1690 data_off = sizeof(hdr);
1691 p = skb->data + ETH_HLEN;
1692
1693 /* 802.11 header */
1694 hdr.p80211.data_len = cpu_to_le16(data_len + ENCAPS_OVERHEAD);
1695
1696 /* 802.3 header */
1697 memcpy(hdr.p8023.h_dest, eh->h_dest, ETH_ALEN);
1698 memcpy(hdr.p8023.h_source, eh->h_source, ETH_ALEN);
1699 hdr.p8023.h_proto = htons(data_len + ENCAPS_OVERHEAD);
1700
1701 /* 802.2 header */
1702 /* FIXME: ugh, what a hack for the 00:00:00 APs. Need to find a better way */
1703 if (use_alternate_encaps)
1704 memcpy(&hdr.p8022, &alternate_encaps_hdr, sizeof(alternate_encaps_hdr));
1705 else
1706 memcpy(&hdr.p8022, &encaps_hdr, sizeof(encaps_hdr));
1707
1708 hdr.ethertype = eh->h_proto;
1709 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
1710 txfid, 0);
1711 if (err) {
1712 if (err == -EIO)
1713 /* We get these errors reported by the
1714 firmware every so often apparently at
1715 random. Let the upper layers
1716 handle the retry */
1717 DEBUG(1, "%s: DEBUG: EIO writing packet header to BAP\n", dev->name);
1718 else
1719 printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
1720 dev->name, err);
1721 stats->tx_errors++;
1722 goto fail;
1723 }
1724 } else { /* IEEE 802.3 frame */
1725 data_len = len + ETH_HLEN;
1726 data_off = P8023_OFFSET;
1727 p = skb->data;
1728
1729 /* 802.11 header */
1730 hdr.p80211.data_len = cpu_to_le16(len);
1731 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, P8023_OFFSET,
1732 txfid, 0);
1733 if (err) {
1734 printk(KERN_ERR
1735 "%s: Error %d writing packet header to BAP\n",
1736 dev->name, err);
1737 stats->tx_errors++;
1738 goto fail;
1739 }
1740 }
1741
1742 /* Round up for odd length packets */
1743 err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);
1744 if (err) {
1745 if (err == -EIO)
1746 DEBUG(1, "%s: DEBUG: EIO writing packet header to BAP\n", dev->name);
1747 else
1748 printk(KERN_ERR "%s: Error %d writing packet header to BAP",
1749 dev->name, err);
1750 stats->tx_errors++;
1751 goto fail;
1752 }
1753
1754 /* Finally, we actually initiate the send */
1755 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, &resp);
1756 if (err) {
1757 printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);
1758 stats->tx_errors++;
1759 goto fail;
1760 }
1761
1762 dev->trans_start = jiffies;
1763 stats->tx_bytes += data_off + data_len;
1764
1765 netif_stop_queue(dev);
1766
1767 dldwd_unlock(priv);
1768
1769 dev_kfree_skb(skb);
1770
1771 return 0;
1772 fail:
1773
1774 dldwd_unlock(priv);
1775 return err;
1776 }
1777
1778 void
1779 dldwd_tx_timeout(struct net_device *dev)
1780 {
1781 dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1782 struct net_device_stats *stats = &priv->stats;
1783 int err = 0;
1784
1785 printk(KERN_WARNING "%s: Tx timeout! Resetting card.\n", dev->name);
1786
1787 stats->tx_errors++;
1788
1789 err = dldwd_reset(priv);
1790 if (err)
1791 printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
1792 dev->name, err);
1793 else {
1794 dev->trans_start = jiffies;
1795 netif_wake_queue(dev);
1796 }
1797 }
1798
1799 static int dldwd_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
1800 {
1801 dldwd_priv_t *priv = dev->priv;
1802 int err = 0;
1803 int mode;
1804 struct iw_range range;
1805 int numrates;
1806 int i, k;
1807
1808 TRACE_ENTER(dev->name);
1809
1810 err = verify_area(VERIFY_WRITE, rrq->pointer, sizeof(range));
1811 if (err)
1812 return err;
1813
1814 rrq->length = sizeof(range);
1815
1816 dldwd_lock(priv);
1817 mode = priv->iw_mode;
1818 dldwd_unlock(priv);
1819
1820 memset(&range, 0, sizeof(range));
1821
1822 /* Much of this shamelessly taken from wvlan_cs.c. No idea
1823 * what it all means -dgibson */
1824 #if WIRELESS_EXT > 10
1825 range.we_version_compiled = WIRELESS_EXT;
1826 range.we_version_source = 11;
1827 #endif /* WIRELESS_EXT > 10 */
1828
1829 range.min_nwid = range.max_nwid = 0; /* We don't use nwids */
1830
1831 /* Set available channels/frequencies */
1832 range.num_channels = NUM_CHANNELS;
1833 k = 0;
1834 for (i = 0; i < NUM_CHANNELS; i++) {
1835 if (priv->channel_mask & (1 << i)) {
1836 range.freq[k].i = i + 1;
1837 range.freq[k].m = channel_frequency[i] * 100000;
1838 range.freq[k].e = 1;
1839 k++;
1840 }
1841
1842 if (k >= IW_MAX_FREQUENCIES)
1843 break;
1844 }
1845 range.num_frequency = k;
1846
1847 range.sensitivity = 3;
1848
1849 if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
1850 /* Quality stats meaningless in ad-hoc mode */
1851 range.max_qual.qual = 0;
1852 range.max_qual.level = 0;
1853 range.max_qual.noise = 0;
1854 } else {
1855 range.max_qual.qual = 0x8b - 0x2f;
1856 range.max_qual.level = 0x2f - 0x95 - 1;
1857 range.max_qual.noise = 0x2f - 0x95 - 1;
1858 }
1859
1860 err = dldwd_hw_get_bitratelist(priv, &numrates,
1861 range.bitrate, IW_MAX_BITRATES);
1862 if (err)
1863 return err;
1864 range.num_bitrates = numrates;
1865
1866 /* Set an indication of the max TCP throughput in bit/s that we can
1867 * expect using this interface. May be use for QoS stuff...
1868 * Jean II */
1869 if(numrates > 2)
1870 range.throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
1871 else
1872 range.throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
1873
1874 range.min_rts = 0;
1875 range.max_rts = 2347;
1876 range.min_frag = 256;
1877 range.max_frag = 2346;
1878
1879 dldwd_lock(priv);
1880 if (priv->has_wep) {
1881 range.max_encoding_tokens = MAX_KEYS;
1882
1883 range.encoding_size[0] = SMALL_KEY_SIZE;
1884 range.num_encoding_sizes = 1;
1885
1886 if (priv->has_big_wep) {
1887 range.encoding_size[1] = LARGE_KEY_SIZE;
1888 range.num_encoding_sizes = 2;
1889 }
1890 } else {
1891 range.num_encoding_sizes = 0;
1892 range.max_encoding_tokens = 0;
1893 }
1894 dldwd_unlock(priv);
1895
1896 range.min_pmp = 0;
1897 range.max_pmp = 65535000;
1898 range.min_pmt = 0;
1899 range.max_pmt = 65535 * 1000; /* ??? */
1900 range.pmp_flags = IW_POWER_PERIOD;
1901 range.pmt_flags = IW_POWER_TIMEOUT;
1902 range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
1903
1904 range.num_txpower = 1;
1905 range.txpower[0] = 15; /* 15dBm */
1906 range.txpower_capa = IW_TXPOW_DBM;
1907
1908 #if WIRELESS_EXT > 10
1909 range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
1910 range.retry_flags = IW_RETRY_LIMIT;
1911 range.r_time_flags = IW_RETRY_LIFETIME;
1912 range.min_retry = 0;
1913 range.max_retry = 65535; /* ??? */
1914 range.min_r_time = 0;
1915 range.max_r_time = 65535 * 1000; /* ??? */
1916 #endif /* WIRELESS_EXT > 10 */
1917
1918 if (copy_to_user(rrq->pointer, &range, sizeof(range)))
1919 return -EFAULT;
1920
1921 TRACE_EXIT(dev->name);
1922
1923 return 0;
1924 }
1925
1926 static int dldwd_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq)
1927 {
1928 dldwd_priv_t *priv = dev->priv;
1929 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1930 int setindex = priv->tx_key;
1931 int enable = priv->wep_on;
1932 int restricted = priv->wep_restrict;
1933 uint16_t xlen = 0;
1934 int err = 0;
1935 char keybuf[MAX_KEY_SIZE];
1936
1937 if (erq->pointer) {
1938 /* We actually have a key to set */
1939 if(erq->length > MAX_KEY_SIZE)
1940 return -EINVAL;
1941
1942 if (copy_from_user(keybuf, erq->pointer, erq->length))
1943 return -EFAULT;
1944 }
1945
1946 dldwd_lock(priv);
1947
1948 if (erq->pointer) {
1949 if (erq->length > MAX_KEY_SIZE) {
1950 err = -E2BIG;
1951 goto out;
1952 }
1953
1954 if ( (erq->length > LARGE_KEY_SIZE)
1955 || ( ! priv->has_big_wep && (erq->length > SMALL_KEY_SIZE)) ) {
1956 err = -EINVAL;
1957 goto out;
1958 }
1959
1960 if ((index < 0) || (index >= MAX_KEYS))
1961 index = priv->tx_key;
1962
1963 if (erq->length > SMALL_KEY_SIZE) {
1964 xlen = LARGE_KEY_SIZE;
1965 } else if (erq->length > 0) {
1966 xlen = SMALL_KEY_SIZE;
1967 } else
1968 xlen = 0;
1969
1970 /* Switch on WEP if off */
1971 if ((!enable) && (xlen > 0)) {
1972 setindex = index;
1973 enable = 1;
1974 }
1975 } else {
1976 /* Important note : if the user do "iwconfig eth0 enc off",
1977 * we will arrive there with an index of -1. This is valid
1978 * but need to be taken care off... Jean II */
1979 if ((index < 0) || (index >= MAX_KEYS)) {
1980 if((index != -1) || (erq->flags == 0)) {
1981 err = -EINVAL;
1982 goto out;
1983 }
1984 } else {
1985 /* Set the index : Check that the key is valid */
1986 if(priv->keys[index].len == 0) {
1987 err = -EINVAL;
1988 goto out;
1989 }
1990 setindex = index;
1991 }
1992 }
1993
1994 if (erq->flags & IW_ENCODE_DISABLED)
1995 enable = 0;
1996 /* Only for Prism2 & Symbol cards (so far) - Jean II */
1997 if (erq->flags & IW_ENCODE_OPEN)
1998 restricted = 0;
1999 if (erq->flags & IW_ENCODE_RESTRICTED)
2000 restricted = 1;
2001
2002 if (erq->pointer) {
2003 priv->keys[index].len = cpu_to_le16(xlen);
2004 memset(priv->keys[index].data, 0, sizeof(priv->keys[index].data));
2005 memcpy(priv->keys[index].data, keybuf, erq->length);
2006 }
2007 priv->tx_key = setindex;
2008 priv->wep_on = enable;
2009 priv->wep_restrict = restricted;
2010
2011 out:
2012 dldwd_unlock(priv);
2013
2014 return 0;
2015 }
2016
2017 static int dldwd_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq)
2018 {
2019 dldwd_priv_t *priv = dev->priv;
2020 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2021 uint16_t xlen = 0;
2022 char keybuf[MAX_KEY_SIZE];
2023
2024
2025 dldwd_lock(priv);
2026
2027 if ((index < 0) || (index >= MAX_KEYS))
2028 index = priv->tx_key;
2029
2030 erq->flags = 0;
2031 if (! priv->wep_on)
2032 erq->flags |= IW_ENCODE_DISABLED;
2033 erq->flags |= index + 1;
2034
2035 /* Only for symbol cards - Jean II */
2036 if (priv->firmware_type != FIRMWARE_TYPE_LUCENT) {
2037 if(priv->wep_restrict)
2038 erq->flags |= IW_ENCODE_RESTRICTED;
2039 else
2040 erq->flags |= IW_ENCODE_OPEN;
2041 }
2042
2043 xlen = le16_to_cpu(priv->keys[index].len);
2044
2045 erq->length = xlen;
2046
2047 if (erq->pointer) {
2048 memcpy(keybuf, priv->keys[index].data, MAX_KEY_SIZE);
2049 }
2050
2051 dldwd_unlock(priv);
2052
2053 if (erq->pointer) {
2054 if (copy_to_user(erq->pointer, keybuf, xlen))
2055 return -EFAULT;
2056 }
2057
2058 return 0;
2059 }
2060
2061 static int dldwd_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
2062 {
2063 dldwd_priv_t *priv = dev->priv;
2064 char essidbuf[IW_ESSID_MAX_SIZE+1];
2065
2066 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2067 * anyway... - Jean II */
2068
2069 memset(&essidbuf, 0, sizeof(essidbuf));
2070
2071 if (erq->flags) {
2072 if (erq->length > IW_ESSID_MAX_SIZE)
2073 return -E2BIG;
2074
2075 if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2076 return -EFAULT;
2077
2078 essidbuf[erq->length] = '\0';
2079 }
2080
2081 dldwd_lock(priv);
2082
2083 memcpy(priv->desired_essid, essidbuf, IW_ESSID_MAX_SIZE+1);
2084
2085 dldwd_unlock(priv);
2086
2087 return 0;
2088 }
2089
2090 static int dldwd_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
2091 {
2092 dldwd_priv_t *priv = dev->priv;
2093 char essidbuf[IW_ESSID_MAX_SIZE+1];
2094 int active;
2095 int err = 0;
2096
2097 TRACE_ENTER(dev->name);
2098
2099 err = dldwd_hw_get_essid(priv, &active, essidbuf);
2100 if (err)
2101 return err;
2102
2103 erq->flags = 1;
2104 erq->length = strlen(essidbuf) + 1;
2105 if (erq->pointer)
2106 if ( copy_to_user(erq->pointer, essidbuf, erq->length) )
2107 return -EFAULT;
2108
2109 TRACE_EXIT(dev->name);
2110
2111 return 0;
2112 }
2113
2114 static int dldwd_ioctl_setnick(struct net_device *dev, struct iw_point *nrq)
2115 {
2116 dldwd_priv_t *priv = dev->priv;
2117 char nickbuf[IW_ESSID_MAX_SIZE+1];
2118
2119 if (nrq->length > IW_ESSID_MAX_SIZE)
2120 return -E2BIG;
2121
2122 memset(nickbuf, 0, sizeof(nickbuf));
2123
2124 if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
2125 return -EFAULT;
2126
2127 nickbuf[nrq->length] = '\0';
2128
2129 dldwd_lock(priv);
2130
2131 memcpy(priv->nick, nickbuf, sizeof(priv->nick));
2132
2133 dldwd_unlock(priv);
2134
2135 return 0;
2136 }
2137
2138 static int dldwd_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
2139 {
2140 dldwd_priv_t *priv = dev->priv;
2141 char nickbuf[IW_ESSID_MAX_SIZE+1];
2142
2143 dldwd_lock(priv);
2144 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
2145 dldwd_unlock(priv);
2146
2147 nrq->length = strlen(nickbuf)+1;
2148
2149 if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
2150 return -EFAULT;
2151
2152 return 0;
2153 }
2154
2155 static int dldwd_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
2156 {
2157 dldwd_priv_t *priv = dev->priv;
2158 int chan = -1;
2159
2160 /* We can only use this in Ad-Hoc demo mode to set the operating
2161 * frequency, or in IBSS mode to set the frequency where the IBSS
2162 * will be created - Jean II */
2163 if (priv->iw_mode != IW_MODE_ADHOC)
2164 return -EOPNOTSUPP;
2165
2166 if ( (frq->e == 0) && (frq->m <= 1000) ) {
2167 /* Setting by channel number */
2168 chan = frq->m;
2169 } else {
2170 /* Setting by frequency - search the table */
2171 int mult = 1;
2172 int i;
2173
2174 for (i = 0; i < (6 - frq->e); i++)
2175 mult *= 10;
2176
2177 for (i = 0; i < NUM_CHANNELS; i++)
2178 if (frq->m == (channel_frequency[i] * mult))
2179 chan = i+1;
2180 }
2181
2182 if ( (chan < 1) || (chan > NUM_CHANNELS) ||
2183 ! (priv->channel_mask & (1 << (chan-1)) ) )
2184 return -EINVAL;
2185
2186 dldwd_lock(priv);
2187 priv->channel = chan;
2188 dldwd_unlock(priv);
2189
2190 return 0;
2191 }
2192
2193 static int dldwd_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
2194 {
2195 dldwd_priv_t *priv = dev->priv;
2196 hermes_t *hw = &priv->hw;
2197 uint16_t val;
2198 int err;
2199
2200 dldwd_lock(priv);
2201 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, &val);
2202 dldwd_unlock(priv);
2203
2204 if (err)
2205 return err;
2206
2207 srq->value = val;
2208 srq->fixed = 0; /* auto */
2209
2210 return 0;
2211 }
2212
2213 static int dldwd_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
2214 {
2215 dldwd_priv_t *priv = dev->priv;
2216 int val = srq->value;
2217
2218 if ((val < 1) || (val > 3))
2219 return -EINVAL;
2220
2221 dldwd_lock(priv);
2222 priv->ap_density = val;
2223 dldwd_unlock(priv);
2224
2225 return 0;
2226 }
2227
2228 static int dldwd_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
2229 {
2230 dldwd_priv_t *priv = dev->priv;
2231 int val = rrq->value;
2232
2233 if (rrq->disabled)
2234 val = 2347;
2235
2236 if ( (val < 0) || (val > 2347) )
2237 return -EINVAL;
2238
2239 dldwd_lock(priv);
2240 priv->rts_thresh = val;
2241 dldwd_unlock(priv);
2242
2243 return 0;
2244 }
2245
2246 static int dldwd_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
2247 {
2248 dldwd_priv_t *priv = dev->priv;
2249 int err = 0;
2250
2251 dldwd_lock(priv);
2252
2253 if (priv->has_mwo) {
2254 if (frq->disabled)
2255 priv->mwo_robust = 0;
2256 else {
2257 if (frq->fixed)
2258 printk(KERN_WARNING "%s: Fixed fragmentation not \
2259 supported on this firmware. Using MWO robust instead.\n", dev->name);
2260 priv->mwo_robust = 1;
2261 }
2262 } else {
2263 if (frq->disabled)
2264 priv->frag_thresh = 2346;
2265 else {
2266 if ( (frq->value < 256) || (frq->value > 2346) )
2267 err = -EINVAL;
2268 else
2269 priv->frag_thresh = frq->value & ~0x1; /* must be even */
2270 }
2271 }
2272
2273 dldwd_unlock(priv);
2274
2275 return err;
2276 }
2277
2278 static int dldwd_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
2279 {
2280 dldwd_priv_t *priv = dev->priv;
2281 hermes_t *hw = &priv->hw;
2282 int err = 0;
2283 uint16_t val;
2284
2285 dldwd_lock(priv);
2286
2287 if (priv->has_mwo) {
2288 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_MWO_ROBUST, &val);
2289 if (err)
2290 val = 0;
2291
2292 frq->value = val ? 2347 : 0;
2293 frq->disabled = ! val;
2294 frq->fixed = 0;
2295 } else {
2296 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_FRAG_THRESH, &val);
2297 if (err)
2298 val = 0;
2299
2300 frq->value = val;
2301 frq->disabled = (val >= 2346);
2302 frq->fixed = 1;
2303 }
2304
2305 dldwd_unlock(priv);
2306
2307 return err;
2308 }
2309
2310 static int dldwd_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
2311 {
2312 dldwd_priv_t *priv = dev->priv;
2313 int err = 0;
2314 int rate_ctrl = -1;
2315 int fixed, upto;
2316 int brate;
2317 int i;
2318
2319 dldwd_lock(priv);
2320
2321 /* Normalise value */
2322 brate = rrq->value / 500000;
2323
2324 switch (priv->firmware_type) {
2325 case FIRMWARE_TYPE_LUCENT: /* Lucent style rate */
2326 if (! rrq->fixed) {
2327 if (brate > 0)
2328 brate = -brate;
2329 else
2330 brate = -22;
2331 }
2332
2333 for (i = 0; i < NUM_RATES; i++)
2334 if (rate_list[i] == brate) {
2335 rate_ctrl = i;
2336 break;
2337 }
2338
2339 if ( (rate_ctrl < 1) || (rate_ctrl >= NUM_RATES) )
2340 err = -EINVAL;
2341 else
2342 priv->tx_rate_ctrl = rate_ctrl;
2343 break;
2344 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
2345 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
2346 switch(brate) {
2347 case 0:
2348 fixed = 0x0;
2349 upto = 0xF;
2350 break;
2351 case 2:
2352 fixed = 0x1;
2353 upto = 0x1;
2354 break;
2355 case 4:
2356 fixed = 0x2;
2357 upto = 0x3;
2358 break;
2359 case 11:
2360 fixed = 0x4;
2361 upto = 0x7;
2362 break;
2363 case 22:
2364 fixed = 0x8;
2365 upto = 0xF;
2366 break;
2367 default:
2368 fixed = 0x0;
2369 upto = 0x0;
2370 }
2371 if (rrq->fixed)
2372 rate_ctrl = fixed;
2373 else
2374 rate_ctrl = upto;
2375 if (rate_ctrl == 0)
2376 err = -EINVAL;
2377 else
2378 priv->tx_rate_ctrl = rate_ctrl;
2379 break;
2380 }
2381
2382 dldwd_unlock(priv);
2383
2384 return err;
2385 }
2386
2387 static int dldwd_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
2388 {
2389 dldwd_priv_t *priv = dev->priv;
2390 hermes_t *hw = &priv->hw;
2391 int err = 0;
2392 uint16_t val;
2393 int brate = 0;
2394
2395 dldwd_lock(priv);
2396 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_RATE_CTRL, &val);
2397 if (err)
2398 goto out;
2399
2400 switch (priv->firmware_type) {
2401 case FIRMWARE_TYPE_LUCENT: /* Lucent style rate */
2402 brate = rate_list[val];
2403
2404 if (brate < 0) {
2405 rrq->fixed = 0;
2406
2407 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_TX_RATE, &val);
2408 if (err)
2409 goto out;
2410
2411 if (val == 6)
2412 brate = 11;
2413 else
2414 brate = 2*val;
2415 } else
2416 rrq->fixed = 1;
2417 break;
2418 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
2419 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
2420 /* Check if auto or fixed (crude approximation) */
2421 if((val & 0x1) && (val > 1)) {
2422 rrq->fixed = 0;
2423
2424 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_TX_RATE, &val);
2425 if (err)
2426 goto out;
2427 } else
2428 rrq->fixed = 1;
2429
2430 if(val >= 8)
2431 brate = 22;
2432 else if(val >= 4)
2433 brate = 11;
2434 else if(val >= 2)
2435 brate = 4;
2436 else
2437 brate = 2;
2438 break;
2439 }
2440
2441 rrq->value = brate * 500000;
2442 rrq->disabled = 0;
2443
2444 out:
2445 dldwd_unlock(priv);
2446
2447 return err;
2448 }
2449
2450 static int dldwd_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
2451 {
2452 dldwd_priv_t *priv = dev->priv;
2453 int err = 0;
2454
2455
2456 dldwd_lock(priv);
2457
2458 if (prq->disabled) {
2459 priv->pm_on = 0;
2460 } else {
2461 switch (prq->flags & IW_POWER_MODE) {
2462 case IW_POWER_UNICAST_R:
2463 priv->pm_mcast = 0;
2464 priv->pm_on = 1;
2465 break;
2466 case IW_POWER_ALL_R:
2467 priv->pm_mcast = 1;
2468 priv->pm_on = 1;
2469 break;
2470 case IW_POWER_ON:
2471 /* No flags : but we may have a value - Jean II */
2472 break;
2473 default:
2474 err = -EINVAL;
2475 }
2476 if (err)
2477 goto out;
2478
2479 if (prq->flags & IW_POWER_TIMEOUT) {
2480 priv->pm_on = 1;
2481 priv->pm_timeout = prq->value / 1000;
2482 }
2483 if (prq->flags & IW_POWER_PERIOD) {
2484 priv->pm_on = 1;
2485 priv->pm_period = prq->value / 1000;
2486 }
2487 /* It's valid to not have a value if we are just toggling
2488 * the flags... Jean II */
2489 if(!priv->pm_on) {
2490 err = -EINVAL;
2491 goto out;
2492 }
2493 }
2494
2495 out:
2496 dldwd_unlock(priv);
2497
2498 return err;
2499 }
2500
2501 static int dldwd_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
2502 {
2503 dldwd_priv_t *priv = dev->priv;
2504 hermes_t *hw = &priv->hw;
2505 int err = 0;
2506 uint16_t enable, period, timeout, mcast;
2507
2508 dldwd_lock(priv);
2509
2510 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_ENABLE, &enable);
2511 if (err)
2512 goto out;
2513
2514 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD, &period);
2515 if (err)
2516 goto out;
2517
2518 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER, &timeout);
2519 if (err)
2520 goto out;
2521
2522 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_MCAST_RX, &mcast);
2523 if (err)
2524 goto out;
2525
2526 prq->disabled = !enable;
2527 /* Note : by default, display the period */
2528 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
2529 prq->flags = IW_POWER_TIMEOUT;
2530 prq->value = timeout * 1000;
2531 } else {
2532 prq->flags = IW_POWER_PERIOD;
2533 prq->value = period * 1000;
2534 }
2535 if (mcast)
2536 prq->flags |= IW_POWER_ALL_R;
2537 else
2538 prq->flags |= IW_POWER_UNICAST_R;
2539
2540 out:
2541 dldwd_unlock(priv);
2542
2543 return err;
2544 }
2545
2546 #if WIRELESS_EXT > 10
2547 static int dldwd_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
2548 {
2549 dldwd_priv_t *priv = dev->priv;
2550 hermes_t *hw = &priv->hw;
2551 int err = 0;
2552 uint16_t short_limit, long_limit, lifetime;
2553
2554 dldwd_lock(priv);
2555
2556 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORT_RETRY_LIMIT, &short_limit);
2557 if (err)
2558 goto out;
2559
2560 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONG_RETRY_LIMIT, &long_limit);
2561 if (err)
2562 goto out;
2563
2564 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAX_TX_LIFETIME, &lifetime);
2565 if (err)
2566 goto out;
2567
2568 rrq->disabled = 0; /* Can't be disabled */
2569
2570 /* Note : by default, display the retry number */
2571 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
2572 rrq->flags = IW_RETRY_LIFETIME;
2573 rrq->value = lifetime * 1000; /* ??? */
2574 } else {
2575 /* By default, display the min number */
2576 if ((rrq->flags & IW_RETRY_MAX)) {
2577 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
2578 rrq->value = long_limit;
2579 } else {
2580 rrq->flags = IW_RETRY_LIMIT;
2581 rrq->value = short_limit;
2582 if(short_limit != long_limit)
2583 rrq->flags |= IW_RETRY_MIN;
2584 }
2585 }
2586
2587 out:
2588 dldwd_unlock(priv);
2589
2590 return err;
2591 }
2592 #endif /* WIRELESS_EXT > 10 */
2593
2594 static int dldwd_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
2595 {
2596 dldwd_priv_t *priv = dev->priv;
2597 int val = *( (int *) wrq->u.name );
2598
2599 dldwd_lock(priv);
2600 priv->ibss_port = val ;
2601
2602 /* Actually update the mode we are using */
2603 set_port_type(priv);
2604
2605 dldwd_unlock(priv);
2606 return 0;
2607 }
2608
2609 static int dldwd_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq)
2610 {
2611 dldwd_priv_t *priv = dev->priv;
2612 int *val = (int *)wrq->u.name;
2613
2614 dldwd_lock(priv);
2615 *val = priv->ibss_port;
2616 dldwd_unlock(priv);
2617
2618 return 0;
2619 }
2620
2621 static int dldwd_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
2622 {
2623 dldwd_priv_t *priv = dev->priv;
2624 int val = *( (int *) wrq->u.name );
2625 int err = 0;
2626
2627 dldwd_lock(priv);
2628 switch (val) {
2629 case 0: /* Try to do IEEE ad-hoc mode */
2630 if (! priv->has_ibss) {
2631 err = -EINVAL;
2632 break;
2633 }
2634 DEBUG(2, "%s: Prefer IBSS Ad-Hoc mode\n", dev->name);
2635 priv->prefer_port3 = 0;
2636
2637 break;
2638
2639 case 1: /* Try to do Lucent proprietary ad-hoc mode */
2640 if (! priv->has_port3) {
2641 err = -EINVAL;
2642 break;
2643 }
2644 DEBUG(2, "%s: Prefer Ad-Hoc demo mode\n", dev->name);
2645 priv->prefer_port3 = 1;
2646 break;
2647
2648 default:
2649 err = -EINVAL;
2650 }
2651
2652 if (! err)
2653 /* Actually update the mode we are using */
2654 set_port_type(priv);
2655
2656 dldwd_unlock(priv);
2657
2658 return err;
2659 }
2660
2661 static int dldwd_ioctl_getport3(struct net_device *dev, struct iwreq *wrq)
2662 {
2663 dldwd_priv_t *priv = dev->priv;
2664 int *val = (int *)wrq->u.name;
2665
2666 dldwd_lock(priv);
2667 *val = priv->prefer_port3;
2668 dldwd_unlock(priv);
2669
2670 return 0;
2671 }
2672
2673 /* Spy is used for link quality/strength measurements in Ad-Hoc mode
2674 * Jean II */
2675 static int dldwd_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
2676 {
2677 dldwd_priv_t *priv = dev->priv;
2678 struct sockaddr address[IW_MAX_SPY];
2679 int number = srq->length;
2680 int i;
2681 int err = 0;
2682
2683 /* Check the number of addresses */
2684 if (number > IW_MAX_SPY)
2685 return -E2BIG;
2686
2687 /* Get the data in the driver */
2688 if (srq->pointer) {
2689 if (copy_from_user(address, srq->pointer,
2690 sizeof(struct sockaddr) * number))
2691 return -EFAULT;
2692 }
2693
2694 /* Make sure nobody mess with the structure while we do */
2695 dldwd_lock(priv);
2696
2697 /* dldwd_lock() doesn't disable interrupts, so make sure the
2698 * interrupt rx path don't get confused while we copy */
2699 priv->spy_number = 0;
2700
2701 if (number > 0) {
2702 /* Extract the addresses */
2703 for (i = 0; i < number; i++)
2704 memcpy(priv->spy_address[i], address[i].sa_data,
2705 ETH_ALEN);
2706 /* Reset stats */
2707 memset(priv->spy_stat, 0,
2708 sizeof(struct iw_quality) * IW_MAX_SPY);
2709 /* Set number of addresses */
2710 priv->spy_number = number;
2711 }
2712
2713 /* Time to show what we have done... */
2714 DEBUG(0, "%s: New spy list:\n", dev->name);
2715 for (i = 0; i < number; i++) {
2716 DEBUG(0, "%s: %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
2717 dev->name, i+1,
2718 priv->spy_address[i][0], priv->spy_address[i][1],
2719 priv->spy_address[i][2], priv->spy_address[i][3],
2720 priv->spy_address[i][4], priv->spy_address[i][5]);
2721 }
2722
2723 /* Now, let the others play */
2724 dldwd_unlock(priv);
2725
2726 return err;
2727 }
2728
2729 static int dldwd_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
2730 {
2731 dldwd_priv_t *priv = dev->priv;
2732 struct sockaddr address[IW_MAX_SPY];
2733 struct iw_quality spy_stat[IW_MAX_SPY];
2734 int number;
2735 int i;
2736
2737 dldwd_lock(priv);
2738
2739 number = priv->spy_number;
2740 if ((number > 0) && (srq->pointer)) {
2741 /* Create address struct */
2742 for (i = 0; i < number; i++) {
2743 memcpy(address[i].sa_data, priv->spy_address[i],
2744 ETH_ALEN);
2745 address[i].sa_family = AF_UNIX;
2746 }
2747 /* Copy stats */
2748 /* In theory, we should disable irqs while copying the stats
2749 * because the rx path migh update it in the middle...
2750 * Bah, who care ? - Jean II */
2751 memcpy(&spy_stat, priv->spy_stat,
2752 sizeof(struct iw_quality) * IW_MAX_SPY);
2753 for (i=0; i < number; i++)
2754 priv->spy_stat[i].updated = 0;
2755 }
2756
2757 dldwd_unlock(priv);
2758
2759 /* Push stuff to user space */
2760 srq->length = number;
2761 if(copy_to_user(srq->pointer, address,
2762 sizeof(struct sockaddr) * number))
2763 return -EFAULT;
2764 if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
2765 &spy_stat, sizeof(struct iw_quality) * number))
2766 return -EFAULT;
2767
2768 return 0;
2769 }
2770
2771 int
2772 dldwd_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2773 {
2774 dldwd_priv_t *priv = dev->priv;
2775 struct iwreq *wrq = (struct iwreq *)rq;
2776 int err = 0;
2777 int changed = 0;
2778
2779 TRACE_ENTER(dev->name);
2780
2781 /* In theory, we could allow most of the the SET stuff to be done
2782 * In practice, the laps of time at startup when the card is not
2783 * ready is very short, so why bother...
2784 * Note that hw_ready is different from up/down (ifconfig), when
2785 * the device is not yet up, it is usually already ready...
2786 * Jean II */
2787 if (!priv->hw_ready)
2788 return -ENODEV;
2789
2790 switch (cmd) {
2791 case SIOCGIWNAME:
2792 DEBUG(1, "%s: SIOCGIWNAME\n", dev->name);
2793 strcpy(wrq->u.name, "IEEE 802.11-DS");
2794 break;
2795
2796 case SIOCGIWAP:
2797 DEBUG(1, "%s: SIOCGIWAP\n", dev->name);
2798 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
2799 err = dldwd_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
2800 break;
2801
2802 case SIOCGIWRANGE:
2803 DEBUG(1, "%s: SIOCGIWRANGE\n", dev->name);
2804 err = dldwd_ioctl_getiwrange(dev, &wrq->u.data);
2805 break;
2806
2807 case SIOCSIWMODE:
2808 DEBUG(1, "%s: SIOCSIWMODE\n", dev->name);
2809 dldwd_lock(priv);
2810 switch (wrq->u.mode) {
2811 case IW_MODE_ADHOC:
2812 if (! (priv->has_ibss || priv->has_port3) )
2813 err = -EINVAL;
2814 else {
2815 priv->iw_mode = IW_MODE_ADHOC;
2816 changed = 1;
2817 }
2818 break;
2819
2820 case IW_MODE_INFRA:
2821 priv->iw_mode = IW_MODE_INFRA;
2822 changed = 1;
2823 break;
2824
2825 default:
2826 err = -EINVAL;
2827 break;
2828 }
2829 set_port_type(priv);
2830 dldwd_unlock(priv);
2831 break;
2832
2833 case SIOCGIWMODE:
2834 DEBUG(1, "%s: SIOCGIWMODE\n", dev->name);
2835 dldwd_lock(priv);
2836 wrq->u.mode = priv->iw_mode;
2837 dldwd_unlock(priv);
2838 break;
2839
2840 case SIOCSIWENCODE:
2841 DEBUG(1, "%s: SIOCSIWENCODE\n", dev->name);
2842 if (! priv->has_wep) {
2843 err = -EOPNOTSUPP;
2844 break;
2845 }
2846
2847 err = dldwd_ioctl_setiwencode(dev, &wrq->u.encoding);
2848 if (! err)
2849 changed = 1;
2850 break;
2851
2852 case SIOCGIWENCODE:
2853 DEBUG(1, "%s: SIOCGIWENCODE\n", dev->name);
2854 if (! priv->has_wep) {
2855 err = -EOPNOTSUPP;
2856 break;
2857 }
2858
2859 if (! capable(CAP_NET_ADMIN)) {
2860 err = -EPERM;
2861 break;
2862 }
2863
2864 err = dldwd_ioctl_getiwencode(dev, &wrq->u.encoding);
2865 break;
2866
2867 case SIOCSIWESSID:
2868 DEBUG(1, "%s: SIOCSIWESSID\n", dev->name);
2869 err = dldwd_ioctl_setessid(dev, &wrq->u.essid);
2870 if (! err)
2871 changed = 1;
2872 break;
2873
2874 case SIOCGIWESSID:
2875 DEBUG(1, "%s: SIOCGIWESSID\n", dev->name);
2876 err = dldwd_ioctl_getessid(dev, &wrq->u.essid);
2877 break;
2878
2879 case SIOCSIWNICKN:
2880 DEBUG(1, "%s: SIOCSIWNICKN\n", dev->name);
2881 err = dldwd_ioctl_setnick(dev, &wrq->u.data);
2882 if (! err)
2883 changed = 1;
2884 break;
2885
2886 case SIOCGIWNICKN:
2887 DEBUG(1, "%s: SIOCGIWNICKN\n", dev->name);
2888 err = dldwd_ioctl_getnick(dev, &wrq->u.data);
2889 break;
2890
2891 case SIOCGIWFREQ:
2892 DEBUG(1, "%s: SIOCGIWFREQ\n", dev->name);
2893 wrq->u.freq.m = dldwd_hw_get_freq(priv);
2894 wrq->u.freq.e = 1;
2895 break;
2896
2897 case SIOCSIWFREQ:
2898 DEBUG(1, "%s: SIOCSIWFREQ\n", dev->name);
2899 err = dldwd_ioctl_setfreq(dev, &wrq->u.freq);
2900 if (! err)
2901 changed = 1;
2902 break;
2903
2904 case SIOCGIWSENS:
2905 DEBUG(1, "%s: SIOCGIWSENS\n", dev->name);
2906 err = dldwd_ioctl_getsens(dev, &wrq->u.sens);
2907 break;
2908
2909 case SIOCSIWSENS:
2910 DEBUG(1, "%s: SIOCSIWSENS\n", dev->name);
2911 err = dldwd_ioctl_setsens(dev, &wrq->u.sens);
2912 if (! err)
2913 changed = 1;
2914 break;
2915
2916 case SIOCGIWRTS:
2917 DEBUG(1, "%s: SIOCGIWRTS\n", dev->name);
2918 wrq->u.rts.value = priv->rts_thresh;
2919 wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
2920 wrq->u.rts.fixed = 1;
2921 break;
2922
2923 case SIOCSIWRTS:
2924 DEBUG(1, "%s: SIOCSIWRTS\n", dev->name);
2925 err = dldwd_ioctl_setrts(dev, &wrq->u.rts);
2926 if (! err)
2927 changed = 1;
2928 break;
2929
2930 case SIOCSIWFRAG:
2931 DEBUG(1, "%s: SIOCSIWFRAG\n", dev->name);
2932 err = dldwd_ioctl_setfrag(dev, &wrq->u.frag);
2933 if (! err)
2934 changed = 1;
2935 break;
2936
2937 case SIOCGIWFRAG:
2938 DEBUG(1, "%s: SIOCGIWFRAG\n", dev->name);
2939 err = dldwd_ioctl_getfrag(dev, &wrq->u.frag);
2940 break;
2941
2942 case SIOCSIWRATE:
2943 DEBUG(1, "%s: SIOCSIWRATE\n", dev->name);
2944 err = dldwd_ioctl_setrate(dev, &wrq->u.bitrate);
2945 if (! err)
2946 changed = 1;
2947 break;
2948
2949 case SIOCGIWRATE:
2950 DEBUG(1, "%s: SIOCGIWRATE\n", dev->name);
2951 err = dldwd_ioctl_getrate(dev, &wrq->u.bitrate);
2952 break;
2953
2954 case SIOCSIWPOWER:
2955 DEBUG(1, "%s: SIOCSIWPOWER\n", dev->name);
2956 err = dldwd_ioctl_setpower(dev, &wrq->u.power);
2957 if (! err)
2958 changed = 1;
2959 break;
2960
2961 case SIOCGIWPOWER:
2962 DEBUG(1, "%s: SIOCGIWPOWER\n", dev->name);
2963 err = dldwd_ioctl_getpower(dev, &wrq->u.power);
2964 break;
2965
2966 case SIOCGIWTXPOW:
2967 DEBUG(1, "%s: SIOCGIWTXPOW\n", dev->name);
2968 /* The card only supports one tx power, so this is easy */
2969 wrq->u.txpower.value = 15; /* dBm */
2970 wrq->u.txpower.fixed = 1;
2971 wrq->u.txpower.disabled = 0;
2972 wrq->u.txpower.flags = IW_TXPOW_DBM;
2973 break;
2974
2975 #if WIRELESS_EXT > 10
2976 case SIOCSIWRETRY:
2977 DEBUG(1, "%s: SIOCSIWRETRY\n", dev->name);
2978 err = -EOPNOTSUPP;
2979 break;
2980
2981 case SIOCGIWRETRY:
2982 DEBUG(1, "%s: SIOCGIWRETRY\n", dev->name);
2983 err = dldwd_ioctl_getretry(dev, &wrq->u.retry);
2984 break;
2985 #endif /* WIRELESS_EXT > 10 */
2986
2987 case SIOCSIWSPY:
2988 DEBUG(1, "%s: SIOCSIWSPY\n", dev->name);
2989
2990 err = dldwd_ioctl_setspy(dev, &wrq->u.data);
2991 break;
2992
2993 case SIOCGIWSPY:
2994 DEBUG(1, "%s: SIOCGIWSPY\n", dev->name);
2995
2996 err = dldwd_ioctl_getspy(dev, &wrq->u.data);
2997 break;
2998
2999 case SIOCGIWPRIV:
3000 DEBUG(1, "%s: SIOCGIWPRIV\n", dev->name);
3001 if (wrq->u.data.pointer) {
3002 struct iw_priv_args privtab[] = {
3003 { SIOCDEVPRIVATE + 0x0, 0, 0, "force_reset" },
3004 { SIOCDEVPRIVATE + 0x1, 0, 0, "card_reset" },
3005 { SIOCDEVPRIVATE + 0x2,
3006 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3007 0, "set_port3" },
3008 { SIOCDEVPRIVATE + 0x3, 0,
3009 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3010 "get_port3" },
3011 { SIOCDEVPRIVATE + 0x4,
3012 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3013 0, "set_preamble" },
3014 { SIOCDEVPRIVATE + 0x5, 0,
3015 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3016 "get_preamble" },
3017 { SIOCDEVPRIVATE + 0x6,
3018 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3019 0, "set_ibssport" },
3020 { SIOCDEVPRIVATE + 0x7, 0,
3021 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3022 "get_ibssport" }
3023 };
3024
3025 err = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab));
3026 if (err)
3027 break;
3028
3029 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
3030 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
3031 err = -EFAULT;
3032 }
3033 break;
3034
3035 case SIOCDEVPRIVATE + 0x0: /* force_reset */
3036 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x0 (force_reset)\n",
3037 dev->name);
3038 if (! capable(CAP_NET_ADMIN)) {
3039 err = -EPERM;
3040 break;
3041 }
3042
3043 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
3044 dldwd_reset(priv);
3045 break;
3046
3047 case SIOCDEVPRIVATE + 0x1: /* card_reset */
3048 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x1 (card_reset)\n",
3049 dev->name);
3050 if (! capable(CAP_NET_ADMIN)) {
3051 err = -EPERM;
3052 break;
3053 }
3054
3055 printk(KERN_DEBUG "%s: Forcing card reset!\n", dev->name);
3056 if(priv->card_reset_handler != NULL)
3057 priv->card_reset_handler(priv);
3058 dldwd_reset(priv);
3059 break;
3060
3061 case SIOCDEVPRIVATE + 0x2: /* set_port3 */
3062 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x2 (set_port3)\n",
3063 dev->name);
3064 if (! capable(CAP_NET_ADMIN)) {
3065 err = -EPERM;
3066 break;
3067 }
3068
3069 err = dldwd_ioctl_setport3(dev, wrq);
3070 if (! err)
3071 changed = 1;
3072 break;
3073
3074 case SIOCDEVPRIVATE + 0x3: /* get_port3 */
3075 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x3 (get_port3)\n",
3076 dev->name);
3077 err = dldwd_ioctl_getport3(dev, wrq);
3078 break;
3079
3080 case SIOCDEVPRIVATE + 0x4: /* set_preamble */
3081 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x4 (set_preamble)\n",
3082 dev->name);
3083 if (! capable(CAP_NET_ADMIN)) {
3084 err = -EPERM;
3085 break;
3086 }
3087
3088 /* 802.11b has recently defined some short preamble.
3089 * Basically, the Phy header has been reduced in size.
3090 * This increase performance, especially at high rates
3091 * (the preamble is transmitted at 1Mb/s), unfortunately
3092 * this give compatibility troubles... - Jean II */
3093 if(priv->has_preamble) {
3094 int val = *( (int *) wrq->u.name );
3095
3096 dldwd_lock(priv);
3097 if(val)
3098 priv->preamble = 1;
3099 else
3100 priv->preamble = 0;
3101 dldwd_unlock(priv);
3102 changed = 1;
3103 } else
3104 err = -EOPNOTSUPP;
3105 break;
3106
3107 case SIOCDEVPRIVATE + 0x5: /* get_preamble */
3108 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x5 (get_preamble)\n",
3109 dev->name);
3110 if(priv->has_preamble) {
3111 int *val = (int *)wrq->u.name;
3112
3113 dldwd_lock(priv);
3114 *val = priv->preamble;
3115 dldwd_unlock(priv);
3116 } else
3117 err = -EOPNOTSUPP;
3118 break;
3119 case SIOCDEVPRIVATE + 0x6: /* set_ibssport */
3120 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x6 (set_ibssport)\n",
3121 dev->name);
3122 if (! capable(CAP_NET_ADMIN)) {
3123 err = -EPERM;
3124 break;
3125 }
3126
3127 err = dldwd_ioctl_setibssport(dev, wrq);
3128 if (! err)
3129 changed = 1;
3130 break;
3131
3132 case SIOCDEVPRIVATE + 0x7: /* get_ibssport */
3133 DEBUG(1, "%s: SIOCDEVPRIVATE + 0x7 (get_ibssport)\n",
3134 dev->name);
3135 err = dldwd_ioctl_getibssport(dev, wrq);
3136 break;
3137
3138
3139 default:
3140 err = -EOPNOTSUPP;
3141 }
3142
3143 if (! err && changed && netif_running(dev)) {
3144 err = dldwd_reset(priv);
3145 if (err) {
3146 /* Ouch ! What are we supposed to do ? */
3147 printk(KERN_ERR "orinoco_cs: Failed to set parameters on %s\n",
3148 dev->name);
3149 netif_stop_queue(dev);
3150 dldwd_shutdown(priv);
3151 priv->hw_ready = 0;
3152 }
3153 }
3154
3155 TRACE_EXIT(dev->name);
3156
3157 return err;
3158 }
3159
3160 int
3161 dldwd_change_mtu(struct net_device *dev, int new_mtu)
3162 {
3163 TRACE_ENTER(dev->name);
3164
3165 if ( (new_mtu < DLDWD_MIN_MTU) || (new_mtu > DLDWD_MAX_MTU) )
3166 return -EINVAL;
3167
3168 dev->mtu = new_mtu;
3169
3170 TRACE_EXIT(dev->name);
3171
3172 return 0;
3173 }
3174
3175 static void
3176 __dldwd_set_multicast_list(struct net_device *dev)
3177 {
3178 dldwd_priv_t *priv = dev->priv;
3179 hermes_t *hw = &priv->hw;
3180 int err = 0;
3181 int promisc, allmulti, mc_count;
3182
3183 /* We'll wait until it's ready. Anyway, the network doesn't call us
3184 * here until we are open - Jean II */
3185 if (!priv->hw_ready)
3186 return;
3187
3188
3189 TRACE_ENTER(dev->name);
3190
3191 DEBUG(3, "dev->flags=0x%x, priv->promiscuous=%d, dev->mc_count=%d priv->mc_count=%d\n",
3192 dev->flags, priv->promiscuous, dev->mc_count, priv->mc_count);
3193
3194 /* The Hermes doesn't seem to have an allmulti mode, so we go
3195 * into promiscuous mode and let the upper levels deal. */
3196 if ( (dev->flags & IFF_PROMISC) ) {
3197 promisc = 1;
3198 allmulti = 0;
3199 mc_count = 0;
3200 } else if ( (dev->flags & IFF_ALLMULTI) ||
3201 (dev->mc_count > HERMES_MAX_MULTICAST) ) {
3202 promisc = 0;
3203 allmulti = 1;
3204 mc_count = HERMES_MAX_MULTICAST;
3205 } else {
3206 promisc = 0;
3207 allmulti = 0;
3208 mc_count = dev->mc_count;
3209 }
3210
3211 DEBUG(3, "promisc=%d mc_count=%d\n",
3212 promisc, mc_count);
3213
3214 if (promisc != priv->promiscuous) { /* Don't touch the hardware if we don't have to */
3215 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PROMISCUOUS,
3216 promisc);
3217 if (err) {
3218 printk(KERN_ERR "%s: Error %d setting promiscuity to %d.\n",
3219 dev->name, err, promisc);
3220 } else
3221 priv->promiscuous = promisc;
3222 }
3223
3224 if (allmulti) {
3225 /* FIXME: This method of doing allmulticast reception
3226 comes from the NetBSD driver. Haven't actually
3227 tested whether it works or not. */
3228 hermes_multicast_t mclist;
3229
3230 memset(&mclist, 0, sizeof(mclist));
3231 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNF_MULTICAST_LIST, &mclist);
3232 if (err)
3233 printk(KERN_ERR "%s: Error %d setting multicast list.\n",
3234 dev->name, err);
3235 else
3236 priv->allmulti = 1;
3237
3238 } else if (mc_count || (! mc_count && priv->mc_count) ) {
3239 struct dev_mc_list *p = dev->mc_list;
3240 hermes_multicast_t mclist;
3241 int i;
3242
3243 for (i = 0; i < mc_count; i++) {
3244 /* First some paranoid checks */
3245 if (! p) {
3246 printk(KERN_ERR "%s: Multicast list shorter than mc_count.\n",
3247 dev->name);
3248 break;
3249 }
3250 if (p->dmi_addrlen != ETH_ALEN) {
3251
3252 printk(KERN_ERR "%s: Bad address size (%d) in multicast list.\n",
3253 dev->name, p->dmi_addrlen);
3254 break;
3255 }
3256
3257 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
3258 p = p->next;
3259 }
3260
3261 /* More paranoia */
3262 if (p)
3263 printk(KERN_ERR "%s: Multicast list longer than mc_count.\n",
3264 dev->name);
3265
3266 priv->mc_count = i;
3267
3268 DEBUG(3, "priv->mc_count = %d\n", priv->mc_count);
3269
3270 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNF_MULTICAST_LIST,
3271 HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
3272 &mclist);
3273 if (err)
3274 printk(KERN_ERR "%s: Error %d setting multicast list.\n",
3275 dev->name, err);
3276 else
3277 priv->allmulti = 0;
3278 }
3279
3280 /* Since we can set the promiscuous flag when it wasn't asked
3281 for, make sure the net_device knows about it. */
3282 if (priv->promiscuous)
3283 dev->flags |= IFF_PROMISC;
3284 else
3285 dev->flags &= ~IFF_PROMISC;
3286
3287 if (priv->allmulti)
3288 dev->flags |= IFF_ALLMULTI;
3289 else
3290 dev->flags &= ~IFF_ALLMULTI;
3291
3292 TRACE_EXIT(dev->name);
3293 }
3294
3295 /*
3296 * procfs stuff
3297 */
3298
3299 static struct proc_dir_entry *dir_base = NULL;
3300
3301 /*
3302 * This function updates the total amount of data printed so far. It then
3303 * determines if the amount of data printed into a buffer has reached the
3304 * offset requested. If it hasn't, then the buffer is shifted over so that
3305 * the next bit of data can be printed over the old bit. If the total
3306 * amount printed so far exceeds the total amount requested, then this
3307 * function returns 1, otherwise 0.
3308 */
3309 static int
3310
3311 shift_buffer(char *buffer, int requested_offset, int requested_len,
3312 int *total, int *slop, char **buf)
3313 {
3314 int printed;
3315
3316 printed = *buf - buffer;
3317 if (*total + printed <= requested_offset) {
3318 *total += printed;
3319 *buf = buffer;
3320 }
3321 else {
3322 if (*total < requested_offset) {
3323 *slop = requested_offset - *total;
3324 }
3325 *total = requested_offset + printed - *slop;
3326 }
3327 if (*total > requested_offset + requested_len) {
3328 return 1;
3329 }
3330 else {
3331 return 0;
3332 }
3333 }
3334
3335 /*
3336 * This function calculates the actual start of the requested data
3337 * in the buffer. It also calculates actual length of data returned,
3338 * which could be less that the amount of data requested.
3339 */
3340 #define PROC_BUFFER_SIZE 4096
3341 #define PROC_SAFE_SIZE 3072
3342
3343 static int
3344 calc_start_len(char *buffer, char **start, int requested_offset,
3345 int requested_len, int total, char *buf)
3346 {
3347 int return_len, buffer_len;
3348
3349 buffer_len = buf - buffer;
3350 if (buffer_len >= PROC_BUFFER_SIZE - 1) {
3351 printk(KERN_ERR "calc_start_len: exceeded /proc buffer size\n");
3352 }
3353
3354 /*
3355 * There may be bytes before and after the
3356 * chunk that was actually requested.
3357 */
3358 return_len = total - requested_offset;
3359 if (return_len < 0) {
3360 return_len = 0;
3361 }
3362 *start = buf - return_len;
3363 if (return_len > requested_len) {
3364 return_len = requested_len;
3365 }
3366 return return_len;
3367 }
3368
3369 static int
3370 dldwd_proc_get_hermes_regs(char *page, char **start, off_t requested_offset,
3371 int requested_len, int *eof, void *data)
3372 {
3373 dldwd_priv_t *dev = (dldwd_priv_t *)data;
3374 hermes_t *hw = &dev->hw;
3375 char *buf;
3376 int total = 0, slop = 0;
3377
3378 /* Hum, in this case hardware register are probably not readable... */
3379 if (!dev->hw_ready)
3380 return -ENODEV;
3381
3382 buf = page;
3383
3384 #define DHERMESREG(name) buf += sprintf(buf, "%-16s: %04x\n", #name, hermes_read_regn(hw, name))
3385
3386 DHERMESREG(CMD);
3387 DHERMESREG(PARAM0);
3388 DHERMESREG(PARAM1);
3389 DHERMESREG(PARAM2);
3390 DHERMESREG(STATUS);
3391 DHERMESREG(RESP0);
3392 DHERMESREG(RESP1);
3393 DHERMESREG(RESP2);
3394 DHERMESREG(INFOFID);
3395 DHERMESREG(RXFID);
3396 DHERMESREG(ALLOCFID);
3397 DHERMESREG(TXCOMPLFID);
3398 DHERMESREG(SELECT0);
3399 DHERMESREG(OFFSET0);
3400 DHERMESREG(SELECT1);
3401 DHERMESREG(OFFSET1);
3402 DHERMESREG(EVSTAT);
3403 DHERMESREG(INTEN);
3404 DHERMESREG(EVACK);
3405 DHERMESREG(CONTROL);
3406 DHERMESREG(SWSUPPORT0);
3407 DHERMESREG(SWSUPPORT1);
3408 DHERMESREG(SWSUPPORT2);
3409 DHERMESREG(AUXPAGE);
3410 DHERMESREG(AUXOFFSET);
3411 DHERMESREG(AUXDATA);
3412 #undef DHERMESREG
3413
3414 shift_buffer(page, requested_offset, requested_len, &total,
3415 &slop, &buf);
3416 return calc_start_len(page, start, requested_offset, requested_len,
3417 total, buf);
3418 }
3419
3420 struct {
3421 uint16_t rid;
3422 char *name;
3423 int minlen, maxlen;
3424 int displaytype;
3425 #define DISPLAY_WORDS 0
3426 #define DISPLAY_BYTES 1
3427 #define DISPLAY_STRING 2
3428 } record_table[] = {
3429 #define RTCNFENTRY(name, type) { HERMES_RID_CNF_##name, #name, 0, LTV_BUF_SIZE, type }
3430 RTCNFENTRY(PORTTYPE, DISPLAY_WORDS),
3431 RTCNFENTRY(MACADDR, DISPLAY_BYTES),
3432 RTCNFENTRY(DESIRED_SSID, DISPLAY_STRING),
3433 RTCNFENTRY(CHANNEL, DISPLAY_WORDS),
3434 RTCNFENTRY(OWN_SSID, DISPLAY_STRING),
3435 RTCNFENTRY(SYSTEM_SCALE, DISPLAY_WORDS),
3436 RTCNFENTRY(MAX_DATA_LEN, DISPLAY_WORDS),
3437 RTCNFENTRY(PM_ENABLE, DISPLAY_WORDS),
3438 RTCNFENTRY(PM_MCAST_RX, DISPLAY_WORDS),
3439 RTCNFENTRY(PM_PERIOD, DISPLAY_WORDS),
3440 RTCNFENTRY(NICKNAME, DISPLAY_STRING),
3441 RTCNFENTRY(WEP_ON, DISPLAY_WORDS),
3442 RTCNFENTRY(MWO_ROBUST, DISPLAY_WORDS),
3443 RTCNFENTRY(MULTICAST_LIST, DISPLAY_BYTES),
3444 RTCNFENTRY(CREATEIBSS, DISPLAY_WORDS),
3445 RTCNFENTRY(FRAG_THRESH, DISPLAY_WORDS),
3446 RTCNFENTRY(RTS_THRESH, DISPLAY_WORDS),
3447 RTCNFENTRY(TX_RATE_CTRL, DISPLAY_WORDS),
3448 RTCNFENTRY(PROMISCUOUS, DISPLAY_WORDS),
3449 RTCNFENTRY(KEYS, DISPLAY_BYTES),
3450 RTCNFENTRY(TX_KEY, DISPLAY_WORDS),
3451 RTCNFENTRY(TICKTIME, DISPLAY_WORDS),
3452 RTCNFENTRY(PRISM2_TX_KEY, DISPLAY_WORDS),
3453 RTCNFENTRY(PRISM2_KEY0, DISPLAY_BYTES),
3454 RTCNFENTRY(PRISM2_KEY1, DISPLAY_BYTES),
3455 RTCNFENTRY(PRISM2_KEY2, DISPLAY_BYTES),
3456 RTCNFENTRY(PRISM2_KEY3, DISPLAY_BYTES),
3457 RTCNFENTRY(PRISM2_WEP_ON, DISPLAY_WORDS),
3458 #undef RTCNFENTRY
3459 #define RTINFENTRY(name,type) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, type }
3460 RTINFENTRY(CHANNEL_LIST, DISPLAY_WORDS),
3461 RTINFENTRY(STAIDENTITY, DISPLAY_WORDS),
3462 RTINFENTRY(CURRENT_SSID, DISPLAY_STRING),
3463 RTINFENTRY(CURRENT_BSSID, DISPLAY_BYTES),
3464 RTINFENTRY(COMMSQUALITY, DISPLAY_WORDS),
3465 RTINFENTRY(CURRENT_TX_RATE, DISPLAY_WORDS),
3466 RTINFENTRY(WEP_AVAIL, DISPLAY_WORDS),
3467 RTINFENTRY(CURRENT_CHANNEL, DISPLAY_WORDS),
3468 RTINFENTRY(DATARATES, DISPLAY_BYTES),
3469 #undef RTINFENTRY
3470 };
3471 #define NUM_RIDS ( sizeof(record_table) / sizeof(record_table[0]) )
3472
3473 static int
3474 dldwd_proc_get_hermes_recs(char *page, char **start, off_t requested_offset,
3475 int requested_len, int *eof, void *data)
3476 {
3477 dldwd_priv_t *dev = (dldwd_priv_t *)data;
3478 hermes_t *hw = &dev->hw;
3479 char *buf;
3480 int total = 0, slop = 0;
3481 int i;
3482 uint16_t length;
3483 int err;
3484
3485 /* Hum, in this case hardware register are probably not readable... */
3486 if (!dev->hw_ready)
3487 return -ENODEV;
3488
3489 buf = page;
3490
3491 /* print out all the config RIDs */
3492 for (i = 0; i < NUM_RIDS; i++) {
3493 uint16_t rid = record_table[i].rid;
3494 int minlen = record_table[i].minlen;
3495 int maxlen = record_table[i].maxlen;
3496 int len;
3497 uint8_t *val8;
3498 uint16_t *val16;
3499 int j;
3500
3501 val8 = kmalloc(maxlen + 2, GFP_KERNEL);
3502 if (! val8)
3503 return -ENOMEM;
3504
3505 err = hermes_read_ltv(hw, USER_BAP, rid, maxlen,
3506 &length, val8);
3507 if (err) {
3508 DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
3509 continue;
3510 }
3511 val16 = (uint16_t *)val8;
3512
3513 buf += sprintf(buf, "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", record_table[i].name,
3514 rid, length, (length-1)*2);
3515 len = MIN( MAX(minlen, (length-1)*2), maxlen);
3516
3517 switch (record_table[i].displaytype) {
3518 case DISPLAY_WORDS:
3519 for (j = 0; j < len / 2; j++) {
3520 buf += sprintf(buf, "%04X-", le16_to_cpu(val16[j]));
3521 }
3522 buf--;
3523 break;
3524
3525 case DISPLAY_BYTES:
3526 default:
3527 for (j = 0; j < len; j++) {
3528 buf += sprintf(buf, "%02X:", val8[j]);
3529 }
3530 buf--;
3531 break;
3532
3533 case DISPLAY_STRING:
3534 len = MIN(len, le16_to_cpu(val16[0])+2);
3535 val8[len] = '\0';
3536 buf += sprintf(buf, "\"%s\"", (char *)&val16[1]);
3537 break;
3538 }
3539
3540 buf += sprintf(buf, "\n");
3541
3542 kfree(val8);
3543
3544 if (shift_buffer(page, requested_offset, requested_len,
3545 &total, &slop, &buf))
3546 break;
3547
3548 if ( (buf - page) > PROC_SAFE_SIZE )
3549 break;
3550 }
3551
3552 return calc_start_len(page, start, requested_offset, requested_len,
3553 total, buf);
3554 }
3555
3556 /* initialise the /proc subsystem for the hermes driver, creating the
3557 * separate entries */
3558 static int
3559 dldwd_proc_init(void)
3560 {
3561 int err = 0;
3562
3563 TRACE_ENTER("dldwd");
3564
3565 /* create the directory for it to sit in */
3566 dir_base = create_proc_entry("hermes", S_IFDIR, &proc_root);
3567 if (dir_base == NULL) {
3568 printk(KERN_ERR "Unable to initialise /proc/hermes.\n");
3569 dldwd_proc_cleanup();
3570 err = -ENOMEM;
3571 }
3572
3573 TRACE_EXIT("dldwd");
3574
3575 return err;
3576 }
3577
3578 int
3579 dldwd_proc_dev_init(dldwd_priv_t *dev)
3580 {
3581 struct net_device *ndev = &dev->ndev;
3582
3583 dev->dir_dev = NULL;
3584 /* create the directory for it to sit in */
3585 dev->dir_dev = create_proc_entry(ndev->name, S_IFDIR | S_IRUGO | S_IXUGO,
3586 dir_base);
3587 if (dev->dir_dev == NULL) {
3588 printk(KERN_ERR "Unable to initialise /proc/hermes/%s.\n", ndev->name);
3589 goto fail;
3590 }
3591
3592 dev->dir_regs = NULL;
3593 dev->dir_regs = create_proc_read_entry("regs", S_IFREG | S_IRUGO,
3594 dev->dir_dev, dldwd_proc_get_hermes_regs, dev);
3595 if (dev->dir_regs == NULL) {
3596 printk(KERN_ERR "Unable to initialise /proc/hermes/%s/regs.\n", ndev->name);
3597 goto fail;
3598 }
3599
3600 dev->dir_recs = NULL;
3601 dev->dir_recs = create_proc_read_entry("recs", S_IFREG | S_IRUGO,
3602 dev->dir_dev, dldwd_proc_get_hermes_recs, dev);
3603 if (dev->dir_recs == NULL) {
3604 printk(KERN_ERR "Unable to initialise /proc/hermes/%s/recs.\n", ndev->name);
3605 goto fail;
3606 }
3607
3608 return 0;
3609 fail:
3610 dldwd_proc_dev_cleanup(dev);
3611 return -ENOMEM;
3612 }
3613
3614 void
3615 dldwd_proc_dev_cleanup(dldwd_priv_t *priv)
3616 {
3617 struct net_device *ndev = &priv->ndev;
3618
3619 if (priv->dir_regs) {
3620 remove_proc_entry("regs", priv->dir_dev);
3621 priv->dir_regs = NULL;
3622 }
3623 if (priv->dir_recs) {
3624 remove_proc_entry("recs", priv->dir_dev);
3625 priv->dir_recs = NULL;
3626 }
3627 if (priv->dir_dev) {
3628 remove_proc_entry(ndev->name, dir_base);
3629 priv->dir_dev = NULL;
3630 }
3631 }
3632
3633 static void
3634 dldwd_proc_cleanup(void)
3635 {
3636 TRACE_ENTER("dldwd");
3637
3638 if (dir_base) {
3639 remove_proc_entry("hermes", &proc_root);
3640 dir_base = NULL;
3641 }
3642
3643 TRACE_EXIT("dldwd");
3644 }
3645
3646 int
3647 dldwd_setup(dldwd_priv_t* priv)
3648 {
3649 struct net_device *dev = &priv->ndev;;
3650
3651 spin_lock_init(&priv->lock);
3652
3653 /* Set up the net_device */
3654 ether_setup(dev);
3655 dev->priv = priv;
3656
3657 /* Setup up default routines */
3658 priv->card_reset_handler = NULL; /* Caller may override */
3659 dev->init = dldwd_init;
3660 dev->open = NULL; /* Caller *must* override */
3661 dev->stop = NULL;
3662 dev->hard_start_xmit = dldwd_xmit;
3663 dev->tx_timeout = dldwd_tx_timeout;
3664 dev->watchdog_timeo = HZ; /* 4 second timeout */
3665
3666 dev->get_stats = dldwd_get_stats;
3667 dev->get_wireless_stats = dldwd_get_wireless_stats;
3668
3669 dev->do_ioctl = dldwd_ioctl;
3670
3671 dev->change_mtu = dldwd_change_mtu;
3672 dev->set_multicast_list = dldwd_set_multicast_list;
3673
3674 netif_stop_queue(dev);
3675
3676 return 0;
3677 }
3678
3679 #ifdef ORINOCO_DEBUG
3680 EXPORT_SYMBOL(dldwd_debug);
3681 #endif
3682 EXPORT_SYMBOL(dldwd_init);
3683 EXPORT_SYMBOL(dldwd_xmit);
3684 EXPORT_SYMBOL(dldwd_tx_timeout);
3685 EXPORT_SYMBOL(dldwd_ioctl);
3686 EXPORT_SYMBOL(dldwd_change_mtu);
3687 EXPORT_SYMBOL(dldwd_set_multicast_list);
3688 EXPORT_SYMBOL(dldwd_shutdown);
3689 EXPORT_SYMBOL(dldwd_reset);
3690 EXPORT_SYMBOL(dldwd_setup);
3691 EXPORT_SYMBOL(dldwd_proc_dev_init);
3692 EXPORT_SYMBOL(dldwd_proc_dev_cleanup);
3693 EXPORT_SYMBOL(dldwd_interrupt);
3694
3695 static int __init init_dldwd(void)
3696 {
3697 int err;
3698
3699 err = dldwd_proc_init();
3700
3701 printk(KERN_DEBUG "%s\n", version);
3702
3703 return 0;
3704 }
3705
3706 static void __exit exit_dldwd(void)
3707 {
3708 dldwd_proc_cleanup();
3709 }
3710
3711 module_init(init_dldwd);
3712 module_exit(exit_dldwd);
3713