aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r--drivers/net/wireless/orinoco.c2465
1 files changed, 1456 insertions, 1009 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index b1078baa1d5e..aabcdc2be05e 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -46,382 +46,9 @@
46 * under either the MPL or the GPL. */ 46 * under either the MPL or the GPL. */
47 47
48/* 48/*
49 * v0.01 -> v0.02 - 21/3/2001 - Jean II
50 * o Allow to use regular ethX device name instead of dldwdX
51 * o Warning on IBSS with ESSID=any for firmware 6.06
52 * o Put proper range.throughput values (optimistic)
53 * o IWSPY support (IOCTL and stat gather in Rx path)
54 * o Allow setting frequency in Ad-Hoc mode
55 * o Disable WEP setting if !has_wep to work on old firmware
56 * o Fix txpower range
57 * o Start adding support for Samsung/Compaq firmware
58 *
59 * v0.02 -> v0.03 - 23/3/2001 - Jean II
60 * o Start adding Symbol support - need to check all that
61 * o Fix Prism2/Symbol WEP to accept 128 bits keys
62 * o Add Symbol WEP (add authentication type)
63 * o Add Prism2/Symbol rate
64 * o Add PM timeout (holdover duration)
65 * o Enable "iwconfig eth0 key off" and friends (toggle flags)
66 * o Enable "iwconfig eth0 power unicast/all" (toggle flags)
67 * o Try with an Intel card. It report firmware 1.01, behave like
68 * an antiquated firmware, however on windows it says 2.00. Yuck !
69 * o Workaround firmware bug in allocate buffer (Intel 1.01)
70 * o Finish external renaming to orinoco...
71 * o Testing with various Wavelan firmwares
72 *
73 * v0.03 -> v0.04 - 30/3/2001 - Jean II
74 * o Update to Wireless 11 -> add retry limit/lifetime support
75 * o Tested with a D-Link DWL 650 card, fill in firmware support
76 * o Warning on Vcc mismatch (D-Link 3.3v card in Lucent 5v only slot)
77 * o Fixed the Prism2 WEP bugs that I introduced in v0.03 :-(
78 * It works on D-Link *only* after a tcpdump. Weird...
79 * And still doesn't work on Intel card. Grrrr...
80 * o Update the mode after a setport3
81 * o Add preamble setting for Symbol cards (not yet enabled)
82 * o Don't complain as much about Symbol cards...
83 *
84 * v0.04 -> v0.04b - 22/4/2001 - David Gibson
85 * o Removed the 'eth' parameter - always use ethXX as the
86 * interface name instead of dldwdXX. The other was racy
87 * anyway.
88 * o Clean up RID definitions in hermes.h, other cleanups
89 *
90 * v0.04b -> v0.04c - 24/4/2001 - Jean II
91 * o Tim Hurley <timster AT seiki.bliztech.com> reported a D-Link card
92 * with vendor 02 and firmware 0.08. Added in the capabilities...
93 * o Tested Lucent firmware 7.28, everything works...
94 *
95 * v0.04c -> v0.05 - 3/5/2001 - Benjamin Herrenschmidt
96 * o Spin-off Pcmcia code. This file is renamed orinoco.c,
97 * and orinoco_cs.c now contains only the Pcmcia specific stuff
98 * o Add Airport driver support on top of orinoco.c (see airport.c)
99 *
100 * v0.05 -> v0.05a - 4/5/2001 - Jean II
101 * o Revert to old Pcmcia code to fix breakage of Ben's changes...
102 *
103 * v0.05a -> v0.05b - 4/5/2001 - Jean II
104 * o add module parameter 'ignore_cis_vcc' for D-Link @ 5V
105 * o D-Link firmware doesn't support multicast. We just print a few
106 * error messages, but otherwise everything works...
107 * o For David : set/getport3 works fine, just upgrade iwpriv...
108 *
109 * v0.05b -> v0.05c - 5/5/2001 - Benjamin Herrenschmidt
110 * o Adapt airport.c to latest changes in orinoco.c
111 * o Remove deferred power enabling code
112 *
113 * v0.05c -> v0.05d - 5/5/2001 - Jean II
114 * o Workaround to SNAP decapsulate frame from Linksys AP
115 * original patch from : Dong Liu <dliu AT research.bell-labs.com>
116 * (note : the memcmp bug was mine - fixed)
117 * o Remove set_retry stuff, no firmware support it (bloat--).
118 *
119 * v0.05d -> v0.06 - 25/5/2001 - Jean II
120 * Original patch from "Hong Lin" <alin AT redhat.com>,
121 * "Ian Kinner" <ikinner AT redhat.com>
122 * and "David Smith" <dsmith AT redhat.com>
123 * o Init of priv->tx_rate_ctrl in firmware specific section.
124 * o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
125 * o Spectrum card always need cor_reset (for every reset)
126 * o Fix cor_reset to not lose bit 7 in the register
127 * o flush_stale_links to remove zombie Pcmcia instances
128 * o Ack previous hermes event before reset
129 * Me (with my little hands)
130 * o Allow orinoco.c to call cor_reset via priv->card_reset_handler
131 * o Add priv->need_card_reset to toggle this feature
132 * o Fix various buglets when setting WEP in Symbol firmware
133 * Now, encryption is fully functional on Symbol cards. Youpi !
134 *
135 * v0.06 -> v0.06b - 25/5/2001 - Jean II
136 * o IBSS on Symbol use port_mode = 4. Please don't ask...
137 *
138 * v0.06b -> v0.06c - 29/5/2001 - Jean II
139 * o Show first spy address in /proc/net/wireless for IBSS mode as well
140 *
141 * v0.06c -> v0.06d - 6/7/2001 - David Gibson
142 * o Change a bunch of KERN_INFO messages to KERN_DEBUG, as per Linus'
143 * wishes to reduce the number of unnecessary messages.
144 * o Removed bogus message on CRC error.
145 * o Merged fixes for v0.08 Prism 2 firmware from William Waghorn
146 * <willwaghorn AT yahoo.co.uk>
147 * o Slight cleanup/re-arrangement of firmware detection code.
148 *
149 * v0.06d -> v0.06e - 1/8/2001 - David Gibson
150 * o Removed some redundant global initializers (orinoco_cs.c).
151 * o Added some module metadata
152 *
153 * v0.06e -> v0.06f - 14/8/2001 - David Gibson
154 * o Wording fix to license
155 * o Added a 'use_alternate_encaps' module parameter for APs which need an
156 * oui of 00:00:00. We really need a better way of handling this, but
157 * the module flag is better than nothing for now.
158 *
159 * v0.06f -> v0.07 - 20/8/2001 - David Gibson
160 * o Removed BAP error retries from hermes_bap_seek(). For Tx we now
161 * let the upper layers handle the retry, we retry explicitly in the
162 * Rx path, but don't make as much noise about it.
163 * o Firmware detection cleanups.
164 *
165 * v0.07 -> v0.07a - 1/10/3001 - Jean II
166 * o Add code to read Symbol firmware revision, inspired by latest code
167 * in Spectrum24 by Lee John Keyser-Allen - Thanks Lee !
168 * o Thanks to Jared Valentine <hidden AT xmission.com> for "providing" me
169 * a 3Com card with a recent firmware, fill out Symbol firmware
170 * capabilities of latest rev (2.20), as well as older Symbol cards.
171 * o Disable Power Management in newer Symbol firmware, the API
172 * has changed (documentation needed).
173 *
174 * v0.07a -> v0.08 - 3/10/2001 - David Gibson
175 * o Fixed a possible buffer overrun found by the Stanford checker (in
176 * dldwd_ioctl_setiwencode()). Can only be called by root anyway, so not
177 * a big problem.
178 * o Turned has_big_wep on for Intersil cards. That's not true for all of
179 * them but we should at least let the capable ones try.
180 * o Wait for BUSY to clear at the beginning of hermes_bap_seek(). I
181 * realized that my assumption that the driver's serialization
182 * would prevent the BAP being busy on entry was possibly false, because
183 * things other than seeks may make the BAP busy.
184 * o Use "alternate" (oui 00:00:00) encapsulation by default.
185 * Setting use_old_encaps will mimic the old behaviour, but I think we
186 * will be able to eliminate this.
187 * o Don't try to make __initdata const (the version string). This can't
188 * work because of the way the __initdata sectioning works.
189 * o Added MODULE_LICENSE tags.
190 * o Support for PLX (transparent PCMCIA->PCI bridge) cards.
191 * o Changed to using the new type-fascist min/max.
192 *
193 * v0.08 -> v0.08a - 9/10/2001 - David Gibson
194 * o Inserted some missing acknowledgements/info into the Changelog.
195 * o Fixed some bugs in the normalization of signal level reporting.
196 * o Fixed bad bug in WEP key handling on Intersil and Symbol firmware,
197 * which led to an instant crash on big-endian machines.
198 *
199 * v0.08a -> v0.08b - 20/11/2001 - David Gibson
200 * o Lots of cleanup and bugfixes in orinoco_plx.c
201 * o Cleanup to handling of Tx rate setting.
202 * o Removed support for old encapsulation method.
203 * o Removed old "dldwd" names.
204 * o Split RID constants into a new file hermes_rid.h
205 * o Renamed RID constants to match linux-wlan-ng and prism2.o
206 * o Bugfixes in hermes.c
207 * o Poke the PLX's INTCSR register, so it actually starts
208 * generating interrupts. These cards might actually work now.
209 * o Update to wireless extensions v12 (Jean II)
210 * o Support for tallies and inquire command (Jean II)
211 * o Airport updates for newer PPC kernels (BenH)
212 *
213 * v0.08b -> v0.09 - 21/12/2001 - David Gibson
214 * o Some new PCI IDs for PLX cards.
215 * o Removed broken attempt to do ALLMULTI reception. Just use
216 * promiscuous mode instead
217 * o Preliminary work for list-AP (Jean II)
218 * o Airport updates from (BenH)
219 * o Eliminated racy hw_ready stuff
220 * o Fixed generation of fake events in irq handler. This should
221 * finally kill the EIO problems (Jean II & dgibson)
222 * o Fixed breakage of bitrate set/get on Agere firmware (Jean II)
223 *
224 * v0.09 -> v0.09a - 2/1/2002 - David Gibson
225 * o Fixed stupid mistake in multicast list handling, triggering
226 * a BUG()
227 *
228 * v0.09a -> v0.09b - 16/1/2002 - David Gibson
229 * o Fixed even stupider mistake in new interrupt handling, which
230 * seriously broke things on big-endian machines.
231 * o Removed a bunch of redundant includes and exports.
232 * o Removed a redundant MOD_{INC,DEC}_USE_COUNT pair in airport.c
233 * o Don't attempt to do hardware level multicast reception on
234 * Intersil firmware, just go promisc instead.
235 * o Typo fixed in hermes_issue_cmd()
236 * o Eliminated WIRELESS_SPY #ifdefs
237 * o Status code reported on Tx exceptions
238 * o Moved netif_wake_queue() from ALLOC interrupts to TX and TXEXC
239 * interrupts, which should fix the timeouts we're seeing.
240 *
241 * v0.09b -> v0.10 - 25 Feb 2002 - David Gibson
242 * o Removed nested structures used for header parsing, so the
243 * driver should now work without hackery on ARM
244 * o Fix for WEP handling on Intersil (Hawk Newton)
245 * o Eliminated the /proc/hermes/ethXX/regs debugging file. It
246 * was never very useful.
247 * o Make Rx errors less noisy.
248 *
249 * v0.10 -> v0.11 - 5 Apr 2002 - David Gibson
250 * o Laid the groundwork in hermes.[ch] for devices which map
251 * into PCI memory space rather than IO space.
252 * o Fixed bug in multicast handling (cleared multicast list when
253 * leaving promiscuous mode).
254 * o Relegated Tx error messages to debug.
255 * o Cleaned up / corrected handling of allocation lengths.
256 * o Set OWNSSID in IBSS mode for WinXP interoperability (jimc).
257 * o Change to using alloc_etherdev() for structure allocations.
258 * o Check for and drop undersized packets.
259 * o Fixed a race in stopping/waking the queue. This should fix
260 * the timeout problems (Pavel Roskin)
261 * o Reverted to netif_wake_queue() on the ALLOC event.
262 * o Fixes for recent Symbol firmwares which lack AP density
263 * (Pavel Roskin).
264 *
265 * v0.11 -> v0.11a - 29 Apr 2002 - David Gibson
266 * o Handle different register spacing, necessary for Prism 2.5
267 * PCI adaptors (Steve Hill).
268 * o Cleaned up initialization of card structures in orinoco_cs
269 * and airport. Removed card->priv field.
270 * o Make response structure optional for hermes_docmd_wait()
271 * Pavel Roskin)
272 * o Added PCI id for Nortel emobility to orinoco_plx.c.
273 * o Cleanup to handling of Symbol's allocation bug. (Pavel Roskin)
274 * o Cleanups to firmware capability detection.
275 * o Arrange for orinoco_pci.c to override firmware detection.
276 * We should be able to support the PCI Intersil cards now.
277 * o Cleanup handling of reset_cor and hard_reset (Pavel Roskin).
278 * o Remove erroneous use of USER_BAP in the TxExc handler (Jouni
279 * Malinen).
280 * o Makefile changes for better integration into David Hinds
281 * pcmcia-cs package.
282 *
283 * v0.11a -> v0.11b - 1 May 2002 - David Gibson
284 * o Better error reporting in orinoco_plx_init_one()
285 * o Fixed multiple bad kfree() bugs introduced by the
286 * alloc_orinocodev() changes.
287 *
288 * v0.11b -> v0.12 - 19 Jun 2002 - David Gibson
289 * o Support changing the MAC address.
290 * o Correct display of Intersil firmware revision numbers.
291 * o Entirely revised locking scheme. Should be both simpler and
292 * better.
293 * o Merged some common code in orinoco_plx, orinoco_pci and
294 * airport by creating orinoco_default_{open,stop,reset}()
295 * which are used as the dev->open, dev->stop, priv->reset
296 * callbacks if none are specified when alloc_orinocodev() is
297 * called.
298 * o Removed orinoco_plx_interrupt() and orinoco_pci_interrupt().
299 * They didn't do anything.
300 *
301 * v0.12 -> v0.12a - 4 Jul 2002 - David Gibson
302 * o Some rearrangement of code.
303 * o Numerous fixups to locking and rest handling, particularly
304 * for PCMCIA.
305 * o This allows open and stop net_device methods to be in
306 * orinoco.c now, rather than in the init modules.
307 * o In orinoco_cs.c link->priv now points to the struct
308 * net_device not to the struct orinoco_private.
309 * o Added a check for undersized SNAP frames, which could cause
310 * crashes.
311 *
312 * v0.12a -> v0.12b - 11 Jul 2002 - David Gibson
313 * o Fix hw->num_init testing code, so num_init is actually
314 * incremented.
315 * o Fix very stupid bug in orinoco_cs which broke compile with
316 * CONFIG_SMP.
317 * o Squashed a warning.
318 *
319 * v0.12b -> v0.12c - 26 Jul 2002 - David Gibson
320 * o Change to C9X style designated initializers.
321 * o Add support for 3Com AirConnect PCI.
322 * o No longer ignore the hard_reset argument to
323 * alloc_orinocodev(). Oops.
324 *
325 * v0.12c -> v0.13beta1 - 13 Sep 2002 - David Gibson
326 * o Revert the broken 0.12* locking scheme and go to a new yet
327 * simpler scheme.
328 * o Do firmware resets only in orinoco_init() and when waking
329 * the card from hard sleep.
330 *
331 * v0.13beta1 -> v0.13 - 27 Sep 2002 - David Gibson
332 * o Re-introduced full resets (via schedule_task()) on Tx
333 * timeout.
334 *
335 * v0.13 -> v0.13a - 30 Sep 2002 - David Gibson
336 * o Minor cleanups to info frame handling. Add basic support
337 * for linkstatus info frames.
338 * o Include required kernel headers in orinoco.h, to avoid
339 * compile problems.
340 *
341 * v0.13a -> v0.13b - 10 Feb 2003 - David Gibson
342 * o Implemented hard reset for Airport cards
343 * o Experimental suspend/resume implementation for orinoco_pci
344 * o Abolished /proc debugging support, replaced with a debugging
345 * iwpriv. Now it's ugly and simple instead of ugly and complex.
346 * o Bugfix in hermes.c if the firmware returned a record length
347 * of 0, we could go clobbering memory.
348 * o Bugfix in orinoco_stop() - it used to fail if hw_unavailable
349 * was set, which was usually true on PCMCIA hot removes.
350 * o Track LINKSTATUS messages, silently drop Tx packets before
351 * we are connected (avoids confusing the firmware), and only
352 * give LINKSTATUS printk()s if the status has changed.
353 *
354 * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson
355 * o Cleanup: use dev instead of priv in various places.
356 * o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event
357 * if we're in the middle of a (driver initiated) hard reset.
358 * o Bug fix: ETH_ZLEN is supposed to include the header
359 * (Dionysus Blazakis & Manish Karir)
360 * o Convert to using workqueues instead of taskqueues (and
361 * backwards compatibility macros for pre 2.5.41 kernels).
362 * o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in
363 * airport.c
364 * o New orinoco_tmd.c init module from Joerg Dorchain for
365 * TMD7160 based PCI to PCMCIA bridges (similar to
366 * orinoco_plx.c).
367 *
368 * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson
369 * o Make hw_unavailable a counter, rather than just a flag, this
370 * is necessary to avoid some races (such as a card being
371 * removed in the middle of orinoco_reset().
372 * o Restore Release/RequestConfiguration in the PCMCIA event handler
373 * when dealing with a driver initiated hard reset. This is
374 * necessary to prevent hangs due to a spurious interrupt while
375 * the reset is in progress.
376 * o Clear the 802.11 header when transmitting, even though we
377 * don't use it. This fixes a long standing bug on some
378 * firmwares, which seem to get confused if that isn't done.
379 * o Be less eager to de-encapsulate SNAP frames, only do so if
380 * the OUI is 00:00:00 or 00:00:f8, leave others alone. The old
381 * behaviour broke CDP (Cisco Discovery Protocol).
382 * o Use dev instead of priv for free_irq() as well as
383 * request_irq() (oops).
384 * o Attempt to reset rather than giving up if we get too many
385 * IRQs.
386 * o Changed semantics of __orinoco_down() so it can be called
387 * safely with hw_unavailable set. It also now clears the
388 * linkstatus (since we're going to have to reassociate).
389 *
390 * v0.13d -> v0.13e - 12 May 2003 - David Gibson
391 * o Support for post-2.5.68 return values from irq handler.
392 * o Fixed bug where underlength packets would be double counted
393 * in the rx_dropped statistics.
394 * o Provided a module parameter to suppress linkstatus messages.
395 *
396 * v0.13e -> v0.14alpha1 - 30 Sep 2003 - David Gibson
397 * o Replaced priv->connected logic with netif_carrier_on/off()
398 * calls.
399 * o Remove has_ibss_any and never set the CREATEIBSS RID when
400 * the ESSID is empty. Too many firmwares break if we do.
401 * o 2.6 merges: Replace pdev->slot_name with pci_name(), remove
402 * __devinitdata from PCI ID tables, use free_netdev().
403 * o Enabled shared-key authentication for Agere firmware (from
404 * Robert J. Moore <Robert.J.Moore AT allanbank.com>
405 * o Move netif_wake_queue() (back) to the Tx completion from the
406 * ALLOC event. This seems to prevent/mitigate the rolling
407 * error -110 problems at least on some Intersil firmwares.
408 * Theoretically reduces performance, but I can't measure it.
409 * Patch from Andrew Tridgell <tridge AT samba.org>
410 *
411 * v0.14alpha1 -> v0.14alpha2 - 20 Oct 2003 - David Gibson
412 * o Correctly turn off shared-key authentication when requested
413 * (bugfix from Robert J. Moore).
414 * o Correct airport sleep interfaces for current 2.6 kernels.
415 * o Add code for key change without disabling/enabling the MAC
416 * port. This is supposed to allow 802.1x to work sanely, but
417 * doesn't seem to yet.
418 *
419 * TODO 49 * TODO
420 * o New wireless extensions API (patch from Moustafa
421 * Youssef, updated by Jim Carter and Pavel Roskin).
422 * o Handle de-encapsulation within network layer, provide 802.11 50 * o Handle de-encapsulation within network layer, provide 802.11
423 * headers (patch from Thomas 'Dent' Mirlacher) 51 * headers (patch from Thomas 'Dent' Mirlacher)
424 * o RF monitor mode support
425 * o Fix possible races in SPY handling. 52 * o Fix possible races in SPY handling.
426 * o Disconnect wireless extensions from fundamental configuration. 53 * o Disconnect wireless extensions from fundamental configuration.
427 * o (maybe) Software WEP support (patch from Stano Meduna). 54 * o (maybe) Software WEP support (patch from Stano Meduna).
@@ -462,7 +89,10 @@
462#include <linux/netdevice.h> 89#include <linux/netdevice.h>
463#include <linux/if_arp.h> 90#include <linux/if_arp.h>
464#include <linux/etherdevice.h> 91#include <linux/etherdevice.h>
92#include <linux/ethtool.h>
465#include <linux/wireless.h> 93#include <linux/wireless.h>
94#include <net/iw_handler.h>
95#include <net/ieee80211.h>
466 96
467#include <asm/uaccess.h> 97#include <asm/uaccess.h>
468#include <asm/io.h> 98#include <asm/io.h>
@@ -496,6 +126,10 @@ static int ignore_disconnect; /* = 0 */
496module_param(ignore_disconnect, int, 0644); 126module_param(ignore_disconnect, int, 0644);
497MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer"); 127MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
498 128
129static int force_monitor; /* = 0 */
130module_param(force_monitor, int, 0644);
131MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
132
499/********************************************************************/ 133/********************************************************************/
500/* Compile time configuration and compatibility stuff */ 134/* Compile time configuration and compatibility stuff */
501/********************************************************************/ 135/********************************************************************/
@@ -511,6 +145,10 @@ MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer
511/* Internal constants */ 145/* Internal constants */
512/********************************************************************/ 146/********************************************************************/
513 147
148/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
149static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
150#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
151
514#define ORINOCO_MIN_MTU 256 152#define ORINOCO_MIN_MTU 256
515#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD) 153#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
516 154
@@ -537,6 +175,11 @@ MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer
537 | HERMES_EV_WTERR | HERMES_EV_INFO \ 175 | HERMES_EV_WTERR | HERMES_EV_INFO \
538 | HERMES_EV_INFDROP ) 176 | HERMES_EV_INFDROP )
539 177
178#define MAX_RID_LEN 1024
179
180static const struct iw_handler_def orinoco_handler_def;
181static struct ethtool_ops orinoco_ethtool_ops;
182
540/********************************************************************/ 183/********************************************************************/
541/* Data tables */ 184/* Data tables */
542/********************************************************************/ 185/********************************************************************/
@@ -571,26 +214,45 @@ static struct {
571/* Data types */ 214/* Data types */
572/********************************************************************/ 215/********************************************************************/
573 216
574struct header_struct { 217/* Used in Event handling.
575 /* 802.3 */ 218 * We avoid nested structres as they break on ARM -- Moustafa */
576 u8 dest[ETH_ALEN]; 219struct hermes_tx_descriptor_802_11 {
577 u8 src[ETH_ALEN]; 220 /* hermes_tx_descriptor */
578 u16 len; 221 u16 status;
579 /* 802.2 */ 222 u16 reserved1;
223 u16 reserved2;
224 u32 sw_support;
225 u8 retry_count;
226 u8 tx_rate;
227 u16 tx_control;
228
229 /* ieee802_11_hdr */
230 u16 frame_ctl;
231 u16 duration_id;
232 u8 addr1[ETH_ALEN];
233 u8 addr2[ETH_ALEN];
234 u8 addr3[ETH_ALEN];
235 u16 seq_ctl;
236 u8 addr4[ETH_ALEN];
237 u16 data_len;
238
239 /* ethhdr */
240 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
241 unsigned char h_source[ETH_ALEN]; /* source ether addr */
242 unsigned short h_proto; /* packet type ID field */
243
244 /* p8022_hdr */
580 u8 dsap; 245 u8 dsap;
581 u8 ssap; 246 u8 ssap;
582 u8 ctrl; 247 u8 ctrl;
583 /* SNAP */
584 u8 oui[3]; 248 u8 oui[3];
249
585 u16 ethertype; 250 u16 ethertype;
586} __attribute__ ((packed)); 251} __attribute__ ((packed));
587 252
588/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */ 253/* Rx frame header except compatibility 802.3 header */
589u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
590
591#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
592
593struct hermes_rx_descriptor { 254struct hermes_rx_descriptor {
255 /* Control */
594 u16 status; 256 u16 status;
595 u32 time; 257 u32 time;
596 u8 silence; 258 u8 silence;
@@ -598,13 +260,24 @@ struct hermes_rx_descriptor {
598 u8 rate; 260 u8 rate;
599 u8 rxflow; 261 u8 rxflow;
600 u32 reserved; 262 u32 reserved;
263
264 /* 802.11 header */
265 u16 frame_ctl;
266 u16 duration_id;
267 u8 addr1[ETH_ALEN];
268 u8 addr2[ETH_ALEN];
269 u8 addr3[ETH_ALEN];
270 u16 seq_ctl;
271 u8 addr4[ETH_ALEN];
272
273 /* Data length */
274 u16 data_len;
601} __attribute__ ((packed)); 275} __attribute__ ((packed));
602 276
603/********************************************************************/ 277/********************************************************************/
604/* Function prototypes */ 278/* Function prototypes */
605/********************************************************************/ 279/********************************************************************/
606 280
607static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
608static int __orinoco_program_rids(struct net_device *dev); 281static int __orinoco_program_rids(struct net_device *dev);
609static void __orinoco_set_multicast_list(struct net_device *dev); 282static void __orinoco_set_multicast_list(struct net_device *dev);
610 283
@@ -628,6 +301,10 @@ static inline void set_port_type(struct orinoco_private *priv)
628 priv->createibss = 1; 301 priv->createibss = 1;
629 } 302 }
630 break; 303 break;
304 case IW_MODE_MONITOR:
305 priv->port_type = 3;
306 priv->createibss = 0;
307 break;
631 default: 308 default:
632 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n", 309 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
633 priv->ndev->name); 310 priv->ndev->name);
@@ -814,7 +491,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
814 return 1; 491 return 1;
815 } 492 }
816 493
817 if (! netif_carrier_ok(dev)) { 494 if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
818 /* Oops, the firmware hasn't established a connection, 495 /* Oops, the firmware hasn't established a connection,
819 silently drop the packet (this seems to be the 496 silently drop the packet (this seems to be the
820 safest approach). */ 497 safest approach). */
@@ -951,26 +628,55 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
951 struct orinoco_private *priv = netdev_priv(dev); 628 struct orinoco_private *priv = netdev_priv(dev);
952 struct net_device_stats *stats = &priv->stats; 629 struct net_device_stats *stats = &priv->stats;
953 u16 fid = hermes_read_regn(hw, TXCOMPLFID); 630 u16 fid = hermes_read_regn(hw, TXCOMPLFID);
954 struct hermes_tx_descriptor desc; 631 struct hermes_tx_descriptor_802_11 hdr;
955 int err = 0; 632 int err = 0;
956 633
957 if (fid == DUMMY_FID) 634 if (fid == DUMMY_FID)
958 return; /* Nothing's really happened */ 635 return; /* Nothing's really happened */
959 636
960 err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0); 637 /* Read the frame header */
638 err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
639 sizeof(struct hermes_tx_descriptor) +
640 sizeof(struct ieee80211_hdr),
641 fid, 0);
642
643 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
644 stats->tx_errors++;
645
961 if (err) { 646 if (err) {
962 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error " 647 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
963 "(FID=%04X error %d)\n", 648 "(FID=%04X error %d)\n",
964 dev->name, fid, err); 649 dev->name, fid, err);
965 } else { 650 return;
966 DEBUG(1, "%s: Tx error, status %d\n",
967 dev->name, le16_to_cpu(desc.status));
968 } 651 }
969 652
970 stats->tx_errors++; 653 DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
654 err, fid);
655
656 /* We produce a TXDROP event only for retry or lifetime
657 * exceeded, because that's the only status that really mean
658 * that this particular node went away.
659 * Other errors means that *we* screwed up. - Jean II */
660 hdr.status = le16_to_cpu(hdr.status);
661 if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
662 union iwreq_data wrqu;
663
664 /* Copy 802.11 dest address.
665 * We use the 802.11 header because the frame may
666 * not be 802.3 or may be mangled...
667 * In Ad-Hoc mode, it will be the node address.
668 * In managed mode, it will be most likely the AP addr
669 * User space will figure out how to convert it to
670 * whatever it needs (IP address or else).
671 * - Jean II */
672 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
673 wrqu.addr.sa_family = ARPHRD_ETHER;
674
675 /* Send event to user space */
676 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
677 }
971 678
972 netif_wake_queue(dev); 679 netif_wake_queue(dev);
973 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
974} 680}
975 681
976static void orinoco_tx_timeout(struct net_device *dev) 682static void orinoco_tx_timeout(struct net_device *dev)
@@ -1047,18 +753,127 @@ static void orinoco_stat_gather(struct net_device *dev,
1047 } 753 }
1048} 754}
1049 755
756/*
757 * orinoco_rx_monitor - handle received monitor frames.
758 *
759 * Arguments:
760 * dev network device
761 * rxfid received FID
762 * desc rx descriptor of the frame
763 *
764 * Call context: interrupt
765 */
766static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
767 struct hermes_rx_descriptor *desc)
768{
769 u32 hdrlen = 30; /* return full header by default */
770 u32 datalen = 0;
771 u16 fc;
772 int err;
773 int len;
774 struct sk_buff *skb;
775 struct orinoco_private *priv = netdev_priv(dev);
776 struct net_device_stats *stats = &priv->stats;
777 hermes_t *hw = &priv->hw;
778
779 len = le16_to_cpu(desc->data_len);
780
781 /* Determine the size of the header and the data */
782 fc = le16_to_cpu(desc->frame_ctl);
783 switch (fc & IEEE80211_FCTL_FTYPE) {
784 case IEEE80211_FTYPE_DATA:
785 if ((fc & IEEE80211_FCTL_TODS)
786 && (fc & IEEE80211_FCTL_FROMDS))
787 hdrlen = 30;
788 else
789 hdrlen = 24;
790 datalen = len;
791 break;
792 case IEEE80211_FTYPE_MGMT:
793 hdrlen = 24;
794 datalen = len;
795 break;
796 case IEEE80211_FTYPE_CTL:
797 switch (fc & IEEE80211_FCTL_STYPE) {
798 case IEEE80211_STYPE_PSPOLL:
799 case IEEE80211_STYPE_RTS:
800 case IEEE80211_STYPE_CFEND:
801 case IEEE80211_STYPE_CFENDACK:
802 hdrlen = 16;
803 break;
804 case IEEE80211_STYPE_CTS:
805 case IEEE80211_STYPE_ACK:
806 hdrlen = 10;
807 break;
808 }
809 break;
810 default:
811 /* Unknown frame type */
812 break;
813 }
814
815 /* sanity check the length */
816 if (datalen > IEEE80211_DATA_LEN + 12) {
817 printk(KERN_DEBUG "%s: oversized monitor frame, "
818 "data length = %d\n", dev->name, datalen);
819 err = -EIO;
820 stats->rx_length_errors++;
821 goto update_stats;
822 }
823
824 skb = dev_alloc_skb(hdrlen + datalen);
825 if (!skb) {
826 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
827 dev->name);
828 err = -ENOMEM;
829 goto drop;
830 }
831
832 /* Copy the 802.11 header to the skb */
833 memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
834 skb->mac.raw = skb->data;
835
836 /* If any, copy the data from the card to the skb */
837 if (datalen > 0) {
838 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
839 ALIGN(datalen, 2), rxfid,
840 HERMES_802_2_OFFSET);
841 if (err) {
842 printk(KERN_ERR "%s: error %d reading monitor frame\n",
843 dev->name, err);
844 goto drop;
845 }
846 }
847
848 skb->dev = dev;
849 skb->ip_summed = CHECKSUM_NONE;
850 skb->pkt_type = PACKET_OTHERHOST;
851 skb->protocol = __constant_htons(ETH_P_802_2);
852
853 dev->last_rx = jiffies;
854 stats->rx_packets++;
855 stats->rx_bytes += skb->len;
856
857 netif_rx(skb);
858 return;
859
860 drop:
861 dev_kfree_skb_irq(skb);
862 update_stats:
863 stats->rx_errors++;
864 stats->rx_dropped++;
865}
866
1050static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) 867static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1051{ 868{
1052 struct orinoco_private *priv = netdev_priv(dev); 869 struct orinoco_private *priv = netdev_priv(dev);
1053 struct net_device_stats *stats = &priv->stats; 870 struct net_device_stats *stats = &priv->stats;
1054 struct iw_statistics *wstats = &priv->wstats; 871 struct iw_statistics *wstats = &priv->wstats;
1055 struct sk_buff *skb = NULL; 872 struct sk_buff *skb = NULL;
1056 u16 rxfid, status; 873 u16 rxfid, status, fc;
1057 int length, data_len, data_off; 874 int length;
1058 char *p;
1059 struct hermes_rx_descriptor desc; 875 struct hermes_rx_descriptor desc;
1060 struct header_struct hdr; 876 struct ethhdr *hdr;
1061 struct ethhdr *eh;
1062 int err; 877 int err;
1063 878
1064 rxfid = hermes_read_regn(hw, RXFID); 879 rxfid = hermes_read_regn(hw, RXFID);
@@ -1068,53 +883,46 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1068 if (err) { 883 if (err) {
1069 printk(KERN_ERR "%s: error %d reading Rx descriptor. " 884 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1070 "Frame dropped.\n", dev->name, err); 885 "Frame dropped.\n", dev->name, err);
1071 stats->rx_errors++; 886 goto update_stats;
1072 goto drop;
1073 } 887 }
1074 888
1075 status = le16_to_cpu(desc.status); 889 status = le16_to_cpu(desc.status);
1076 890
1077 if (status & HERMES_RXSTAT_ERR) { 891 if (status & HERMES_RXSTAT_BADCRC) {
1078 if (status & HERMES_RXSTAT_UNDECRYPTABLE) { 892 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
1079 wstats->discard.code++; 893 dev->name);
1080 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n", 894 stats->rx_crc_errors++;
1081 dev->name); 895 goto update_stats;
1082 } else {
1083 stats->rx_crc_errors++;
1084 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
1085 }
1086 stats->rx_errors++;
1087 goto drop;
1088 } 896 }
1089 897
1090 /* For now we ignore the 802.11 header completely, assuming 898 /* Handle frames in monitor mode */
1091 that the card's firmware has handled anything vital */ 899 if (priv->iw_mode == IW_MODE_MONITOR) {
900 orinoco_rx_monitor(dev, rxfid, &desc);
901 return;
902 }
1092 903
1093 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr), 904 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1094 rxfid, HERMES_802_3_OFFSET); 905 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1095 if (err) { 906 dev->name);
1096 printk(KERN_ERR "%s: error %d reading frame header. " 907 wstats->discard.code++;
1097 "Frame dropped.\n", dev->name, err); 908 goto update_stats;
1098 stats->rx_errors++;
1099 goto drop;
1100 } 909 }
1101 910
1102 length = ntohs(hdr.len); 911 length = le16_to_cpu(desc.data_len);
1103 912 fc = le16_to_cpu(desc.frame_ctl);
913
1104 /* Sanity checks */ 914 /* Sanity checks */
1105 if (length < 3) { /* No for even an 802.2 LLC header */ 915 if (length < 3) { /* No for even an 802.2 LLC header */
1106 /* At least on Symbol firmware with PCF we get quite a 916 /* At least on Symbol firmware with PCF we get quite a
1107 lot of these legitimately - Poll frames with no 917 lot of these legitimately - Poll frames with no
1108 data. */ 918 data. */
1109 stats->rx_dropped++; 919 return;
1110 goto drop;
1111 } 920 }
1112 if (length > IEEE802_11_DATA_LEN) { 921 if (length > IEEE802_11_DATA_LEN) {
1113 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", 922 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1114 dev->name, length); 923 dev->name, length);
1115 stats->rx_length_errors++; 924 stats->rx_length_errors++;
1116 stats->rx_errors++; 925 goto update_stats;
1117 goto drop;
1118 } 926 }
1119 927
1120 /* We need space for the packet data itself, plus an ethernet 928 /* We need space for the packet data itself, plus an ethernet
@@ -1126,60 +934,53 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1126 if (!skb) { 934 if (!skb) {
1127 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n", 935 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1128 dev->name); 936 dev->name);
1129 goto drop; 937 goto update_stats;
1130 } 938 }
1131 939
1132 skb_reserve(skb, 2); /* This way the IP header is aligned */ 940 /* We'll prepend the header, so reserve space for it. The worst
941 case is no decapsulation, when 802.3 header is prepended and
942 nothing is removed. 2 is for aligning the IP header. */
943 skb_reserve(skb, ETH_HLEN + 2);
944
945 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
946 ALIGN(length, 2), rxfid,
947 HERMES_802_2_OFFSET);
948 if (err) {
949 printk(KERN_ERR "%s: error %d reading frame. "
950 "Frame dropped.\n", dev->name, err);
951 goto drop;
952 }
1133 953
1134 /* Handle decapsulation 954 /* Handle decapsulation
1135 * In most cases, the firmware tell us about SNAP frames. 955 * In most cases, the firmware tell us about SNAP frames.
1136 * For some reason, the SNAP frames sent by LinkSys APs 956 * For some reason, the SNAP frames sent by LinkSys APs
1137 * are not properly recognised by most firmwares. 957 * are not properly recognised by most firmwares.
1138 * So, check ourselves */ 958 * So, check ourselves */
1139 if (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) || 959 if (length >= ENCAPS_OVERHEAD &&
1140 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) || 960 (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1141 is_ethersnap(&hdr)) { 961 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
962 is_ethersnap(skb->data))) {
1142 /* These indicate a SNAP within 802.2 LLC within 963 /* These indicate a SNAP within 802.2 LLC within
1143 802.11 frame which we'll need to de-encapsulate to 964 802.11 frame which we'll need to de-encapsulate to
1144 the original EthernetII frame. */ 965 the original EthernetII frame. */
1145 966 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
1146 if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
1147 stats->rx_length_errors++;
1148 goto drop;
1149 }
1150
1151 /* Remove SNAP header, reconstruct EthernetII frame */
1152 data_len = length - ENCAPS_OVERHEAD;
1153 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
1154
1155 eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
1156
1157 memcpy(eh, &hdr, 2 * ETH_ALEN);
1158 eh->h_proto = hdr.ethertype;
1159 } else { 967 } else {
1160 /* All other cases indicate a genuine 802.3 frame. No 968 /* 802.3 frame - prepend 802.3 header as is */
1161 decapsulation needed. We just throw the whole 969 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
1162 thing in, and hope the protocol layer can deal with 970 hdr->h_proto = htons(length);
1163 it as 802.3 */
1164 data_len = length;
1165 data_off = HERMES_802_3_OFFSET;
1166 /* FIXME: we re-read from the card data we already read here */
1167 }
1168
1169 p = skb_put(skb, data_len);
1170 err = hermes_bap_pread(hw, IRQ_BAP, p, ALIGN(data_len, 2),
1171 rxfid, data_off);
1172 if (err) {
1173 printk(KERN_ERR "%s: error %d reading frame. "
1174 "Frame dropped.\n", dev->name, err);
1175 stats->rx_errors++;
1176 goto drop;
1177 } 971 }
972 memcpy(hdr->h_dest, desc.addr1, ETH_ALEN);
973 if (fc & IEEE80211_FCTL_FROMDS)
974 memcpy(hdr->h_source, desc.addr3, ETH_ALEN);
975 else
976 memcpy(hdr->h_source, desc.addr2, ETH_ALEN);
1178 977
1179 dev->last_rx = jiffies; 978 dev->last_rx = jiffies;
1180 skb->dev = dev; 979 skb->dev = dev;
1181 skb->protocol = eth_type_trans(skb, dev); 980 skb->protocol = eth_type_trans(skb, dev);
1182 skb->ip_summed = CHECKSUM_NONE; 981 skb->ip_summed = CHECKSUM_NONE;
982 if (fc & IEEE80211_FCTL_TODS)
983 skb->pkt_type = PACKET_OTHERHOST;
1183 984
1184 /* Process the wireless stats if needed */ 985 /* Process the wireless stats if needed */
1185 orinoco_stat_gather(dev, skb, &desc); 986 orinoco_stat_gather(dev, skb, &desc);
@@ -1192,11 +993,10 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1192 return; 993 return;
1193 994
1194 drop: 995 drop:
996 dev_kfree_skb_irq(skb);
997 update_stats:
998 stats->rx_errors++;
1195 stats->rx_dropped++; 999 stats->rx_dropped++;
1196
1197 if (skb)
1198 dev_kfree_skb_irq(skb);
1199 return;
1200} 1000}
1201 1001
1202/********************************************************************/ 1002/********************************************************************/
@@ -1240,6 +1040,99 @@ static void print_linkstatus(struct net_device *dev, u16 status)
1240 dev->name, s, status); 1040 dev->name, s, status);
1241} 1041}
1242 1042
1043/* Search scan results for requested BSSID, join it if found */
1044static void orinoco_join_ap(struct net_device *dev)
1045{
1046 struct orinoco_private *priv = netdev_priv(dev);
1047 struct hermes *hw = &priv->hw;
1048 int err;
1049 unsigned long flags;
1050 struct join_req {
1051 u8 bssid[ETH_ALEN];
1052 u16 channel;
1053 } __attribute__ ((packed)) req;
1054 const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1055 struct prism2_scan_apinfo *atom;
1056 int offset = 4;
1057 u8 *buf;
1058 u16 len;
1059
1060 /* Allocate buffer for scan results */
1061 buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
1062 if (! buf)
1063 return;
1064
1065 if (orinoco_lock(priv, &flags) != 0)
1066 goto out;
1067
1068 /* Sanity checks in case user changed something in the meantime */
1069 if (! priv->bssid_fixed)
1070 goto out;
1071
1072 if (strlen(priv->desired_essid) == 0)
1073 goto out;
1074
1075 /* Read scan results from the firmware */
1076 err = hermes_read_ltv(hw, USER_BAP,
1077 HERMES_RID_SCANRESULTSTABLE,
1078 MAX_SCAN_LEN, &len, buf);
1079 if (err) {
1080 printk(KERN_ERR "%s: Cannot read scan results\n",
1081 dev->name);
1082 goto out;
1083 }
1084
1085 len = HERMES_RECLEN_TO_BYTES(len);
1086
1087 /* Go through the scan results looking for the channel of the AP
1088 * we were requested to join */
1089 for (; offset + atom_len <= len; offset += atom_len) {
1090 atom = (struct prism2_scan_apinfo *) (buf + offset);
1091 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0)
1092 goto found;
1093 }
1094
1095 DEBUG(1, "%s: Requested AP not found in scan results\n",
1096 dev->name);
1097 goto out;
1098
1099 found:
1100 memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1101 req.channel = atom->channel; /* both are little-endian */
1102 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
1103 &req);
1104 if (err)
1105 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1106
1107 out:
1108 kfree(buf);
1109 orinoco_unlock(priv, &flags);
1110}
1111
1112/* Send new BSSID to userspace */
1113static void orinoco_send_wevents(struct net_device *dev)
1114{
1115 struct orinoco_private *priv = netdev_priv(dev);
1116 struct hermes *hw = &priv->hw;
1117 union iwreq_data wrqu;
1118 int err;
1119 unsigned long flags;
1120
1121 if (orinoco_lock(priv, &flags) != 0)
1122 return;
1123
1124 err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
1125 ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1126 if (err != 0)
1127 return;
1128
1129 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1130
1131 /* Send event to user space */
1132 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1133 orinoco_unlock(priv, &flags);
1134}
1135
1243static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) 1136static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1244{ 1137{
1245 struct orinoco_private *priv = netdev_priv(dev); 1138 struct orinoco_private *priv = netdev_priv(dev);
@@ -1307,6 +1200,9 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1307 u16 newstatus; 1200 u16 newstatus;
1308 int connected; 1201 int connected;
1309 1202
1203 if (priv->iw_mode == IW_MODE_MONITOR)
1204 break;
1205
1310 if (len != sizeof(linkstatus)) { 1206 if (len != sizeof(linkstatus)) {
1311 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n", 1207 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1312 dev->name, len); 1208 dev->name, len);
@@ -1319,6 +1215,15 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1319 break; 1215 break;
1320 newstatus = le16_to_cpu(linkstatus.linkstatus); 1216 newstatus = le16_to_cpu(linkstatus.linkstatus);
1321 1217
1218 /* Symbol firmware uses "out of range" to signal that
1219 * the hostscan frame can be requested. */
1220 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
1221 priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
1222 priv->has_hostscan && priv->scan_inprogress) {
1223 hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
1224 break;
1225 }
1226
1322 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) 1227 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1323 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE) 1228 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1324 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE); 1229 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
@@ -1328,12 +1233,89 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1328 else if (!ignore_disconnect) 1233 else if (!ignore_disconnect)
1329 netif_carrier_off(dev); 1234 netif_carrier_off(dev);
1330 1235
1331 if (newstatus != priv->last_linkstatus) 1236 if (newstatus != priv->last_linkstatus) {
1237 priv->last_linkstatus = newstatus;
1332 print_linkstatus(dev, newstatus); 1238 print_linkstatus(dev, newstatus);
1239 /* The info frame contains only one word which is the
1240 * status (see hermes.h). The status is pretty boring
1241 * in itself, that's why we export the new BSSID...
1242 * Jean II */
1243 schedule_work(&priv->wevent_work);
1244 }
1245 }
1246 break;
1247 case HERMES_INQ_SCAN:
1248 if (!priv->scan_inprogress && priv->bssid_fixed &&
1249 priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
1250 schedule_work(&priv->join_work);
1251 break;
1252 }
1253 /* fall through */
1254 case HERMES_INQ_HOSTSCAN:
1255 case HERMES_INQ_HOSTSCAN_SYMBOL: {
1256 /* Result of a scanning. Contains information about
1257 * cells in the vicinity - Jean II */
1258 union iwreq_data wrqu;
1259 unsigned char *buf;
1260
1261 /* Sanity check */
1262 if (len > 4096) {
1263 printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
1264 dev->name, len);
1265 break;
1266 }
1333 1267
1334 priv->last_linkstatus = newstatus; 1268 /* We are a strict producer. If the previous scan results
1269 * have not been consumed, we just have to drop this
1270 * frame. We can't remove the previous results ourselves,
1271 * that would be *very* racy... Jean II */
1272 if (priv->scan_result != NULL) {
1273 printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name);
1274 break;
1275 }
1276
1277 /* Allocate buffer for results */
1278 buf = kmalloc(len, GFP_ATOMIC);
1279 if (buf == NULL)
1280 /* No memory, so can't printk()... */
1281 break;
1282
1283 /* Read scan data */
1284 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1285 infofid, sizeof(info));
1286 if (err)
1287 break;
1288
1289#ifdef ORINOCO_DEBUG
1290 {
1291 int i;
1292 printk(KERN_DEBUG "Scan result [%02X", buf[0]);
1293 for(i = 1; i < (len * 2); i++)
1294 printk(":%02X", buf[i]);
1295 printk("]\n");
1296 }
1297#endif /* ORINOCO_DEBUG */
1298
1299 /* Allow the clients to access the results */
1300 priv->scan_len = len;
1301 priv->scan_result = buf;
1302
1303 /* Send an empty event to user space.
1304 * We don't send the received data on the event because
1305 * it would require us to do complex transcoding, and
1306 * we want to minimise the work done in the irq handler
1307 * Use a request to extract the data - Jean II */
1308 wrqu.data.length = 0;
1309 wrqu.data.flags = 0;
1310 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1335 } 1311 }
1336 break; 1312 break;
1313 case HERMES_INQ_SEC_STAT_AGERE:
1314 /* Security status (Agere specific) */
1315 /* Ignore this frame for now */
1316 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
1317 break;
1318 /* fall through */
1337 default: 1319 default:
1338 printk(KERN_DEBUG "%s: Unknown information frame received: " 1320 printk(KERN_DEBUG "%s: Unknown information frame received: "
1339 "type 0x%04x, length %d\n", dev->name, type, len); 1321 "type 0x%04x, length %d\n", dev->name, type, len);
@@ -1470,6 +1452,36 @@ static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1470 return err; 1452 return err;
1471} 1453}
1472 1454
1455/* Set fixed AP address */
1456static int __orinoco_hw_set_wap(struct orinoco_private *priv)
1457{
1458 int roaming_flag;
1459 int err = 0;
1460 hermes_t *hw = &priv->hw;
1461
1462 switch (priv->firmware_type) {
1463 case FIRMWARE_TYPE_AGERE:
1464 /* not supported */
1465 break;
1466 case FIRMWARE_TYPE_INTERSIL:
1467 if (priv->bssid_fixed)
1468 roaming_flag = 2;
1469 else
1470 roaming_flag = 1;
1471
1472 err = hermes_write_wordrec(hw, USER_BAP,
1473 HERMES_RID_CNFROAMINGMODE,
1474 roaming_flag);
1475 break;
1476 case FIRMWARE_TYPE_SYMBOL:
1477 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1478 HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
1479 &priv->desired_bssid);
1480 break;
1481 }
1482 return err;
1483}
1484
1473/* Change the WEP keys and/or the current keys. Can be called 1485/* Change the WEP keys and/or the current keys. Can be called
1474 * either from __orinoco_hw_setup_wep() or directly from 1486 * either from __orinoco_hw_setup_wep() or directly from
1475 * orinoco_ioctl_setiwencode(). In the later case the association 1487 * orinoco_ioctl_setiwencode(). In the later case the association
@@ -1655,6 +1667,13 @@ static int __orinoco_program_rids(struct net_device *dev)
1655 } 1667 }
1656 } 1668 }
1657 1669
1670 /* Set the desired BSSID */
1671 err = __orinoco_hw_set_wap(priv);
1672 if (err) {
1673 printk(KERN_ERR "%s: Error %d setting AP address\n",
1674 dev->name, err);
1675 return err;
1676 }
1658 /* Set the desired ESSID */ 1677 /* Set the desired ESSID */
1659 idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); 1678 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
1660 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); 1679 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
@@ -1793,6 +1812,20 @@ static int __orinoco_program_rids(struct net_device *dev)
1793 } 1812 }
1794 } 1813 }
1795 1814
1815 if (priv->iw_mode == IW_MODE_MONITOR) {
1816 /* Enable monitor mode */
1817 dev->type = ARPHRD_IEEE80211;
1818 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
1819 HERMES_TEST_MONITOR, 0, NULL);
1820 } else {
1821 /* Disable monitor mode */
1822 dev->type = ARPHRD_ETHER;
1823 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
1824 HERMES_TEST_STOP, 0, NULL);
1825 }
1826 if (err)
1827 return err;
1828
1796 /* Set promiscuity / multicast*/ 1829 /* Set promiscuity / multicast*/
1797 priv->promiscuous = 0; 1830 priv->promiscuous = 0;
1798 priv->mc_count = 0; 1831 priv->mc_count = 0;
@@ -1869,55 +1902,6 @@ __orinoco_set_multicast_list(struct net_device *dev)
1869 dev->flags &= ~IFF_PROMISC; 1902 dev->flags &= ~IFF_PROMISC;
1870} 1903}
1871 1904
1872static int orinoco_reconfigure(struct net_device *dev)
1873{
1874 struct orinoco_private *priv = netdev_priv(dev);
1875 struct hermes *hw = &priv->hw;
1876 unsigned long flags;
1877 int err = 0;
1878
1879 if (priv->broken_disableport) {
1880 schedule_work(&priv->reset_work);
1881 return 0;
1882 }
1883
1884 if (orinoco_lock(priv, &flags) != 0)
1885 return -EBUSY;
1886
1887 err = hermes_disable_port(hw, 0);
1888 if (err) {
1889 printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n",
1890 dev->name);
1891 priv->broken_disableport = 1;
1892 goto out;
1893 }
1894
1895 err = __orinoco_program_rids(dev);
1896 if (err) {
1897 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
1898 dev->name);
1899 goto out;
1900 }
1901
1902 err = hermes_enable_port(hw, 0);
1903 if (err) {
1904 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
1905 dev->name);
1906 goto out;
1907 }
1908
1909 out:
1910 if (err) {
1911 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
1912 schedule_work(&priv->reset_work);
1913 err = 0;
1914 }
1915
1916 orinoco_unlock(priv, &flags);
1917 return err;
1918
1919}
1920
1921/* This must be called from user context, without locks held - use 1905/* This must be called from user context, without locks held - use
1922 * schedule_work() */ 1906 * schedule_work() */
1923static void orinoco_reset(struct net_device *dev) 1907static void orinoco_reset(struct net_device *dev)
@@ -1946,6 +1930,11 @@ static void orinoco_reset(struct net_device *dev)
1946 1930
1947 orinoco_unlock(priv, &flags); 1931 orinoco_unlock(priv, &flags);
1948 1932
1933 /* Scanning support: Cleanup of driver struct */
1934 kfree(priv->scan_result);
1935 priv->scan_result = NULL;
1936 priv->scan_inprogress = 0;
1937
1949 if (priv->hard_reset) { 1938 if (priv->hard_reset) {
1950 err = (*priv->hard_reset)(priv); 1939 err = (*priv->hard_reset)(priv);
1951 if (err) { 1940 if (err) {
@@ -2184,6 +2173,8 @@ static int determine_firmware(struct net_device *dev)
2184 priv->has_mwo = (firmver >= 0x60000); 2173 priv->has_mwo = (firmver >= 0x60000);
2185 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */ 2174 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2186 priv->ibss_port = 1; 2175 priv->ibss_port = 1;
2176 priv->has_hostscan = (firmver >= 0x8000a);
2177 priv->broken_monitor = (firmver >= 0x80000);
2187 2178
2188 /* Tested with Agere firmware : 2179 /* Tested with Agere firmware :
2189 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II 2180 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
@@ -2229,6 +2220,8 @@ static int determine_firmware(struct net_device *dev)
2229 priv->ibss_port = 4; 2220 priv->ibss_port = 4;
2230 priv->broken_disableport = (firmver == 0x25013) || 2221 priv->broken_disableport = (firmver == 0x25013) ||
2231 (firmver >= 0x30000 && firmver <= 0x31000); 2222 (firmver >= 0x30000 && firmver <= 0x31000);
2223 priv->has_hostscan = (firmver >= 0x31001) ||
2224 (firmver >= 0x29057 && firmver < 0x30000);
2232 /* Tested with Intel firmware : 0x20015 => Jean II */ 2225 /* Tested with Intel firmware : 0x20015 => Jean II */
2233 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ 2226 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2234 break; 2227 break;
@@ -2248,6 +2241,7 @@ static int determine_firmware(struct net_device *dev)
2248 priv->has_ibss = (firmver >= 0x000700); /* FIXME */ 2241 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2249 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800); 2242 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2250 priv->has_pm = (firmver >= 0x000700); 2243 priv->has_pm = (firmver >= 0x000700);
2244 priv->has_hostscan = (firmver >= 0x010301);
2251 2245
2252 if (firmver >= 0x000800) 2246 if (firmver >= 0x000800)
2253 priv->ibss_port = 0; 2247 priv->ibss_port = 0;
@@ -2456,8 +2450,9 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2456 dev->tx_timeout = orinoco_tx_timeout; 2450 dev->tx_timeout = orinoco_tx_timeout;
2457 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2451 dev->watchdog_timeo = HZ; /* 1 second timeout */
2458 dev->get_stats = orinoco_get_stats; 2452 dev->get_stats = orinoco_get_stats;
2453 dev->ethtool_ops = &orinoco_ethtool_ops;
2459 dev->get_wireless_stats = orinoco_get_wireless_stats; 2454 dev->get_wireless_stats = orinoco_get_wireless_stats;
2460 dev->do_ioctl = orinoco_ioctl; 2455 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
2461 dev->change_mtu = orinoco_change_mtu; 2456 dev->change_mtu = orinoco_change_mtu;
2462 dev->set_multicast_list = orinoco_set_multicast_list; 2457 dev->set_multicast_list = orinoco_set_multicast_list;
2463 /* we use the default eth_mac_addr for setting the MAC addr */ 2458 /* we use the default eth_mac_addr for setting the MAC addr */
@@ -2473,6 +2468,8 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2473 * before anything else touches the 2468 * before anything else touches the
2474 * hardware */ 2469 * hardware */
2475 INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev); 2470 INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
2471 INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev);
2472 INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev);
2476 2473
2477 netif_carrier_off(dev); 2474 netif_carrier_off(dev);
2478 priv->last_linkstatus = 0xffff; 2475 priv->last_linkstatus = 0xffff;
@@ -2483,6 +2480,9 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2483 2480
2484void free_orinocodev(struct net_device *dev) 2481void free_orinocodev(struct net_device *dev)
2485{ 2482{
2483 struct orinoco_private *priv = netdev_priv(dev);
2484
2485 kfree(priv->scan_result);
2486 free_netdev(dev); 2486 free_netdev(dev);
2487} 2487}
2488 2488
@@ -2490,24 +2490,6 @@ void free_orinocodev(struct net_device *dev)
2490/* Wireless extensions */ 2490/* Wireless extensions */
2491/********************************************************************/ 2491/********************************************************************/
2492 2492
2493static int orinoco_hw_get_bssid(struct orinoco_private *priv,
2494 char buf[ETH_ALEN])
2495{
2496 hermes_t *hw = &priv->hw;
2497 int err = 0;
2498 unsigned long flags;
2499
2500 if (orinoco_lock(priv, &flags) != 0)
2501 return -EBUSY;
2502
2503 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
2504 ETH_ALEN, NULL, buf);
2505
2506 orinoco_unlock(priv, &flags);
2507
2508 return err;
2509}
2510
2511static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, 2493static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
2512 char buf[IW_ESSID_MAX_SIZE+1]) 2494 char buf[IW_ESSID_MAX_SIZE+1])
2513{ 2495{
@@ -2633,140 +2615,271 @@ static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
2633 return 0; 2615 return 0;
2634} 2616}
2635 2617
2636static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq) 2618static int orinoco_ioctl_getname(struct net_device *dev,
2619 struct iw_request_info *info,
2620 char *name,
2621 char *extra)
2637{ 2622{
2638 struct orinoco_private *priv = netdev_priv(dev); 2623 struct orinoco_private *priv = netdev_priv(dev);
2639 int err = 0;
2640 int mode;
2641 struct iw_range range;
2642 int numrates; 2624 int numrates;
2643 int i, k; 2625 int err;
2626
2627 err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
2628
2629 if (!err && (numrates > 2))
2630 strcpy(name, "IEEE 802.11b");
2631 else
2632 strcpy(name, "IEEE 802.11-DS");
2633
2634 return 0;
2635}
2636
2637static int orinoco_ioctl_setwap(struct net_device *dev,
2638 struct iw_request_info *info,
2639 struct sockaddr *ap_addr,
2640 char *extra)
2641{
2642 struct orinoco_private *priv = netdev_priv(dev);
2643 int err = -EINPROGRESS; /* Call commit handler */
2644 unsigned long flags; 2644 unsigned long flags;
2645 static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2646 static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2645 2647
2646 TRACE_ENTER(dev->name); 2648 if (orinoco_lock(priv, &flags) != 0)
2649 return -EBUSY;
2650
2651 /* Enable automatic roaming - no sanity checks are needed */
2652 if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
2653 memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
2654 priv->bssid_fixed = 0;
2655 memset(priv->desired_bssid, 0, ETH_ALEN);
2656
2657 /* "off" means keep existing connection */
2658 if (ap_addr->sa_data[0] == 0) {
2659 __orinoco_hw_set_wap(priv);
2660 err = 0;
2661 }
2662 goto out;
2663 }
2664
2665 if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
2666 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
2667 "support manual roaming\n",
2668 dev->name);
2669 err = -EOPNOTSUPP;
2670 goto out;
2671 }
2672
2673 if (priv->iw_mode != IW_MODE_INFRA) {
2674 printk(KERN_WARNING "%s: Manual roaming supported only in "
2675 "managed mode\n", dev->name);
2676 err = -EOPNOTSUPP;
2677 goto out;
2678 }
2679
2680 /* Intersil firmware hangs without Desired ESSID */
2681 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
2682 strlen(priv->desired_essid) == 0) {
2683 printk(KERN_WARNING "%s: Desired ESSID must be set for "
2684 "manual roaming\n", dev->name);
2685 err = -EOPNOTSUPP;
2686 goto out;
2687 }
2688
2689 /* Finally, enable manual roaming */
2690 priv->bssid_fixed = 1;
2691 memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
2692
2693 out:
2694 orinoco_unlock(priv, &flags);
2695 return err;
2696}
2697
2698static int orinoco_ioctl_getwap(struct net_device *dev,
2699 struct iw_request_info *info,
2700 struct sockaddr *ap_addr,
2701 char *extra)
2702{
2703 struct orinoco_private *priv = netdev_priv(dev);
2704
2705 hermes_t *hw = &priv->hw;
2706 int err = 0;
2707 unsigned long flags;
2708
2709 if (orinoco_lock(priv, &flags) != 0)
2710 return -EBUSY;
2711
2712 ap_addr->sa_family = ARPHRD_ETHER;
2713 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
2714 ETH_ALEN, NULL, ap_addr->sa_data);
2715
2716 orinoco_unlock(priv, &flags);
2717
2718 return err;
2719}
2647 2720
2648 if (!access_ok(VERIFY_WRITE, rrq->pointer, sizeof(range))) 2721static int orinoco_ioctl_setmode(struct net_device *dev,
2649 return -EFAULT; 2722 struct iw_request_info *info,
2723 u32 *mode,
2724 char *extra)
2725{
2726 struct orinoco_private *priv = netdev_priv(dev);
2727 int err = -EINPROGRESS; /* Call commit handler */
2728 unsigned long flags;
2650 2729
2651 rrq->length = sizeof(range); 2730 if (priv->iw_mode == *mode)
2731 return 0;
2652 2732
2653 if (orinoco_lock(priv, &flags) != 0) 2733 if (orinoco_lock(priv, &flags) != 0)
2654 return -EBUSY; 2734 return -EBUSY;
2655 2735
2656 mode = priv->iw_mode; 2736 switch (*mode) {
2737 case IW_MODE_ADHOC:
2738 if (!priv->has_ibss && !priv->has_port3)
2739 err = -EOPNOTSUPP;
2740 break;
2741
2742 case IW_MODE_INFRA:
2743 break;
2744
2745 case IW_MODE_MONITOR:
2746 if (priv->broken_monitor && !force_monitor) {
2747 printk(KERN_WARNING "%s: Monitor mode support is "
2748 "buggy in this firmware, not enabling\n",
2749 dev->name);
2750 err = -EOPNOTSUPP;
2751 }
2752 break;
2753
2754 default:
2755 err = -EOPNOTSUPP;
2756 break;
2757 }
2758
2759 if (err == -EINPROGRESS) {
2760 priv->iw_mode = *mode;
2761 set_port_type(priv);
2762 }
2763
2657 orinoco_unlock(priv, &flags); 2764 orinoco_unlock(priv, &flags);
2658 2765
2659 memset(&range, 0, sizeof(range)); 2766 return err;
2767}
2768
2769static int orinoco_ioctl_getmode(struct net_device *dev,
2770 struct iw_request_info *info,
2771 u32 *mode,
2772 char *extra)
2773{
2774 struct orinoco_private *priv = netdev_priv(dev);
2775
2776 *mode = priv->iw_mode;
2777 return 0;
2778}
2779
2780static int orinoco_ioctl_getiwrange(struct net_device *dev,
2781 struct iw_request_info *info,
2782 struct iw_point *rrq,
2783 char *extra)
2784{
2785 struct orinoco_private *priv = netdev_priv(dev);
2786 int err = 0;
2787 struct iw_range *range = (struct iw_range *) extra;
2788 int numrates;
2789 int i, k;
2790
2791 TRACE_ENTER(dev->name);
2660 2792
2661 /* Much of this shamelessly taken from wvlan_cs.c. No idea 2793 rrq->length = sizeof(struct iw_range);
2662 * what it all means -dgibson */ 2794 memset(range, 0, sizeof(struct iw_range));
2663 range.we_version_compiled = WIRELESS_EXT;
2664 range.we_version_source = 11;
2665 2795
2666 range.min_nwid = range.max_nwid = 0; /* We don't use nwids */ 2796 range->we_version_compiled = WIRELESS_EXT;
2797 range->we_version_source = 14;
2667 2798
2668 /* Set available channels/frequencies */ 2799 /* Set available channels/frequencies */
2669 range.num_channels = NUM_CHANNELS; 2800 range->num_channels = NUM_CHANNELS;
2670 k = 0; 2801 k = 0;
2671 for (i = 0; i < NUM_CHANNELS; i++) { 2802 for (i = 0; i < NUM_CHANNELS; i++) {
2672 if (priv->channel_mask & (1 << i)) { 2803 if (priv->channel_mask & (1 << i)) {
2673 range.freq[k].i = i + 1; 2804 range->freq[k].i = i + 1;
2674 range.freq[k].m = channel_frequency[i] * 100000; 2805 range->freq[k].m = channel_frequency[i] * 100000;
2675 range.freq[k].e = 1; 2806 range->freq[k].e = 1;
2676 k++; 2807 k++;
2677 } 2808 }
2678 2809
2679 if (k >= IW_MAX_FREQUENCIES) 2810 if (k >= IW_MAX_FREQUENCIES)
2680 break; 2811 break;
2681 } 2812 }
2682 range.num_frequency = k; 2813 range->num_frequency = k;
2814 range->sensitivity = 3;
2683 2815
2684 range.sensitivity = 3; 2816 if (priv->has_wep) {
2817 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
2818 range->encoding_size[0] = SMALL_KEY_SIZE;
2819 range->num_encoding_sizes = 1;
2685 2820
2686 if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){ 2821 if (priv->has_big_wep) {
2822 range->encoding_size[1] = LARGE_KEY_SIZE;
2823 range->num_encoding_sizes = 2;
2824 }
2825 }
2826
2827 if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
2687 /* Quality stats meaningless in ad-hoc mode */ 2828 /* Quality stats meaningless in ad-hoc mode */
2688 range.max_qual.qual = 0;
2689 range.max_qual.level = 0;
2690 range.max_qual.noise = 0;
2691 range.avg_qual.qual = 0;
2692 range.avg_qual.level = 0;
2693 range.avg_qual.noise = 0;
2694 } else { 2829 } else {
2695 range.max_qual.qual = 0x8b - 0x2f; 2830 range->max_qual.qual = 0x8b - 0x2f;
2696 range.max_qual.level = 0x2f - 0x95 - 1; 2831 range->max_qual.level = 0x2f - 0x95 - 1;
2697 range.max_qual.noise = 0x2f - 0x95 - 1; 2832 range->max_qual.noise = 0x2f - 0x95 - 1;
2698 /* Need to get better values */ 2833 /* Need to get better values */
2699 range.avg_qual.qual = 0x24; 2834 range->avg_qual.qual = 0x24;
2700 range.avg_qual.level = 0xC2; 2835 range->avg_qual.level = 0xC2;
2701 range.avg_qual.noise = 0x9E; 2836 range->avg_qual.noise = 0x9E;
2702 } 2837 }
2703 2838
2704 err = orinoco_hw_get_bitratelist(priv, &numrates, 2839 err = orinoco_hw_get_bitratelist(priv, &numrates,
2705 range.bitrate, IW_MAX_BITRATES); 2840 range->bitrate, IW_MAX_BITRATES);
2706 if (err) 2841 if (err)
2707 return err; 2842 return err;
2708 range.num_bitrates = numrates; 2843 range->num_bitrates = numrates;
2709 2844
2710 /* Set an indication of the max TCP throughput in bit/s that we can 2845 /* Set an indication of the max TCP throughput in bit/s that we can
2711 * expect using this interface. May be use for QoS stuff... 2846 * expect using this interface. May be use for QoS stuff...
2712 * Jean II */ 2847 * Jean II */
2713 if(numrates > 2) 2848 if (numrates > 2)
2714 range.throughput = 5 * 1000 * 1000; /* ~5 Mb/s */ 2849 range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
2715 else 2850 else
2716 range.throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */ 2851 range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
2717 2852
2718 range.min_rts = 0; 2853 range->min_rts = 0;
2719 range.max_rts = 2347; 2854 range->max_rts = 2347;
2720 range.min_frag = 256; 2855 range->min_frag = 256;
2721 range.max_frag = 2346; 2856 range->max_frag = 2346;
2722 2857
2723 if (orinoco_lock(priv, &flags) != 0) 2858 range->min_pmp = 0;
2724 return -EBUSY; 2859 range->max_pmp = 65535000;
2725 if (priv->has_wep) { 2860 range->min_pmt = 0;
2726 range.max_encoding_tokens = ORINOCO_MAX_KEYS; 2861 range->max_pmt = 65535 * 1000; /* ??? */
2727 2862 range->pmp_flags = IW_POWER_PERIOD;
2728 range.encoding_size[0] = SMALL_KEY_SIZE; 2863 range->pmt_flags = IW_POWER_TIMEOUT;
2729 range.num_encoding_sizes = 1; 2864 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
2730 2865
2731 if (priv->has_big_wep) { 2866 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
2732 range.encoding_size[1] = LARGE_KEY_SIZE; 2867 range->retry_flags = IW_RETRY_LIMIT;
2733 range.num_encoding_sizes = 2; 2868 range->r_time_flags = IW_RETRY_LIFETIME;
2734 } 2869 range->min_retry = 0;
2735 } else { 2870 range->max_retry = 65535; /* ??? */
2736 range.num_encoding_sizes = 0; 2871 range->min_r_time = 0;
2737 range.max_encoding_tokens = 0; 2872 range->max_r_time = 65535 * 1000; /* ??? */
2738 }
2739 orinoco_unlock(priv, &flags);
2740
2741 range.min_pmp = 0;
2742 range.max_pmp = 65535000;
2743 range.min_pmt = 0;
2744 range.max_pmt = 65535 * 1000; /* ??? */
2745 range.pmp_flags = IW_POWER_PERIOD;
2746 range.pmt_flags = IW_POWER_TIMEOUT;
2747 range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
2748
2749 range.num_txpower = 1;
2750 range.txpower[0] = 15; /* 15dBm */
2751 range.txpower_capa = IW_TXPOW_DBM;
2752
2753 range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
2754 range.retry_flags = IW_RETRY_LIMIT;
2755 range.r_time_flags = IW_RETRY_LIFETIME;
2756 range.min_retry = 0;
2757 range.max_retry = 65535; /* ??? */
2758 range.min_r_time = 0;
2759 range.max_r_time = 65535 * 1000; /* ??? */
2760
2761 if (copy_to_user(rrq->pointer, &range, sizeof(range)))
2762 return -EFAULT;
2763 2873
2764 TRACE_EXIT(dev->name); 2874 TRACE_EXIT(dev->name);
2765 2875
2766 return 0; 2876 return 0;
2767} 2877}
2768 2878
2769static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq) 2879static int orinoco_ioctl_setiwencode(struct net_device *dev,
2880 struct iw_request_info *info,
2881 struct iw_point *erq,
2882 char *keybuf)
2770{ 2883{
2771 struct orinoco_private *priv = netdev_priv(dev); 2884 struct orinoco_private *priv = netdev_priv(dev);
2772 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 2885 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
@@ -2774,8 +2887,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *er
2774 int enable = priv->wep_on; 2887 int enable = priv->wep_on;
2775 int restricted = priv->wep_restrict; 2888 int restricted = priv->wep_restrict;
2776 u16 xlen = 0; 2889 u16 xlen = 0;
2777 int err = 0; 2890 int err = -EINPROGRESS; /* Call commit handler */
2778 char keybuf[ORINOCO_MAX_KEY_SIZE];
2779 unsigned long flags; 2891 unsigned long flags;
2780 2892
2781 if (! priv->has_wep) 2893 if (! priv->has_wep)
@@ -2788,9 +2900,6 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *er
2788 2900
2789 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep ) 2901 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
2790 return -E2BIG; 2902 return -E2BIG;
2791
2792 if (copy_from_user(keybuf, erq->pointer, erq->length))
2793 return -EFAULT;
2794 } 2903 }
2795 2904
2796 if (orinoco_lock(priv, &flags) != 0) 2905 if (orinoco_lock(priv, &flags) != 0)
@@ -2864,12 +2973,14 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *er
2864 return err; 2973 return err;
2865} 2974}
2866 2975
2867static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq) 2976static int orinoco_ioctl_getiwencode(struct net_device *dev,
2977 struct iw_request_info *info,
2978 struct iw_point *erq,
2979 char *keybuf)
2868{ 2980{
2869 struct orinoco_private *priv = netdev_priv(dev); 2981 struct orinoco_private *priv = netdev_priv(dev);
2870 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 2982 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2871 u16 xlen = 0; 2983 u16 xlen = 0;
2872 char keybuf[ORINOCO_MAX_KEY_SIZE];
2873 unsigned long flags; 2984 unsigned long flags;
2874 2985
2875 if (! priv->has_wep) 2986 if (! priv->has_wep)
@@ -2898,51 +3009,47 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *er
2898 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE); 3009 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
2899 3010
2900 orinoco_unlock(priv, &flags); 3011 orinoco_unlock(priv, &flags);
2901
2902 if (erq->pointer) {
2903 if (copy_to_user(erq->pointer, keybuf, xlen))
2904 return -EFAULT;
2905 }
2906
2907 return 0; 3012 return 0;
2908} 3013}
2909 3014
2910static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq) 3015static int orinoco_ioctl_setessid(struct net_device *dev,
3016 struct iw_request_info *info,
3017 struct iw_point *erq,
3018 char *essidbuf)
2911{ 3019{
2912 struct orinoco_private *priv = netdev_priv(dev); 3020 struct orinoco_private *priv = netdev_priv(dev);
2913 char essidbuf[IW_ESSID_MAX_SIZE+1];
2914 unsigned long flags; 3021 unsigned long flags;
2915 3022
2916 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it 3023 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2917 * anyway... - Jean II */ 3024 * anyway... - Jean II */
2918 3025
2919 memset(&essidbuf, 0, sizeof(essidbuf)); 3026 /* Hum... Should not use Wireless Extension constant (may change),
2920 3027 * should use our own... - Jean II */
2921 if (erq->flags) { 3028 if (erq->length > IW_ESSID_MAX_SIZE)
2922 /* iwconfig includes the NUL in the specified length */ 3029 return -E2BIG;
2923 if (erq->length > IW_ESSID_MAX_SIZE+1)
2924 return -E2BIG;
2925
2926 if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2927 return -EFAULT;
2928
2929 essidbuf[IW_ESSID_MAX_SIZE] = '\0';
2930 }
2931 3030
2932 if (orinoco_lock(priv, &flags) != 0) 3031 if (orinoco_lock(priv, &flags) != 0)
2933 return -EBUSY; 3032 return -EBUSY;
2934 3033
2935 memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid)); 3034 /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
3035 memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
3036
3037 /* If not ANY, get the new ESSID */
3038 if (erq->flags) {
3039 memcpy(priv->desired_essid, essidbuf, erq->length);
3040 }
2936 3041
2937 orinoco_unlock(priv, &flags); 3042 orinoco_unlock(priv, &flags);
2938 3043
2939 return 0; 3044 return -EINPROGRESS; /* Call commit handler */
2940} 3045}
2941 3046
2942static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq) 3047static int orinoco_ioctl_getessid(struct net_device *dev,
3048 struct iw_request_info *info,
3049 struct iw_point *erq,
3050 char *essidbuf)
2943{ 3051{
2944 struct orinoco_private *priv = netdev_priv(dev); 3052 struct orinoco_private *priv = netdev_priv(dev);
2945 char essidbuf[IW_ESSID_MAX_SIZE+1];
2946 int active; 3053 int active;
2947 int err = 0; 3054 int err = 0;
2948 unsigned long flags; 3055 unsigned long flags;
@@ -2956,51 +3063,46 @@ static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
2956 } else { 3063 } else {
2957 if (orinoco_lock(priv, &flags) != 0) 3064 if (orinoco_lock(priv, &flags) != 0)
2958 return -EBUSY; 3065 return -EBUSY;
2959 memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf)); 3066 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
2960 orinoco_unlock(priv, &flags); 3067 orinoco_unlock(priv, &flags);
2961 } 3068 }
2962 3069
2963 erq->flags = 1; 3070 erq->flags = 1;
2964 erq->length = strlen(essidbuf) + 1; 3071 erq->length = strlen(essidbuf) + 1;
2965 if (erq->pointer)
2966 if (copy_to_user(erq->pointer, essidbuf, erq->length))
2967 return -EFAULT;
2968 3072
2969 TRACE_EXIT(dev->name); 3073 TRACE_EXIT(dev->name);
2970 3074
2971 return 0; 3075 return 0;
2972} 3076}
2973 3077
2974static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq) 3078static int orinoco_ioctl_setnick(struct net_device *dev,
3079 struct iw_request_info *info,
3080 struct iw_point *nrq,
3081 char *nickbuf)
2975{ 3082{
2976 struct orinoco_private *priv = netdev_priv(dev); 3083 struct orinoco_private *priv = netdev_priv(dev);
2977 char nickbuf[IW_ESSID_MAX_SIZE+1];
2978 unsigned long flags; 3084 unsigned long flags;
2979 3085
2980 if (nrq->length > IW_ESSID_MAX_SIZE) 3086 if (nrq->length > IW_ESSID_MAX_SIZE)
2981 return -E2BIG; 3087 return -E2BIG;
2982 3088
2983 memset(nickbuf, 0, sizeof(nickbuf));
2984
2985 if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
2986 return -EFAULT;
2987
2988 nickbuf[nrq->length] = '\0';
2989
2990 if (orinoco_lock(priv, &flags) != 0) 3089 if (orinoco_lock(priv, &flags) != 0)
2991 return -EBUSY; 3090 return -EBUSY;
2992 3091
2993 memcpy(priv->nick, nickbuf, sizeof(priv->nick)); 3092 memset(priv->nick, 0, sizeof(priv->nick));
3093 memcpy(priv->nick, nickbuf, nrq->length);
2994 3094
2995 orinoco_unlock(priv, &flags); 3095 orinoco_unlock(priv, &flags);
2996 3096
2997 return 0; 3097 return -EINPROGRESS; /* Call commit handler */
2998} 3098}
2999 3099
3000static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq) 3100static int orinoco_ioctl_getnick(struct net_device *dev,
3101 struct iw_request_info *info,
3102 struct iw_point *nrq,
3103 char *nickbuf)
3001{ 3104{
3002 struct orinoco_private *priv = netdev_priv(dev); 3105 struct orinoco_private *priv = netdev_priv(dev);
3003 char nickbuf[IW_ESSID_MAX_SIZE+1];
3004 unsigned long flags; 3106 unsigned long flags;
3005 3107
3006 if (orinoco_lock(priv, &flags) != 0) 3108 if (orinoco_lock(priv, &flags) != 0)
@@ -3011,23 +3113,22 @@ static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
3011 3113
3012 nrq->length = strlen(nickbuf)+1; 3114 nrq->length = strlen(nickbuf)+1;
3013 3115
3014 if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
3015 return -EFAULT;
3016
3017 return 0; 3116 return 0;
3018} 3117}
3019 3118
3020static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq) 3119static int orinoco_ioctl_setfreq(struct net_device *dev,
3120 struct iw_request_info *info,
3121 struct iw_freq *frq,
3122 char *extra)
3021{ 3123{
3022 struct orinoco_private *priv = netdev_priv(dev); 3124 struct orinoco_private *priv = netdev_priv(dev);
3023 int chan = -1; 3125 int chan = -1;
3024 unsigned long flags; 3126 unsigned long flags;
3127 int err = -EINPROGRESS; /* Call commit handler */
3025 3128
3026 /* We can only use this in Ad-Hoc demo mode to set the operating 3129 /* In infrastructure mode the AP sets the channel */
3027 * frequency, or in IBSS mode to set the frequency where the IBSS 3130 if (priv->iw_mode == IW_MODE_INFRA)
3028 * will be created - Jean II */ 3131 return -EBUSY;
3029 if (priv->iw_mode != IW_MODE_ADHOC)
3030 return -EOPNOTSUPP;
3031 3132
3032 if ( (frq->e == 0) && (frq->m <= 1000) ) { 3133 if ( (frq->e == 0) && (frq->m <= 1000) ) {
3033 /* Setting by channel number */ 3134 /* Setting by channel number */
@@ -3051,13 +3152,44 @@ static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
3051 3152
3052 if (orinoco_lock(priv, &flags) != 0) 3153 if (orinoco_lock(priv, &flags) != 0)
3053 return -EBUSY; 3154 return -EBUSY;
3155
3054 priv->channel = chan; 3156 priv->channel = chan;
3157 if (priv->iw_mode == IW_MODE_MONITOR) {
3158 /* Fast channel change - no commit if successful */
3159 hermes_t *hw = &priv->hw;
3160 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
3161 HERMES_TEST_SET_CHANNEL,
3162 chan, NULL);
3163 }
3055 orinoco_unlock(priv, &flags); 3164 orinoco_unlock(priv, &flags);
3056 3165
3166 return err;
3167}
3168
3169static int orinoco_ioctl_getfreq(struct net_device *dev,
3170 struct iw_request_info *info,
3171 struct iw_freq *frq,
3172 char *extra)
3173{
3174 struct orinoco_private *priv = netdev_priv(dev);
3175 int tmp;
3176
3177 /* Locking done in there */
3178 tmp = orinoco_hw_get_freq(priv);
3179 if (tmp < 0) {
3180 return tmp;
3181 }
3182
3183 frq->m = tmp;
3184 frq->e = 1;
3185
3057 return 0; 3186 return 0;
3058} 3187}
3059 3188
3060static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq) 3189static int orinoco_ioctl_getsens(struct net_device *dev,
3190 struct iw_request_info *info,
3191 struct iw_param *srq,
3192 char *extra)
3061{ 3193{
3062 struct orinoco_private *priv = netdev_priv(dev); 3194 struct orinoco_private *priv = netdev_priv(dev);
3063 hermes_t *hw = &priv->hw; 3195 hermes_t *hw = &priv->hw;
@@ -3083,7 +3215,10 @@ static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
3083 return 0; 3215 return 0;
3084} 3216}
3085 3217
3086static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq) 3218static int orinoco_ioctl_setsens(struct net_device *dev,
3219 struct iw_request_info *info,
3220 struct iw_param *srq,
3221 char *extra)
3087{ 3222{
3088 struct orinoco_private *priv = netdev_priv(dev); 3223 struct orinoco_private *priv = netdev_priv(dev);
3089 int val = srq->value; 3224 int val = srq->value;
@@ -3100,10 +3235,13 @@ static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
3100 priv->ap_density = val; 3235 priv->ap_density = val;
3101 orinoco_unlock(priv, &flags); 3236 orinoco_unlock(priv, &flags);
3102 3237
3103 return 0; 3238 return -EINPROGRESS; /* Call commit handler */
3104} 3239}
3105 3240
3106static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq) 3241static int orinoco_ioctl_setrts(struct net_device *dev,
3242 struct iw_request_info *info,
3243 struct iw_param *rrq,
3244 char *extra)
3107{ 3245{
3108 struct orinoco_private *priv = netdev_priv(dev); 3246 struct orinoco_private *priv = netdev_priv(dev);
3109 int val = rrq->value; 3247 int val = rrq->value;
@@ -3121,13 +3259,30 @@ static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
3121 priv->rts_thresh = val; 3259 priv->rts_thresh = val;
3122 orinoco_unlock(priv, &flags); 3260 orinoco_unlock(priv, &flags);
3123 3261
3262 return -EINPROGRESS; /* Call commit handler */
3263}
3264
3265static int orinoco_ioctl_getrts(struct net_device *dev,
3266 struct iw_request_info *info,
3267 struct iw_param *rrq,
3268 char *extra)
3269{
3270 struct orinoco_private *priv = netdev_priv(dev);
3271
3272 rrq->value = priv->rts_thresh;
3273 rrq->disabled = (rrq->value == 2347);
3274 rrq->fixed = 1;
3275
3124 return 0; 3276 return 0;
3125} 3277}
3126 3278
3127static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq) 3279static int orinoco_ioctl_setfrag(struct net_device *dev,
3280 struct iw_request_info *info,
3281 struct iw_param *frq,
3282 char *extra)
3128{ 3283{
3129 struct orinoco_private *priv = netdev_priv(dev); 3284 struct orinoco_private *priv = netdev_priv(dev);
3130 int err = 0; 3285 int err = -EINPROGRESS; /* Call commit handler */
3131 unsigned long flags; 3286 unsigned long flags;
3132 3287
3133 if (orinoco_lock(priv, &flags) != 0) 3288 if (orinoco_lock(priv, &flags) != 0)
@@ -3159,11 +3314,14 @@ static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
3159 return err; 3314 return err;
3160} 3315}
3161 3316
3162static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq) 3317static int orinoco_ioctl_getfrag(struct net_device *dev,
3318 struct iw_request_info *info,
3319 struct iw_param *frq,
3320 char *extra)
3163{ 3321{
3164 struct orinoco_private *priv = netdev_priv(dev); 3322 struct orinoco_private *priv = netdev_priv(dev);
3165 hermes_t *hw = &priv->hw; 3323 hermes_t *hw = &priv->hw;
3166 int err = 0; 3324 int err;
3167 u16 val; 3325 u16 val;
3168 unsigned long flags; 3326 unsigned long flags;
3169 3327
@@ -3196,10 +3354,12 @@ static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
3196 return err; 3354 return err;
3197} 3355}
3198 3356
3199static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq) 3357static int orinoco_ioctl_setrate(struct net_device *dev,
3358 struct iw_request_info *info,
3359 struct iw_param *rrq,
3360 char *extra)
3200{ 3361{
3201 struct orinoco_private *priv = netdev_priv(dev); 3362 struct orinoco_private *priv = netdev_priv(dev);
3202 int err = 0;
3203 int ratemode = -1; 3363 int ratemode = -1;
3204 int bitrate; /* 100s of kilobits */ 3364 int bitrate; /* 100s of kilobits */
3205 int i; 3365 int i;
@@ -3235,10 +3395,13 @@ static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
3235 priv->bitratemode = ratemode; 3395 priv->bitratemode = ratemode;
3236 orinoco_unlock(priv, &flags); 3396 orinoco_unlock(priv, &flags);
3237 3397
3238 return err; 3398 return -EINPROGRESS;
3239} 3399}
3240 3400
3241static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq) 3401static int orinoco_ioctl_getrate(struct net_device *dev,
3402 struct iw_request_info *info,
3403 struct iw_param *rrq,
3404 char *extra)
3242{ 3405{
3243 struct orinoco_private *priv = netdev_priv(dev); 3406 struct orinoco_private *priv = netdev_priv(dev);
3244 hermes_t *hw = &priv->hw; 3407 hermes_t *hw = &priv->hw;
@@ -3303,10 +3466,13 @@ static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
3303 return err; 3466 return err;
3304} 3467}
3305 3468
3306static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq) 3469static int orinoco_ioctl_setpower(struct net_device *dev,
3470 struct iw_request_info *info,
3471 struct iw_param *prq,
3472 char *extra)
3307{ 3473{
3308 struct orinoco_private *priv = netdev_priv(dev); 3474 struct orinoco_private *priv = netdev_priv(dev);
3309 int err = 0; 3475 int err = -EINPROGRESS; /* Call commit handler */
3310 unsigned long flags; 3476 unsigned long flags;
3311 3477
3312 if (orinoco_lock(priv, &flags) != 0) 3478 if (orinoco_lock(priv, &flags) != 0)
@@ -3355,7 +3521,10 @@ static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
3355 return err; 3521 return err;
3356} 3522}
3357 3523
3358static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq) 3524static int orinoco_ioctl_getpower(struct net_device *dev,
3525 struct iw_request_info *info,
3526 struct iw_param *prq,
3527 char *extra)
3359{ 3528{
3360 struct orinoco_private *priv = netdev_priv(dev); 3529 struct orinoco_private *priv = netdev_priv(dev);
3361 hermes_t *hw = &priv->hw; 3530 hermes_t *hw = &priv->hw;
@@ -3403,7 +3572,10 @@ static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
3403 return err; 3572 return err;
3404} 3573}
3405 3574
3406static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq) 3575static int orinoco_ioctl_getretry(struct net_device *dev,
3576 struct iw_request_info *info,
3577 struct iw_param *rrq,
3578 char *extra)
3407{ 3579{
3408 struct orinoco_private *priv = netdev_priv(dev); 3580 struct orinoco_private *priv = netdev_priv(dev);
3409 hermes_t *hw = &priv->hw; 3581 hermes_t *hw = &priv->hw;
@@ -3454,10 +3626,38 @@ static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
3454 return err; 3626 return err;
3455} 3627}
3456 3628
3457static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq) 3629static int orinoco_ioctl_reset(struct net_device *dev,
3630 struct iw_request_info *info,
3631 void *wrqu,
3632 char *extra)
3458{ 3633{
3459 struct orinoco_private *priv = netdev_priv(dev); 3634 struct orinoco_private *priv = netdev_priv(dev);
3460 int val = *( (int *) wrq->u.name ); 3635
3636 if (! capable(CAP_NET_ADMIN))
3637 return -EPERM;
3638
3639 if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
3640 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
3641
3642 /* Firmware reset */
3643 orinoco_reset(dev);
3644 } else {
3645 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
3646
3647 schedule_work(&priv->reset_work);
3648 }
3649
3650 return 0;
3651}
3652
3653static int orinoco_ioctl_setibssport(struct net_device *dev,
3654 struct iw_request_info *info,
3655 void *wrqu,
3656 char *extra)
3657
3658{
3659 struct orinoco_private *priv = netdev_priv(dev);
3660 int val = *( (int *) extra );
3461 unsigned long flags; 3661 unsigned long flags;
3462 3662
3463 if (orinoco_lock(priv, &flags) != 0) 3663 if (orinoco_lock(priv, &flags) != 0)
@@ -3469,28 +3669,28 @@ static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
3469 set_port_type(priv); 3669 set_port_type(priv);
3470 3670
3471 orinoco_unlock(priv, &flags); 3671 orinoco_unlock(priv, &flags);
3472 return 0; 3672 return -EINPROGRESS; /* Call commit handler */
3473} 3673}
3474 3674
3475static int orinoco_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq) 3675static int orinoco_ioctl_getibssport(struct net_device *dev,
3676 struct iw_request_info *info,
3677 void *wrqu,
3678 char *extra)
3476{ 3679{
3477 struct orinoco_private *priv = netdev_priv(dev); 3680 struct orinoco_private *priv = netdev_priv(dev);
3478 int *val = (int *)wrq->u.name; 3681 int *val = (int *) extra;
3479 unsigned long flags;
3480
3481 if (orinoco_lock(priv, &flags) != 0)
3482 return -EBUSY;
3483 3682
3484 *val = priv->ibss_port; 3683 *val = priv->ibss_port;
3485 orinoco_unlock(priv, &flags);
3486
3487 return 0; 3684 return 0;
3488} 3685}
3489 3686
3490static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq) 3687static int orinoco_ioctl_setport3(struct net_device *dev,
3688 struct iw_request_info *info,
3689 void *wrqu,
3690 char *extra)
3491{ 3691{
3492 struct orinoco_private *priv = netdev_priv(dev); 3692 struct orinoco_private *priv = netdev_priv(dev);
3493 int val = *( (int *) wrq->u.name ); 3693 int val = *( (int *) extra );
3494 int err = 0; 3694 int err = 0;
3495 unsigned long flags; 3695 unsigned long flags;
3496 3696
@@ -3519,51 +3719,131 @@ static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
3519 err = -EINVAL; 3719 err = -EINVAL;
3520 } 3720 }
3521 3721
3522 if (! err) 3722 if (! err) {
3523 /* Actually update the mode we are using */ 3723 /* Actually update the mode we are using */
3524 set_port_type(priv); 3724 set_port_type(priv);
3725 err = -EINPROGRESS;
3726 }
3525 3727
3526 orinoco_unlock(priv, &flags); 3728 orinoco_unlock(priv, &flags);
3527 3729
3528 return err; 3730 return err;
3529} 3731}
3530 3732
3531static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq) 3733static int orinoco_ioctl_getport3(struct net_device *dev,
3734 struct iw_request_info *info,
3735 void *wrqu,
3736 char *extra)
3737{
3738 struct orinoco_private *priv = netdev_priv(dev);
3739 int *val = (int *) extra;
3740
3741 *val = priv->prefer_port3;
3742 return 0;
3743}
3744
3745static int orinoco_ioctl_setpreamble(struct net_device *dev,
3746 struct iw_request_info *info,
3747 void *wrqu,
3748 char *extra)
3532{ 3749{
3533 struct orinoco_private *priv = netdev_priv(dev); 3750 struct orinoco_private *priv = netdev_priv(dev);
3534 int *val = (int *)wrq->u.name;
3535 unsigned long flags; 3751 unsigned long flags;
3752 int val;
3753
3754 if (! priv->has_preamble)
3755 return -EOPNOTSUPP;
3756
3757 /* 802.11b has recently defined some short preamble.
3758 * Basically, the Phy header has been reduced in size.
3759 * This increase performance, especially at high rates
3760 * (the preamble is transmitted at 1Mb/s), unfortunately
3761 * this give compatibility troubles... - Jean II */
3762 val = *( (int *) extra );
3536 3763
3537 if (orinoco_lock(priv, &flags) != 0) 3764 if (orinoco_lock(priv, &flags) != 0)
3538 return -EBUSY; 3765 return -EBUSY;
3539 3766
3540 *val = priv->prefer_port3; 3767 if (val)
3768 priv->preamble = 1;
3769 else
3770 priv->preamble = 0;
3771
3541 orinoco_unlock(priv, &flags); 3772 orinoco_unlock(priv, &flags);
3773
3774 return -EINPROGRESS; /* Call commit handler */
3775}
3776
3777static int orinoco_ioctl_getpreamble(struct net_device *dev,
3778 struct iw_request_info *info,
3779 void *wrqu,
3780 char *extra)
3781{
3782 struct orinoco_private *priv = netdev_priv(dev);
3783 int *val = (int *) extra;
3784
3785 if (! priv->has_preamble)
3786 return -EOPNOTSUPP;
3787
3788 *val = priv->preamble;
3542 return 0; 3789 return 0;
3543} 3790}
3544 3791
3792/* ioctl interface to hermes_read_ltv()
3793 * To use with iwpriv, pass the RID as the token argument, e.g.
3794 * iwpriv get_rid [0xfc00]
3795 * At least Wireless Tools 25 is required to use iwpriv.
3796 * For Wireless Tools 25 and 26 append "dummy" are the end. */
3797static int orinoco_ioctl_getrid(struct net_device *dev,
3798 struct iw_request_info *info,
3799 struct iw_point *data,
3800 char *extra)
3801{
3802 struct orinoco_private *priv = netdev_priv(dev);
3803 hermes_t *hw = &priv->hw;
3804 int rid = data->flags;
3805 u16 length;
3806 int err;
3807 unsigned long flags;
3808
3809 /* It's a "get" function, but we don't want users to access the
3810 * WEP key and other raw firmware data */
3811 if (! capable(CAP_NET_ADMIN))
3812 return -EPERM;
3813
3814 if (rid < 0xfc00 || rid > 0xffff)
3815 return -EINVAL;
3816
3817 if (orinoco_lock(priv, &flags) != 0)
3818 return -EBUSY;
3819
3820 err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
3821 extra);
3822 if (err)
3823 goto out;
3824
3825 data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
3826 MAX_RID_LEN);
3827
3828 out:
3829 orinoco_unlock(priv, &flags);
3830 return err;
3831}
3832
3545/* Spy is used for link quality/strength measurements in Ad-Hoc mode 3833/* Spy is used for link quality/strength measurements in Ad-Hoc mode
3546 * Jean II */ 3834 * Jean II */
3547static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq) 3835static int orinoco_ioctl_setspy(struct net_device *dev,
3836 struct iw_request_info *info,
3837 struct iw_point *srq,
3838 char *extra)
3839
3548{ 3840{
3549 struct orinoco_private *priv = netdev_priv(dev); 3841 struct orinoco_private *priv = netdev_priv(dev);
3550 struct sockaddr address[IW_MAX_SPY]; 3842 struct sockaddr *address = (struct sockaddr *) extra;
3551 int number = srq->length; 3843 int number = srq->length;
3552 int i; 3844 int i;
3553 int err = 0;
3554 unsigned long flags; 3845 unsigned long flags;
3555 3846
3556 /* Check the number of addresses */
3557 if (number > IW_MAX_SPY)
3558 return -E2BIG;
3559
3560 /* Get the data in the driver */
3561 if (srq->pointer) {
3562 if (copy_from_user(address, srq->pointer,
3563 sizeof(struct sockaddr) * number))
3564 return -EFAULT;
3565 }
3566
3567 /* Make sure nobody mess with the structure while we do */ 3847 /* Make sure nobody mess with the structure while we do */
3568 if (orinoco_lock(priv, &flags) != 0) 3848 if (orinoco_lock(priv, &flags) != 0)
3569 return -EBUSY; 3849 return -EBUSY;
@@ -3587,14 +3867,17 @@ static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
3587 /* Now, let the others play */ 3867 /* Now, let the others play */
3588 orinoco_unlock(priv, &flags); 3868 orinoco_unlock(priv, &flags);
3589 3869
3590 return err; 3870 /* Do NOT call commit handler */
3871 return 0;
3591} 3872}
3592 3873
3593static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq) 3874static int orinoco_ioctl_getspy(struct net_device *dev,
3875 struct iw_request_info *info,
3876 struct iw_point *srq,
3877 char *extra)
3594{ 3878{
3595 struct orinoco_private *priv = netdev_priv(dev); 3879 struct orinoco_private *priv = netdev_priv(dev);
3596 struct sockaddr address[IW_MAX_SPY]; 3880 struct sockaddr *address = (struct sockaddr *) extra;
3597 struct iw_quality spy_stat[IW_MAX_SPY];
3598 int number; 3881 int number;
3599 int i; 3882 int i;
3600 unsigned long flags; 3883 unsigned long flags;
@@ -3603,7 +3886,12 @@ static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
3603 return -EBUSY; 3886 return -EBUSY;
3604 3887
3605 number = priv->spy_number; 3888 number = priv->spy_number;
3606 if ((number > 0) && (srq->pointer)) { 3889 /* Create address struct */
3890 for (i = 0; i < number; i++) {
3891 memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
3892 address[i].sa_family = AF_UNIX;
3893 }
3894 if (number > 0) {
3607 /* Create address struct */ 3895 /* Create address struct */
3608 for (i = 0; i < number; i++) { 3896 for (i = 0; i < number; i++) {
3609 memcpy(address[i].sa_data, priv->spy_address[i], 3897 memcpy(address[i].sa_data, priv->spy_address[i],
@@ -3614,344 +3902,503 @@ static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
3614 /* In theory, we should disable irqs while copying the stats 3902 /* In theory, we should disable irqs while copying the stats
3615 * because the rx path might update it in the middle... 3903 * because the rx path might update it in the middle...
3616 * Bah, who care ? - Jean II */ 3904 * Bah, who care ? - Jean II */
3617 memcpy(&spy_stat, priv->spy_stat, 3905 memcpy(extra + (sizeof(struct sockaddr) * number),
3618 sizeof(struct iw_quality) * IW_MAX_SPY); 3906 priv->spy_stat, sizeof(struct iw_quality) * number);
3619 for (i=0; i < number; i++)
3620 priv->spy_stat[i].updated = 0;
3621 } 3907 }
3908 /* Reset updated flags. */
3909 for (i = 0; i < number; i++)
3910 priv->spy_stat[i].updated = 0;
3622 3911
3623 orinoco_unlock(priv, &flags); 3912 orinoco_unlock(priv, &flags);
3624 3913
3625 /* Push stuff to user space */
3626 srq->length = number; 3914 srq->length = number;
3627 if(copy_to_user(srq->pointer, address,
3628 sizeof(struct sockaddr) * number))
3629 return -EFAULT;
3630 if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
3631 &spy_stat, sizeof(struct iw_quality) * number))
3632 return -EFAULT;
3633 3915
3634 return 0; 3916 return 0;
3635} 3917}
3636 3918
3637static int 3919/* Trigger a scan (look for other cells in the vicinity */
3638orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 3920static int orinoco_ioctl_setscan(struct net_device *dev,
3921 struct iw_request_info *info,
3922 struct iw_param *srq,
3923 char *extra)
3639{ 3924{
3640 struct orinoco_private *priv = netdev_priv(dev); 3925 struct orinoco_private *priv = netdev_priv(dev);
3641 struct iwreq *wrq = (struct iwreq *)rq; 3926 hermes_t *hw = &priv->hw;
3642 int err = 0; 3927 int err = 0;
3643 int tmp;
3644 int changed = 0;
3645 unsigned long flags; 3928 unsigned long flags;
3646 3929
3647 TRACE_ENTER(dev->name); 3930 /* Note : you may have realised that, as this is a SET operation,
3931 * this is priviledged and therefore a normal user can't
3932 * perform scanning.
3933 * This is not an error, while the device perform scanning,
3934 * traffic doesn't flow, so it's a perfect DoS...
3935 * Jean II */
3648 3936
3649 /* In theory, we could allow most of the the SET stuff to be 3937 if (orinoco_lock(priv, &flags) != 0)
3650 * done. In practice, the lapse of time at startup when the 3938 return -EBUSY;
3651 * card is not ready is very short, so why bother... Note
3652 * that netif_device_present is different from up/down
3653 * (ifconfig), when the device is not yet up, it is usually
3654 * already ready... Jean II */
3655 if (! netif_device_present(dev))
3656 return -ENODEV;
3657 3939
3658 switch (cmd) { 3940 /* Scanning with port 0 disabled would fail */
3659 case SIOCGIWNAME: 3941 if (!netif_running(dev)) {
3660 strcpy(wrq->u.name, "IEEE 802.11-DS"); 3942 err = -ENETDOWN;
3661 break; 3943 goto out;
3662 3944 }
3663 case SIOCGIWAP:
3664 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
3665 err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
3666 break;
3667 3945
3668 case SIOCGIWRANGE: 3946 /* In monitor mode, the scan results are always empty.
3669 err = orinoco_ioctl_getiwrange(dev, &wrq->u.data); 3947 * Probe responses are passed to the driver as received
3670 break; 3948 * frames and could be processed in software. */
3949 if (priv->iw_mode == IW_MODE_MONITOR) {
3950 err = -EOPNOTSUPP;
3951 goto out;
3952 }
3671 3953
3672 case SIOCSIWMODE: 3954 /* Note : because we don't lock out the irq handler, the way
3673 if (orinoco_lock(priv, &flags) != 0) 3955 * we access scan variables in priv is critical.
3674 return -EBUSY; 3956 * o scan_inprogress : not touched by irq handler
3675 switch (wrq->u.mode) { 3957 * o scan_mode : not touched by irq handler
3676 case IW_MODE_ADHOC: 3958 * o scan_result : irq is strict producer, non-irq is strict
3677 if (! (priv->has_ibss || priv->has_port3) ) 3959 * consumer.
3678 err = -EINVAL; 3960 * o scan_len : synchronised with scan_result
3679 else { 3961 * Before modifying anything on those variables, please think hard !
3680 priv->iw_mode = IW_MODE_ADHOC; 3962 * Jean II */
3681 changed = 1;
3682 }
3683 break;
3684 3963
3685 case IW_MODE_INFRA: 3964 /* If there is still some left-over scan results, get rid of it */
3686 priv->iw_mode = IW_MODE_INFRA; 3965 if (priv->scan_result != NULL) {
3687 changed = 1; 3966 /* What's likely is that a client did crash or was killed
3688 break; 3967 * between triggering the scan request and reading the
3968 * results, so we need to reset everything.
3969 * Some clients that are too slow may suffer from that...
3970 * Jean II */
3971 kfree(priv->scan_result);
3972 priv->scan_result = NULL;
3973 }
3689 3974
3690 default: 3975 /* Save flags */
3691 err = -EINVAL; 3976 priv->scan_mode = srq->flags;
3692 break;
3693 }
3694 set_port_type(priv);
3695 orinoco_unlock(priv, &flags);
3696 break;
3697 3977
3698 case SIOCGIWMODE: 3978 /* Always trigger scanning, even if it's in progress.
3699 if (orinoco_lock(priv, &flags) != 0) 3979 * This way, if the info frame get lost, we will recover somewhat
3700 return -EBUSY; 3980 * gracefully - Jean II */
3701 wrq->u.mode = priv->iw_mode;
3702 orinoco_unlock(priv, &flags);
3703 break;
3704 3981
3705 case SIOCSIWENCODE: 3982 if (priv->has_hostscan) {
3706 err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding); 3983 switch (priv->firmware_type) {
3707 if (! err) 3984 case FIRMWARE_TYPE_SYMBOL:
3708 changed = 1; 3985 err = hermes_write_wordrec(hw, USER_BAP,
3986 HERMES_RID_CNFHOSTSCAN_SYMBOL,
3987 HERMES_HOSTSCAN_SYMBOL_ONCE |
3988 HERMES_HOSTSCAN_SYMBOL_BCAST);
3989 break;
3990 case FIRMWARE_TYPE_INTERSIL: {
3991 u16 req[3];
3992
3993 req[0] = cpu_to_le16(0x3fff); /* All channels */
3994 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
3995 req[2] = 0; /* Any ESSID */
3996 err = HERMES_WRITE_RECORD(hw, USER_BAP,
3997 HERMES_RID_CNFHOSTSCAN, &req);
3998 }
3709 break; 3999 break;
4000 case FIRMWARE_TYPE_AGERE:
4001 err = hermes_write_wordrec(hw, USER_BAP,
4002 HERMES_RID_CNFSCANSSID_AGERE,
4003 0); /* Any ESSID */
4004 if (err)
4005 break;
3710 4006
3711 case SIOCGIWENCODE: 4007 err = hermes_inquire(hw, HERMES_INQ_SCAN);
3712 if (! capable(CAP_NET_ADMIN)) {
3713 err = -EPERM;
3714 break; 4008 break;
3715 } 4009 }
4010 } else
4011 err = hermes_inquire(hw, HERMES_INQ_SCAN);
3716 4012
3717 err = orinoco_ioctl_getiwencode(dev, &wrq->u.encoding); 4013 /* One more client */
3718 break; 4014 if (! err)
3719 4015 priv->scan_inprogress = 1;
3720 case SIOCSIWESSID:
3721 err = orinoco_ioctl_setessid(dev, &wrq->u.essid);
3722 if (! err)
3723 changed = 1;
3724 break;
3725 4016
3726 case SIOCGIWESSID: 4017 out:
3727 err = orinoco_ioctl_getessid(dev, &wrq->u.essid); 4018 orinoco_unlock(priv, &flags);
3728 break; 4019 return err;
4020}
3729 4021
3730 case SIOCSIWNICKN: 4022/* Translate scan data returned from the card to a card independant
3731 err = orinoco_ioctl_setnick(dev, &wrq->u.data); 4023 * format that the Wireless Tools will understand - Jean II */
3732 if (! err) 4024static inline int orinoco_translate_scan(struct net_device *dev,
3733 changed = 1; 4025 char *buffer,
3734 break; 4026 char *scan,
4027 int scan_len)
4028{
4029 struct orinoco_private *priv = netdev_priv(dev);
4030 int offset; /* In the scan data */
4031 union hermes_scan_info *atom;
4032 int atom_len;
4033 u16 capabilities;
4034 u16 channel;
4035 struct iw_event iwe; /* Temporary buffer */
4036 char * current_ev = buffer;
4037 char * end_buf = buffer + IW_SCAN_MAX_DATA;
3735 4038
3736 case SIOCGIWNICKN: 4039 switch (priv->firmware_type) {
3737 err = orinoco_ioctl_getnick(dev, &wrq->u.data); 4040 case FIRMWARE_TYPE_AGERE:
4041 atom_len = sizeof(struct agere_scan_apinfo);
4042 offset = 0;
3738 break; 4043 break;
3739 4044 case FIRMWARE_TYPE_SYMBOL:
3740 case SIOCGIWFREQ: 4045 /* Lack of documentation necessitates this hack.
3741 tmp = orinoco_hw_get_freq(priv); 4046 * Different firmwares have 68 or 76 byte long atoms.
3742 if (tmp < 0) { 4047 * We try modulo first. If the length divides by both,
3743 err = tmp; 4048 * we check what would be the channel in the second
3744 } else { 4049 * frame for a 68-byte atom. 76-byte atoms have 0 there.
3745 wrq->u.freq.m = tmp; 4050 * Valid channel cannot be 0. */
3746 wrq->u.freq.e = 1; 4051 if (scan_len % 76)
3747 } 4052 atom_len = 68;
4053 else if (scan_len % 68)
4054 atom_len = 76;
4055 else if (scan_len >= 1292 && scan[68] == 0)
4056 atom_len = 76;
4057 else
4058 atom_len = 68;
4059 offset = 0;
3748 break; 4060 break;
3749 4061 case FIRMWARE_TYPE_INTERSIL:
3750 case SIOCSIWFREQ: 4062 offset = 4;
3751 err = orinoco_ioctl_setfreq(dev, &wrq->u.freq); 4063 if (priv->has_hostscan)
3752 if (! err) 4064 atom_len = scan[0] + (scan[1] << 8);
3753 changed = 1; 4065 else
4066 atom_len = offsetof(struct prism2_scan_apinfo, atim);
3754 break; 4067 break;
4068 default:
4069 return 0;
4070 }
3755 4071
3756 case SIOCGIWSENS: 4072 /* Check that we got an whole number of atoms */
3757 err = orinoco_ioctl_getsens(dev, &wrq->u.sens); 4073 if ((scan_len - offset) % atom_len) {
3758 break; 4074 printk(KERN_ERR "%s: Unexpected scan data length %d, "
4075 "atom_len %d, offset %d\n", dev->name, scan_len,
4076 atom_len, offset);
4077 return 0;
4078 }
3759 4079
3760 case SIOCSIWSENS: 4080 /* Read the entries one by one */
3761 err = orinoco_ioctl_setsens(dev, &wrq->u.sens); 4081 for (; offset + atom_len <= scan_len; offset += atom_len) {
3762 if (! err) 4082 /* Get next atom */
3763 changed = 1; 4083 atom = (union hermes_scan_info *) (scan + offset);
3764 break; 4084
4085 /* First entry *MUST* be the AP MAC address */
4086 iwe.cmd = SIOCGIWAP;
4087 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4088 memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
4089 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
4090
4091 /* Other entries will be displayed in the order we give them */
4092
4093 /* Add the ESSID */
4094 iwe.u.data.length = le16_to_cpu(atom->a.essid_len);
4095 if (iwe.u.data.length > 32)
4096 iwe.u.data.length = 32;
4097 iwe.cmd = SIOCGIWESSID;
4098 iwe.u.data.flags = 1;
4099 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
4100
4101 /* Add mode */
4102 iwe.cmd = SIOCGIWMODE;
4103 capabilities = le16_to_cpu(atom->a.capabilities);
4104 if (capabilities & 0x3) {
4105 if (capabilities & 0x1)
4106 iwe.u.mode = IW_MODE_MASTER;
4107 else
4108 iwe.u.mode = IW_MODE_ADHOC;
4109 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
4110 }
3765 4111
3766 case SIOCGIWRTS: 4112 channel = atom->s.channel;
3767 wrq->u.rts.value = priv->rts_thresh; 4113 if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) {
3768 wrq->u.rts.disabled = (wrq->u.rts.value == 2347); 4114 /* Add frequency */
3769 wrq->u.rts.fixed = 1; 4115 iwe.cmd = SIOCGIWFREQ;
3770 break; 4116 iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4117 iwe.u.freq.e = 1;
4118 current_ev = iwe_stream_add_event(current_ev, end_buf,
4119 &iwe, IW_EV_FREQ_LEN);
4120 }
3771 4121
3772 case SIOCSIWRTS: 4122 /* Add quality statistics */
3773 err = orinoco_ioctl_setrts(dev, &wrq->u.rts); 4123 iwe.cmd = IWEVQUAL;
3774 if (! err) 4124 iwe.u.qual.updated = 0x10; /* no link quality */
3775 changed = 1; 4125 iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95;
3776 break; 4126 iwe.u.qual.noise = (__u8) le16_to_cpu(atom->a.noise) - 0x95;
4127 /* Wireless tools prior to 27.pre22 will show link quality
4128 * anyway, so we provide a reasonable value. */
4129 if (iwe.u.qual.level > iwe.u.qual.noise)
4130 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4131 else
4132 iwe.u.qual.qual = 0;
4133 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
3777 4134
3778 case SIOCSIWFRAG: 4135 /* Add encryption capability */
3779 err = orinoco_ioctl_setfrag(dev, &wrq->u.frag); 4136 iwe.cmd = SIOCGIWENCODE;
3780 if (! err) 4137 if (capabilities & 0x10)
3781 changed = 1; 4138 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
3782 break; 4139 else
4140 iwe.u.data.flags = IW_ENCODE_DISABLED;
4141 iwe.u.data.length = 0;
4142 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
4143
4144 /* Bit rate is not available in Lucent/Agere firmwares */
4145 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
4146 char * current_val = current_ev + IW_EV_LCP_LEN;
4147 int i;
4148 int step;
4149
4150 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
4151 step = 2;
4152 else
4153 step = 1;
4154
4155 iwe.cmd = SIOCGIWRATE;
4156 /* Those two flags are ignored... */
4157 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4158 /* Max 10 values */
4159 for (i = 0; i < 10; i += step) {
4160 /* NULL terminated */
4161 if (atom->p.rates[i] == 0x0)
4162 break;
4163 /* Bit rate given in 500 kb/s units (+ 0x80) */
4164 iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
4165 current_val = iwe_stream_add_value(current_ev, current_val,
4166 end_buf, &iwe,
4167 IW_EV_PARAM_LEN);
4168 }
4169 /* Check if we added any event */
4170 if ((current_val - current_ev) > IW_EV_LCP_LEN)
4171 current_ev = current_val;
4172 }
3783 4173
3784 case SIOCGIWFRAG: 4174 /* The other data in the scan result are not really
3785 err = orinoco_ioctl_getfrag(dev, &wrq->u.frag); 4175 * interesting, so for now drop it - Jean II */
3786 break; 4176 }
4177 return current_ev - buffer;
4178}
3787 4179
3788 case SIOCSIWRATE: 4180/* Return results of a scan */
3789 err = orinoco_ioctl_setrate(dev, &wrq->u.bitrate); 4181static int orinoco_ioctl_getscan(struct net_device *dev,
3790 if (! err) 4182 struct iw_request_info *info,
3791 changed = 1; 4183 struct iw_point *srq,
3792 break; 4184 char *extra)
4185{
4186 struct orinoco_private *priv = netdev_priv(dev);
4187 int err = 0;
4188 unsigned long flags;
3793 4189
3794 case SIOCGIWRATE: 4190 if (orinoco_lock(priv, &flags) != 0)
3795 err = orinoco_ioctl_getrate(dev, &wrq->u.bitrate); 4191 return -EBUSY;
3796 break;
3797 4192
3798 case SIOCSIWPOWER: 4193 /* If no results yet, ask to try again later */
3799 err = orinoco_ioctl_setpower(dev, &wrq->u.power); 4194 if (priv->scan_result == NULL) {
3800 if (! err) 4195 if (priv->scan_inprogress)
3801 changed = 1; 4196 /* Important note : we don't want to block the caller
3802 break; 4197 * until results are ready for various reasons.
4198 * First, managing wait queues is complex and racy.
4199 * Second, we grab some rtnetlink lock before comming
4200 * here (in dev_ioctl()).
4201 * Third, we generate an Wireless Event, so the
4202 * caller can wait itself on that - Jean II */
4203 err = -EAGAIN;
4204 else
4205 /* Client error, no scan results...
4206 * The caller need to restart the scan. */
4207 err = -ENODATA;
4208 } else {
4209 /* We have some results to push back to user space */
4210
4211 /* Translate to WE format */
4212 srq->length = orinoco_translate_scan(dev, extra,
4213 priv->scan_result,
4214 priv->scan_len);
4215
4216 /* Return flags */
4217 srq->flags = (__u16) priv->scan_mode;
4218
4219 /* Results are here, so scan no longer in progress */
4220 priv->scan_inprogress = 0;
4221
4222 /* In any case, Scan results will be cleaned up in the
4223 * reset function and when exiting the driver.
4224 * The person triggering the scanning may never come to
4225 * pick the results, so we need to do it in those places.
4226 * Jean II */
4227
4228#ifdef SCAN_SINGLE_READ
4229 /* If you enable this option, only one client (the first
4230 * one) will be able to read the result (and only one
4231 * time). If there is multiple concurent clients that
4232 * want to read scan results, this behavior is not
4233 * advisable - Jean II */
4234 kfree(priv->scan_result);
4235 priv->scan_result = NULL;
4236#endif /* SCAN_SINGLE_READ */
4237 /* Here, if too much time has elapsed since last scan,
4238 * we may want to clean up scan results... - Jean II */
4239 }
4240
4241 orinoco_unlock(priv, &flags);
4242 return err;
4243}
3803 4244
3804 case SIOCGIWPOWER: 4245/* Commit handler, called after set operations */
3805 err = orinoco_ioctl_getpower(dev, &wrq->u.power); 4246static int orinoco_ioctl_commit(struct net_device *dev,
3806 break; 4247 struct iw_request_info *info,
4248 void *wrqu,
4249 char *extra)
4250{
4251 struct orinoco_private *priv = netdev_priv(dev);
4252 struct hermes *hw = &priv->hw;
4253 unsigned long flags;
4254 int err = 0;
3807 4255
3808 case SIOCGIWTXPOW: 4256 if (!priv->open)
3809 /* The card only supports one tx power, so this is easy */ 4257 return 0;
3810 wrq->u.txpower.value = 15; /* dBm */
3811 wrq->u.txpower.fixed = 1;
3812 wrq->u.txpower.disabled = 0;
3813 wrq->u.txpower.flags = IW_TXPOW_DBM;
3814 break;
3815 4258
3816 case SIOCSIWRETRY: 4259 if (priv->broken_disableport) {
3817 err = -EOPNOTSUPP; 4260 orinoco_reset(dev);
3818 break; 4261 return 0;
4262 }
3819 4263
3820 case SIOCGIWRETRY: 4264 if (orinoco_lock(priv, &flags) != 0)
3821 err = orinoco_ioctl_getretry(dev, &wrq->u.retry); 4265 return err;
3822 break;
3823 4266
3824 case SIOCSIWSPY: 4267 err = hermes_disable_port(hw, 0);
3825 err = orinoco_ioctl_setspy(dev, &wrq->u.data); 4268 if (err) {
3826 break; 4269 printk(KERN_WARNING "%s: Unable to disable port "
4270 "while reconfiguring card\n", dev->name);
4271 priv->broken_disableport = 1;
4272 goto out;
4273 }
3827 4274
3828 case SIOCGIWSPY: 4275 err = __orinoco_program_rids(dev);
3829 err = orinoco_ioctl_getspy(dev, &wrq->u.data); 4276 if (err) {
3830 break; 4277 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
4278 dev->name);
4279 goto out;
4280 }
3831 4281
3832 case SIOCGIWPRIV: 4282 err = hermes_enable_port(hw, 0);
3833 if (wrq->u.data.pointer) { 4283 if (err) {
3834 struct iw_priv_args privtab[] = { 4284 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
3835 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" }, 4285 dev->name);
3836 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" }, 4286 goto out;
3837 { SIOCIWFIRSTPRIV + 0x2, 4287 }
3838 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3839 0, "set_port3" },
3840 { SIOCIWFIRSTPRIV + 0x3, 0,
3841 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3842 "get_port3" },
3843 { SIOCIWFIRSTPRIV + 0x4,
3844 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3845 0, "set_preamble" },
3846 { SIOCIWFIRSTPRIV + 0x5, 0,
3847 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3848 "get_preamble" },
3849 { SIOCIWFIRSTPRIV + 0x6,
3850 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3851 0, "set_ibssport" },
3852 { SIOCIWFIRSTPRIV + 0x7, 0,
3853 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3854 "get_ibssport" },
3855 };
3856
3857 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
3858 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
3859 err = -EFAULT;
3860 }
3861 break;
3862
3863 case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
3864 case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
3865 if (! capable(CAP_NET_ADMIN)) {
3866 err = -EPERM;
3867 break;
3868 }
3869
3870 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
3871 4288
4289 out:
4290 if (err) {
4291 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
3872 schedule_work(&priv->reset_work); 4292 schedule_work(&priv->reset_work);
3873 break; 4293 err = 0;
3874 4294 }
3875 case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
3876 if (! capable(CAP_NET_ADMIN)) {
3877 err = -EPERM;
3878 break;
3879 }
3880
3881 err = orinoco_ioctl_setport3(dev, wrq);
3882 if (! err)
3883 changed = 1;
3884 break;
3885 4295
3886 case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */ 4296 orinoco_unlock(priv, &flags);
3887 err = orinoco_ioctl_getport3(dev, wrq); 4297 return err;
3888 break; 4298}
3889 4299
3890 case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */ 4300static const struct iw_priv_args orinoco_privtab[] = {
3891 if (! capable(CAP_NET_ADMIN)) { 4301 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
3892 err = -EPERM; 4302 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
3893 break; 4303 { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3894 } 4304 0, "set_port3" },
4305 { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4306 "get_port3" },
4307 { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4308 0, "set_preamble" },
4309 { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4310 "get_preamble" },
4311 { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4312 0, "set_ibssport" },
4313 { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4314 "get_ibssport" },
4315 { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
4316 "get_rid" },
4317};
3895 4318
3896 /* 802.11b has recently defined some short preamble.
3897 * Basically, the Phy header has been reduced in size.
3898 * This increase performance, especially at high rates
3899 * (the preamble is transmitted at 1Mb/s), unfortunately
3900 * this give compatibility troubles... - Jean II */
3901 if(priv->has_preamble) {
3902 int val = *( (int *) wrq->u.name );
3903
3904 if (orinoco_lock(priv, &flags) != 0)
3905 return -EBUSY;
3906 if (val)
3907 priv->preamble = 1;
3908 else
3909 priv->preamble = 0;
3910 orinoco_unlock(priv, &flags);
3911 changed = 1;
3912 } else
3913 err = -EOPNOTSUPP;
3914 break;
3915 4319
3916 case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */ 4320/*
3917 if(priv->has_preamble) { 4321 * Structures to export the Wireless Handlers
3918 int *val = (int *)wrq->u.name; 4322 */
3919 4323
3920 if (orinoco_lock(priv, &flags) != 0) 4324static const iw_handler orinoco_handler[] = {
3921 return -EBUSY; 4325 [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit,
3922 *val = priv->preamble; 4326 [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname,
3923 orinoco_unlock(priv, &flags); 4327 [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq,
3924 } else 4328 [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq,
3925 err = -EOPNOTSUPP; 4329 [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode,
3926 break; 4330 [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode,
3927 case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */ 4331 [SIOCSIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens,
3928 if (! capable(CAP_NET_ADMIN)) { 4332 [SIOCGIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens,
3929 err = -EPERM; 4333 [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange,
3930 break; 4334 [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy,
3931 } 4335 [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getspy,
4336 [SIOCSIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setwap,
4337 [SIOCGIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getwap,
4338 [SIOCSIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setscan,
4339 [SIOCGIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getscan,
4340 [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setessid,
4341 [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getessid,
4342 [SIOCSIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setnick,
4343 [SIOCGIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getnick,
4344 [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrate,
4345 [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrate,
4346 [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrts,
4347 [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrts,
4348 [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfrag,
4349 [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfrag,
4350 [SIOCGIWRETRY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getretry,
4351 [SIOCSIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_setiwencode,
4352 [SIOCGIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwencode,
4353 [SIOCSIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setpower,
4354 [SIOCGIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getpower,
4355};
3932 4356
3933 err = orinoco_ioctl_setibssport(dev, wrq);
3934 if (! err)
3935 changed = 1;
3936 break;
3937 4357
3938 case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */ 4358/*
3939 err = orinoco_ioctl_getibssport(dev, wrq); 4359 Added typecasting since we no longer use iwreq_data -- Moustafa
3940 break; 4360 */
4361static const iw_handler orinoco_private_handler[] = {
4362 [0] (iw_handler) orinoco_ioctl_reset,
4363 [1] (iw_handler) orinoco_ioctl_reset,
4364 [2] (iw_handler) orinoco_ioctl_setport3,
4365 [3] (iw_handler) orinoco_ioctl_getport3,
4366 [4] (iw_handler) orinoco_ioctl_setpreamble,
4367 [5] (iw_handler) orinoco_ioctl_getpreamble,
4368 [6] (iw_handler) orinoco_ioctl_setibssport,
4369 [7] (iw_handler) orinoco_ioctl_getibssport,
4370 [9] (iw_handler) orinoco_ioctl_getrid,
4371};
3941 4372
3942 default: 4373static const struct iw_handler_def orinoco_handler_def = {
3943 err = -EOPNOTSUPP; 4374 .num_standard = ARRAY_SIZE(orinoco_handler),
3944 } 4375 .num_private = ARRAY_SIZE(orinoco_private_handler),
3945 4376 .num_private_args = ARRAY_SIZE(orinoco_privtab),
3946 if (! err && changed && netif_running(dev)) { 4377 .standard = orinoco_handler,
3947 err = orinoco_reconfigure(dev); 4378 .private = orinoco_private_handler,
3948 } 4379 .private_args = orinoco_privtab,
4380};
3949 4381
3950 TRACE_EXIT(dev->name); 4382static void orinoco_get_drvinfo(struct net_device *dev,
4383 struct ethtool_drvinfo *info)
4384{
4385 struct orinoco_private *priv = netdev_priv(dev);
3951 4386
3952 return err; 4387 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
4388 strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
4389 strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
4390 if (dev->class_dev.dev)
4391 strncpy(info->bus_info, dev->class_dev.dev->bus_id,
4392 sizeof(info->bus_info) - 1);
4393 else
4394 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
4395 "PCMCIA %p", priv->hw.iobase);
3953} 4396}
3954 4397
4398static struct ethtool_ops orinoco_ethtool_ops = {
4399 .get_drvinfo = orinoco_get_drvinfo,
4400 .get_link = ethtool_op_get_link,
4401};
3955 4402
3956/********************************************************************/ 4403/********************************************************************/
3957/* Debugging */ 4404/* Debugging */