Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 4496 lines 122 kB view raw
1/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c) 2 * 3 * A driver for Hermes or Prism 2 chipset based PCMCIA wireless 4 * adaptors, with Lucent/Agere, Intersil or Symbol firmware. 5 * 6 * Current maintainers (as of 29 September 2003) are: 7 * Pavel Roskin <proski AT gnu.org> 8 * and David Gibson <hermes AT gibson.dropbear.id.au> 9 * 10 * (C) Copyright David Gibson, IBM Corporation 2001-2003. 11 * Copyright (C) 2000 David Gibson, Linuxcare Australia. 12 * With some help from : 13 * Copyright (C) 2001 Jean Tourrilhes, HP Labs 14 * Copyright (C) 2001 Benjamin Herrenschmidt 15 * 16 * Based on dummy_cs.c 1.27 2000/06/12 21:27:25 17 * 18 * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy 19 * AT fasta.fh-dortmund.de> 20 * http://www.stud.fh-dortmund.de/~andy/wvlan/ 21 * 22 * The contents of this file are subject to the Mozilla Public License 23 * Version 1.1 (the "License"); you may not use this file except in 24 * compliance with the License. You may obtain a copy of the License 25 * at http://www.mozilla.org/MPL/ 26 * 27 * Software distributed under the License is distributed on an "AS IS" 28 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 29 * the License for the specific language governing rights and 30 * limitations under the License. 31 * 32 * The initial developer of the original code is David A. Hinds 33 * <dahinds AT users.sourceforge.net>. Portions created by David 34 * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights 35 * Reserved. 36 * 37 * Alternatively, the contents of this file may be used under the 38 * terms of the GNU General Public License version 2 (the "GPL"), in 39 * which case the provisions of the GPL are applicable instead of the 40 * above. If you wish to allow the use of your version of this file 41 * only under the terms of the GPL and not to allow others to use your 42 * version of this file under the MPL, indicate your decision by 43 * deleting the provisions above and replace them with the notice and 44 * other provisions required by the GPL. If you do not delete the 45 * provisions above, a recipient may use your version of this file 46 * under either the MPL or the GPL. */ 47 48/* 49 * TODO 50 * o Handle de-encapsulation within network layer, provide 802.11 51 * headers (patch from Thomas 'Dent' Mirlacher) 52 * o Fix possible races in SPY handling. 53 * o Disconnect wireless extensions from fundamental configuration. 54 * o (maybe) Software WEP support (patch from Stano Meduna). 55 * o (maybe) Use multiple Tx buffers - driver handling queue 56 * rather than firmware. 57 */ 58 59/* Locking and synchronization: 60 * 61 * The basic principle is that everything is serialized through a 62 * single spinlock, priv->lock. The lock is used in user, bh and irq 63 * context, so when taken outside hardirq context it should always be 64 * taken with interrupts disabled. The lock protects both the 65 * hardware and the struct orinoco_private. 66 * 67 * Another flag, priv->hw_unavailable indicates that the hardware is 68 * unavailable for an extended period of time (e.g. suspended, or in 69 * the middle of a hard reset). This flag is protected by the 70 * spinlock. All code which touches the hardware should check the 71 * flag after taking the lock, and if it is set, give up on whatever 72 * they are doing and drop the lock again. The orinoco_lock() 73 * function handles this (it unlocks and returns -EBUSY if 74 * hw_unavailable is non-zero). 75 */ 76 77#define DRIVER_NAME "orinoco" 78 79#include <linux/config.h> 80 81#include <linux/module.h> 82#include <linux/kernel.h> 83#include <linux/init.h> 84#include <linux/ptrace.h> 85#include <linux/slab.h> 86#include <linux/string.h> 87#include <linux/timer.h> 88#include <linux/ioport.h> 89#include <linux/netdevice.h> 90#include <linux/if_arp.h> 91#include <linux/etherdevice.h> 92#include <linux/ethtool.h> 93#include <linux/wireless.h> 94#include <net/iw_handler.h> 95#include <net/ieee80211.h> 96 97#include <asm/uaccess.h> 98#include <asm/io.h> 99#include <asm/system.h> 100 101#include "hermes.h" 102#include "hermes_rid.h" 103#include "orinoco.h" 104#include "ieee802_11.h" 105 106/********************************************************************/ 107/* Module information */ 108/********************************************************************/ 109 110MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>"); 111MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards"); 112MODULE_LICENSE("Dual MPL/GPL"); 113 114/* Level of debugging. Used in the macros in orinoco.h */ 115#ifdef ORINOCO_DEBUG 116int orinoco_debug = ORINOCO_DEBUG; 117module_param(orinoco_debug, int, 0644); 118MODULE_PARM_DESC(orinoco_debug, "Debug level"); 119EXPORT_SYMBOL(orinoco_debug); 120#endif 121 122static int suppress_linkstatus; /* = 0 */ 123module_param(suppress_linkstatus, bool, 0644); 124MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); 125static int ignore_disconnect; /* = 0 */ 126module_param(ignore_disconnect, int, 0644); 127MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer"); 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 133/********************************************************************/ 134/* Compile time configuration and compatibility stuff */ 135/********************************************************************/ 136 137/* We do this this way to avoid ifdefs in the actual code */ 138#ifdef WIRELESS_SPY 139#define SPY_NUMBER(priv) (priv->spy_number) 140#else 141#define SPY_NUMBER(priv) 0 142#endif /* WIRELESS_SPY */ 143 144/********************************************************************/ 145/* Internal constants */ 146/********************************************************************/ 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 152#define ORINOCO_MIN_MTU 256 153#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD) 154 155#define SYMBOL_MAX_VER_LEN (14) 156#define USER_BAP 0 157#define IRQ_BAP 1 158#define MAX_IRQLOOPS_PER_IRQ 10 159#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of 160 * how many events the 161 * device could 162 * legitimately generate */ 163#define SMALL_KEY_SIZE 5 164#define LARGE_KEY_SIZE 13 165#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */ 166 167#define DUMMY_FID 0xFFFF 168 169/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \ 170 HERMES_MAX_MULTICAST : 0)*/ 171#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST) 172 173#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \ 174 | HERMES_EV_TX | HERMES_EV_TXEXC \ 175 | HERMES_EV_WTERR | HERMES_EV_INFO \ 176 | HERMES_EV_INFDROP ) 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 183/********************************************************************/ 184/* Data tables */ 185/********************************************************************/ 186 187/* The frequency of each channel in MHz */ 188static const long channel_frequency[] = { 189 2412, 2417, 2422, 2427, 2432, 2437, 2442, 190 2447, 2452, 2457, 2462, 2467, 2472, 2484 191}; 192#define NUM_CHANNELS ARRAY_SIZE(channel_frequency) 193 194/* This tables gives the actual meanings of the bitrate IDs returned 195 * by the firmware. */ 196static struct { 197 int bitrate; /* in 100s of kilobits */ 198 int automatic; 199 u16 agere_txratectrl; 200 u16 intersil_txratectrl; 201} bitrate_table[] = { 202 {110, 1, 3, 15}, /* Entry 0 is the default */ 203 {10, 0, 1, 1}, 204 {10, 1, 1, 1}, 205 {20, 0, 2, 2}, 206 {20, 1, 6, 3}, 207 {55, 0, 4, 4}, 208 {55, 1, 7, 7}, 209 {110, 0, 5, 8}, 210}; 211#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table) 212 213/********************************************************************/ 214/* Data types */ 215/********************************************************************/ 216 217/* Used in Event handling. 218 * We avoid nested structres as they break on ARM -- Moustafa */ 219struct hermes_tx_descriptor_802_11 { 220 /* hermes_tx_descriptor */ 221 u16 status; 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 */ 245 u8 dsap; 246 u8 ssap; 247 u8 ctrl; 248 u8 oui[3]; 249 250 u16 ethertype; 251} __attribute__ ((packed)); 252 253/* Rx frame header except compatibility 802.3 header */ 254struct hermes_rx_descriptor { 255 /* Control */ 256 u16 status; 257 u32 time; 258 u8 silence; 259 u8 signal; 260 u8 rate; 261 u8 rxflow; 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; 275} __attribute__ ((packed)); 276 277/********************************************************************/ 278/* Function prototypes */ 279/********************************************************************/ 280 281static int __orinoco_program_rids(struct net_device *dev); 282static void __orinoco_set_multicast_list(struct net_device *dev); 283 284/********************************************************************/ 285/* Internal helper functions */ 286/********************************************************************/ 287 288static inline void set_port_type(struct orinoco_private *priv) 289{ 290 switch (priv->iw_mode) { 291 case IW_MODE_INFRA: 292 priv->port_type = 1; 293 priv->createibss = 0; 294 break; 295 case IW_MODE_ADHOC: 296 if (priv->prefer_port3) { 297 priv->port_type = 3; 298 priv->createibss = 0; 299 } else { 300 priv->port_type = priv->ibss_port; 301 priv->createibss = 1; 302 } 303 break; 304 case IW_MODE_MONITOR: 305 priv->port_type = 3; 306 priv->createibss = 0; 307 break; 308 default: 309 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n", 310 priv->ndev->name); 311 } 312} 313 314/********************************************************************/ 315/* Device methods */ 316/********************************************************************/ 317 318static int orinoco_open(struct net_device *dev) 319{ 320 struct orinoco_private *priv = netdev_priv(dev); 321 unsigned long flags; 322 int err; 323 324 if (orinoco_lock(priv, &flags) != 0) 325 return -EBUSY; 326 327 err = __orinoco_up(dev); 328 329 if (! err) 330 priv->open = 1; 331 332 orinoco_unlock(priv, &flags); 333 334 return err; 335} 336 337static int orinoco_stop(struct net_device *dev) 338{ 339 struct orinoco_private *priv = netdev_priv(dev); 340 int err = 0; 341 342 /* We mustn't use orinoco_lock() here, because we need to be 343 able to close the interface even if hw_unavailable is set 344 (e.g. as we're released after a PC Card removal) */ 345 spin_lock_irq(&priv->lock); 346 347 priv->open = 0; 348 349 err = __orinoco_down(dev); 350 351 spin_unlock_irq(&priv->lock); 352 353 return err; 354} 355 356static struct net_device_stats *orinoco_get_stats(struct net_device *dev) 357{ 358 struct orinoco_private *priv = netdev_priv(dev); 359 360 return &priv->stats; 361} 362 363static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) 364{ 365 struct orinoco_private *priv = netdev_priv(dev); 366 hermes_t *hw = &priv->hw; 367 struct iw_statistics *wstats = &priv->wstats; 368 int err; 369 unsigned long flags; 370 371 if (! netif_device_present(dev)) { 372 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n", 373 dev->name); 374 return NULL; /* FIXME: Can we do better than this? */ 375 } 376 377 /* If busy, return the old stats. Returning NULL may cause 378 * the interface to disappear from /proc/net/wireless */ 379 if (orinoco_lock(priv, &flags) != 0) 380 return wstats; 381 382 /* We can't really wait for the tallies inquiry command to 383 * complete, so we just use the previous results and trigger 384 * a new tallies inquiry command for next time - Jean II */ 385 /* FIXME: Really we should wait for the inquiry to come back - 386 * as it is the stats we give don't make a whole lot of sense. 387 * Unfortunately, it's not clear how to do that within the 388 * wireless extensions framework: I think we're in user 389 * context, but a lock seems to be held by the time we get in 390 * here so we're not safe to sleep here. */ 391 hermes_inquire(hw, HERMES_INQ_TALLIES); 392 393 if (priv->iw_mode == IW_MODE_ADHOC) { 394 memset(&wstats->qual, 0, sizeof(wstats->qual)); 395 /* If a spy address is defined, we report stats of the 396 * first spy address - Jean II */ 397 if (SPY_NUMBER(priv)) { 398 wstats->qual.qual = priv->spy_stat[0].qual; 399 wstats->qual.level = priv->spy_stat[0].level; 400 wstats->qual.noise = priv->spy_stat[0].noise; 401 wstats->qual.updated = priv->spy_stat[0].updated; 402 } 403 } else { 404 struct { 405 u16 qual, signal, noise; 406 } __attribute__ ((packed)) cq; 407 408 err = HERMES_READ_RECORD(hw, USER_BAP, 409 HERMES_RID_COMMSQUALITY, &cq); 410 411 if (!err) { 412 wstats->qual.qual = (int)le16_to_cpu(cq.qual); 413 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; 414 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; 415 wstats->qual.updated = 7; 416 } 417 } 418 419 orinoco_unlock(priv, &flags); 420 return wstats; 421} 422 423static void orinoco_set_multicast_list(struct net_device *dev) 424{ 425 struct orinoco_private *priv = netdev_priv(dev); 426 unsigned long flags; 427 428 if (orinoco_lock(priv, &flags) != 0) { 429 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() " 430 "called when hw_unavailable\n", dev->name); 431 return; 432 } 433 434 __orinoco_set_multicast_list(dev); 435 orinoco_unlock(priv, &flags); 436} 437 438static int orinoco_change_mtu(struct net_device *dev, int new_mtu) 439{ 440 struct orinoco_private *priv = netdev_priv(dev); 441 442 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) 443 return -EINVAL; 444 445 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) > 446 (priv->nicbuf_size - ETH_HLEN) ) 447 return -EINVAL; 448 449 dev->mtu = new_mtu; 450 451 return 0; 452} 453 454/********************************************************************/ 455/* Tx path */ 456/********************************************************************/ 457 458static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) 459{ 460 struct orinoco_private *priv = netdev_priv(dev); 461 struct net_device_stats *stats = &priv->stats; 462 hermes_t *hw = &priv->hw; 463 int err = 0; 464 u16 txfid = priv->txfid; 465 char *p; 466 struct ethhdr *eh; 467 int len, data_len, data_off; 468 struct hermes_tx_descriptor desc; 469 unsigned long flags; 470 471 TRACE_ENTER(dev->name); 472 473 if (! netif_running(dev)) { 474 printk(KERN_ERR "%s: Tx on stopped device!\n", 475 dev->name); 476 TRACE_EXIT(dev->name); 477 return 1; 478 } 479 480 if (netif_queue_stopped(dev)) { 481 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 482 dev->name); 483 TRACE_EXIT(dev->name); 484 return 1; 485 } 486 487 if (orinoco_lock(priv, &flags) != 0) { 488 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n", 489 dev->name); 490 TRACE_EXIT(dev->name); 491 return 1; 492 } 493 494 if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) { 495 /* Oops, the firmware hasn't established a connection, 496 silently drop the packet (this seems to be the 497 safest approach). */ 498 stats->tx_errors++; 499 orinoco_unlock(priv, &flags); 500 dev_kfree_skb(skb); 501 TRACE_EXIT(dev->name); 502 return 0; 503 } 504 505 /* Length of the packet body */ 506 /* FIXME: what if the skb is smaller than this? */ 507 len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN); 508 509 eh = (struct ethhdr *)skb->data; 510 511 memset(&desc, 0, sizeof(desc)); 512 desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX); 513 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0); 514 if (err) { 515 if (net_ratelimit()) 516 printk(KERN_ERR "%s: Error %d writing Tx descriptor " 517 "to BAP\n", dev->name, err); 518 stats->tx_errors++; 519 goto fail; 520 } 521 522 /* Clear the 802.11 header and data length fields - some 523 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused 524 * if this isn't done. */ 525 hermes_clear_words(hw, HERMES_DATA0, 526 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); 527 528 /* Encapsulate Ethernet-II frames */ 529 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ 530 struct header_struct hdr; 531 data_len = len; 532 data_off = HERMES_802_3_OFFSET + sizeof(hdr); 533 p = skb->data + ETH_HLEN; 534 535 /* 802.3 header */ 536 memcpy(hdr.dest, eh->h_dest, ETH_ALEN); 537 memcpy(hdr.src, eh->h_source, ETH_ALEN); 538 hdr.len = htons(data_len + ENCAPS_OVERHEAD); 539 540 /* 802.2 header */ 541 memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr)); 542 543 hdr.ethertype = eh->h_proto; 544 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr), 545 txfid, HERMES_802_3_OFFSET); 546 if (err) { 547 if (net_ratelimit()) 548 printk(KERN_ERR "%s: Error %d writing packet " 549 "header to BAP\n", dev->name, err); 550 stats->tx_errors++; 551 goto fail; 552 } 553 } else { /* IEEE 802.3 frame */ 554 data_len = len + ETH_HLEN; 555 data_off = HERMES_802_3_OFFSET; 556 p = skb->data; 557 } 558 559 /* Round up for odd length packets */ 560 err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2), 561 txfid, data_off); 562 if (err) { 563 printk(KERN_ERR "%s: Error %d writing packet to BAP\n", 564 dev->name, err); 565 stats->tx_errors++; 566 goto fail; 567 } 568 569 /* Finally, we actually initiate the send */ 570 netif_stop_queue(dev); 571 572 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, 573 txfid, NULL); 574 if (err) { 575 netif_start_queue(dev); 576 printk(KERN_ERR "%s: Error %d transmitting packet\n", 577 dev->name, err); 578 stats->tx_errors++; 579 goto fail; 580 } 581 582 dev->trans_start = jiffies; 583 stats->tx_bytes += data_off + data_len; 584 585 orinoco_unlock(priv, &flags); 586 587 dev_kfree_skb(skb); 588 589 TRACE_EXIT(dev->name); 590 591 return 0; 592 fail: 593 TRACE_EXIT(dev->name); 594 595 orinoco_unlock(priv, &flags); 596 return err; 597} 598 599static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw) 600{ 601 struct orinoco_private *priv = netdev_priv(dev); 602 u16 fid = hermes_read_regn(hw, ALLOCFID); 603 604 if (fid != priv->txfid) { 605 if (fid != DUMMY_FID) 606 printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n", 607 dev->name, fid); 608 return; 609 } 610 611 hermes_write_regn(hw, ALLOCFID, DUMMY_FID); 612} 613 614static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw) 615{ 616 struct orinoco_private *priv = netdev_priv(dev); 617 struct net_device_stats *stats = &priv->stats; 618 619 stats->tx_packets++; 620 621 netif_wake_queue(dev); 622 623 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 624} 625 626static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) 627{ 628 struct orinoco_private *priv = netdev_priv(dev); 629 struct net_device_stats *stats = &priv->stats; 630 u16 fid = hermes_read_regn(hw, TXCOMPLFID); 631 struct hermes_tx_descriptor_802_11 hdr; 632 int err = 0; 633 634 if (fid == DUMMY_FID) 635 return; /* Nothing's really happened */ 636 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 646 if (err) { 647 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error " 648 "(FID=%04X error %d)\n", 649 dev->name, fid, err); 650 return; 651 } 652 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 } 678 679 netif_wake_queue(dev); 680} 681 682static void orinoco_tx_timeout(struct net_device *dev) 683{ 684 struct orinoco_private *priv = netdev_priv(dev); 685 struct net_device_stats *stats = &priv->stats; 686 struct hermes *hw = &priv->hw; 687 688 printk(KERN_WARNING "%s: Tx timeout! " 689 "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n", 690 dev->name, hermes_read_regn(hw, ALLOCFID), 691 hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT)); 692 693 stats->tx_errors++; 694 695 schedule_work(&priv->reset_work); 696} 697 698/********************************************************************/ 699/* Rx path (data frames) */ 700/********************************************************************/ 701 702/* Does the frame have a SNAP header indicating it should be 703 * de-encapsulated to Ethernet-II? */ 704static inline int is_ethersnap(void *_hdr) 705{ 706 u8 *hdr = _hdr; 707 708 /* We de-encapsulate all packets which, a) have SNAP headers 709 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header 710 * and where b) the OUI of the SNAP header is 00:00:00 or 711 * 00:00:f8 - we need both because different APs appear to use 712 * different OUIs for some reason */ 713 return (memcmp(hdr, &encaps_hdr, 5) == 0) 714 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) ); 715} 716 717static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, 718 int level, int noise) 719{ 720 struct orinoco_private *priv = netdev_priv(dev); 721 int i; 722 723 /* Gather wireless spy statistics: for each packet, compare the 724 * source address with out list, and if match, get the stats... */ 725 for (i = 0; i < priv->spy_number; i++) 726 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) { 727 priv->spy_stat[i].level = level - 0x95; 728 priv->spy_stat[i].noise = noise - 0x95; 729 priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0; 730 priv->spy_stat[i].updated = 7; 731 } 732} 733 734static void orinoco_stat_gather(struct net_device *dev, 735 struct sk_buff *skb, 736 struct hermes_rx_descriptor *desc) 737{ 738 struct orinoco_private *priv = netdev_priv(dev); 739 740 /* Using spy support with lots of Rx packets, like in an 741 * infrastructure (AP), will really slow down everything, because 742 * the MAC address must be compared to each entry of the spy list. 743 * If the user really asks for it (set some address in the 744 * spy list), we do it, but he will pay the price. 745 * Note that to get here, you need both WIRELESS_SPY 746 * compiled in AND some addresses in the list !!! 747 */ 748 /* Note : gcc will optimise the whole section away if 749 * WIRELESS_SPY is not defined... - Jean II */ 750 if (SPY_NUMBER(priv)) { 751 orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN, 752 desc->signal, desc->silence); 753 } 754} 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 867static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) 868{ 869 struct orinoco_private *priv = netdev_priv(dev); 870 struct net_device_stats *stats = &priv->stats; 871 struct iw_statistics *wstats = &priv->wstats; 872 struct sk_buff *skb = NULL; 873 u16 rxfid, status, fc; 874 int length; 875 struct hermes_rx_descriptor desc; 876 struct ethhdr *hdr; 877 int err; 878 879 rxfid = hermes_read_regn(hw, RXFID); 880 881 err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), 882 rxfid, 0); 883 if (err) { 884 printk(KERN_ERR "%s: error %d reading Rx descriptor. " 885 "Frame dropped.\n", dev->name, err); 886 goto update_stats; 887 } 888 889 status = le16_to_cpu(desc.status); 890 891 if (status & HERMES_RXSTAT_BADCRC) { 892 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", 893 dev->name); 894 stats->rx_crc_errors++; 895 goto update_stats; 896 } 897 898 /* Handle frames in monitor mode */ 899 if (priv->iw_mode == IW_MODE_MONITOR) { 900 orinoco_rx_monitor(dev, rxfid, &desc); 901 return; 902 } 903 904 if (status & HERMES_RXSTAT_UNDECRYPTABLE) { 905 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n", 906 dev->name); 907 wstats->discard.code++; 908 goto update_stats; 909 } 910 911 length = le16_to_cpu(desc.data_len); 912 fc = le16_to_cpu(desc.frame_ctl); 913 914 /* Sanity checks */ 915 if (length < 3) { /* No for even an 802.2 LLC header */ 916 /* At least on Symbol firmware with PCF we get quite a 917 lot of these legitimately - Poll frames with no 918 data. */ 919 return; 920 } 921 if (length > IEEE802_11_DATA_LEN) { 922 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", 923 dev->name, length); 924 stats->rx_length_errors++; 925 goto update_stats; 926 } 927 928 /* We need space for the packet data itself, plus an ethernet 929 header, plus 2 bytes so we can align the IP header on a 930 32bit boundary, plus 1 byte so we can read in odd length 931 packets from the card, which has an IO granularity of 16 932 bits */ 933 skb = dev_alloc_skb(length+ETH_HLEN+2+1); 934 if (!skb) { 935 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n", 936 dev->name); 937 goto update_stats; 938 } 939 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 } 953 954 /* Handle decapsulation 955 * In most cases, the firmware tell us about SNAP frames. 956 * For some reason, the SNAP frames sent by LinkSys APs 957 * are not properly recognised by most firmwares. 958 * So, check ourselves */ 959 if (length >= ENCAPS_OVERHEAD && 960 (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) || 961 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) || 962 is_ethersnap(skb->data))) { 963 /* These indicate a SNAP within 802.2 LLC within 964 802.11 frame which we'll need to de-encapsulate to 965 the original EthernetII frame. */ 966 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD); 967 } else { 968 /* 802.3 frame - prepend 802.3 header as is */ 969 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN); 970 hdr->h_proto = htons(length); 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); 977 978 dev->last_rx = jiffies; 979 skb->dev = dev; 980 skb->protocol = eth_type_trans(skb, dev); 981 skb->ip_summed = CHECKSUM_NONE; 982 if (fc & IEEE80211_FCTL_TODS) 983 skb->pkt_type = PACKET_OTHERHOST; 984 985 /* Process the wireless stats if needed */ 986 orinoco_stat_gather(dev, skb, &desc); 987 988 /* Pass the packet to the networking stack */ 989 netif_rx(skb); 990 stats->rx_packets++; 991 stats->rx_bytes += length; 992 993 return; 994 995 drop: 996 dev_kfree_skb_irq(skb); 997 update_stats: 998 stats->rx_errors++; 999 stats->rx_dropped++; 1000} 1001 1002/********************************************************************/ 1003/* Rx path (info frames) */ 1004/********************************************************************/ 1005 1006static void print_linkstatus(struct net_device *dev, u16 status) 1007{ 1008 char * s; 1009 1010 if (suppress_linkstatus) 1011 return; 1012 1013 switch (status) { 1014 case HERMES_LINKSTATUS_NOT_CONNECTED: 1015 s = "Not Connected"; 1016 break; 1017 case HERMES_LINKSTATUS_CONNECTED: 1018 s = "Connected"; 1019 break; 1020 case HERMES_LINKSTATUS_DISCONNECTED: 1021 s = "Disconnected"; 1022 break; 1023 case HERMES_LINKSTATUS_AP_CHANGE: 1024 s = "AP Changed"; 1025 break; 1026 case HERMES_LINKSTATUS_AP_OUT_OF_RANGE: 1027 s = "AP Out of Range"; 1028 break; 1029 case HERMES_LINKSTATUS_AP_IN_RANGE: 1030 s = "AP In Range"; 1031 break; 1032 case HERMES_LINKSTATUS_ASSOC_FAILED: 1033 s = "Association Failed"; 1034 break; 1035 default: 1036 s = "UNKNOWN"; 1037 } 1038 1039 printk(KERN_INFO "%s: New link status: %s (%04x)\n", 1040 dev->name, s, status); 1041} 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 1136static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) 1137{ 1138 struct orinoco_private *priv = netdev_priv(dev); 1139 u16 infofid; 1140 struct { 1141 u16 len; 1142 u16 type; 1143 } __attribute__ ((packed)) info; 1144 int len, type; 1145 int err; 1146 1147 /* This is an answer to an INQUIRE command that we did earlier, 1148 * or an information "event" generated by the card 1149 * The controller return to us a pseudo frame containing 1150 * the information in question - Jean II */ 1151 infofid = hermes_read_regn(hw, INFOFID); 1152 1153 /* Read the info frame header - don't try too hard */ 1154 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), 1155 infofid, 0); 1156 if (err) { 1157 printk(KERN_ERR "%s: error %d reading info frame. " 1158 "Frame dropped.\n", dev->name, err); 1159 return; 1160 } 1161 1162 len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len)); 1163 type = le16_to_cpu(info.type); 1164 1165 switch (type) { 1166 case HERMES_INQ_TALLIES: { 1167 struct hermes_tallies_frame tallies; 1168 struct iw_statistics *wstats = &priv->wstats; 1169 1170 if (len > sizeof(tallies)) { 1171 printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n", 1172 dev->name, len); 1173 len = sizeof(tallies); 1174 } 1175 1176 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, 1177 infofid, sizeof(info)); 1178 if (err) 1179 break; 1180 1181 /* Increment our various counters */ 1182 /* wstats->discard.nwid - no wrong BSSID stuff */ 1183 wstats->discard.code += 1184 le16_to_cpu(tallies.RxWEPUndecryptable); 1185 if (len == sizeof(tallies)) 1186 wstats->discard.code += 1187 le16_to_cpu(tallies.RxDiscards_WEPICVError) + 1188 le16_to_cpu(tallies.RxDiscards_WEPExcluded); 1189 wstats->discard.misc += 1190 le16_to_cpu(tallies.TxDiscardsWrongSA); 1191 wstats->discard.fragment += 1192 le16_to_cpu(tallies.RxMsgInBadMsgFragments); 1193 wstats->discard.retries += 1194 le16_to_cpu(tallies.TxRetryLimitExceeded); 1195 /* wstats->miss.beacon - no match */ 1196 } 1197 break; 1198 case HERMES_INQ_LINKSTATUS: { 1199 struct hermes_linkstatus linkstatus; 1200 u16 newstatus; 1201 int connected; 1202 1203 if (priv->iw_mode == IW_MODE_MONITOR) 1204 break; 1205 1206 if (len != sizeof(linkstatus)) { 1207 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n", 1208 dev->name, len); 1209 break; 1210 } 1211 1212 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, 1213 infofid, sizeof(info)); 1214 if (err) 1215 break; 1216 newstatus = le16_to_cpu(linkstatus.linkstatus); 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 1227 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) 1228 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE) 1229 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE); 1230 1231 if (connected) 1232 netif_carrier_on(dev); 1233 else if (!ignore_disconnect) 1234 netif_carrier_off(dev); 1235 1236 if (newstatus != priv->last_linkstatus) { 1237 priv->last_linkstatus = 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 } 1267 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); 1311 } 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 */ 1319 default: 1320 printk(KERN_DEBUG "%s: Unknown information frame received: " 1321 "type 0x%04x, length %d\n", dev->name, type, len); 1322 /* We don't actually do anything about it */ 1323 break; 1324 } 1325} 1326 1327static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) 1328{ 1329 if (net_ratelimit()) 1330 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name); 1331} 1332 1333/********************************************************************/ 1334/* Internal hardware control routines */ 1335/********************************************************************/ 1336 1337int __orinoco_up(struct net_device *dev) 1338{ 1339 struct orinoco_private *priv = netdev_priv(dev); 1340 struct hermes *hw = &priv->hw; 1341 int err; 1342 1343 netif_carrier_off(dev); /* just to make sure */ 1344 1345 err = __orinoco_program_rids(dev); 1346 if (err) { 1347 printk(KERN_ERR "%s: Error %d configuring card\n", 1348 dev->name, err); 1349 return err; 1350 } 1351 1352 /* Fire things up again */ 1353 hermes_set_irqmask(hw, ORINOCO_INTEN); 1354 err = hermes_enable_port(hw, 0); 1355 if (err) { 1356 printk(KERN_ERR "%s: Error %d enabling MAC port\n", 1357 dev->name, err); 1358 return err; 1359 } 1360 1361 netif_start_queue(dev); 1362 1363 return 0; 1364} 1365 1366int __orinoco_down(struct net_device *dev) 1367{ 1368 struct orinoco_private *priv = netdev_priv(dev); 1369 struct hermes *hw = &priv->hw; 1370 int err; 1371 1372 netif_stop_queue(dev); 1373 1374 if (! priv->hw_unavailable) { 1375 if (! priv->broken_disableport) { 1376 err = hermes_disable_port(hw, 0); 1377 if (err) { 1378 /* Some firmwares (e.g. Intersil 1.3.x) seem 1379 * to have problems disabling the port, oh 1380 * well, too bad. */ 1381 printk(KERN_WARNING "%s: Error %d disabling MAC port\n", 1382 dev->name, err); 1383 priv->broken_disableport = 1; 1384 } 1385 } 1386 hermes_set_irqmask(hw, 0); 1387 hermes_write_regn(hw, EVACK, 0xffff); 1388 } 1389 1390 /* firmware will have to reassociate */ 1391 netif_carrier_off(dev); 1392 priv->last_linkstatus = 0xffff; 1393 1394 return 0; 1395} 1396 1397int orinoco_reinit_firmware(struct net_device *dev) 1398{ 1399 struct orinoco_private *priv = netdev_priv(dev); 1400 struct hermes *hw = &priv->hw; 1401 int err; 1402 1403 err = hermes_init(hw); 1404 if (err) 1405 return err; 1406 1407 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 1408 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { 1409 /* Try workaround for old Symbol firmware bug */ 1410 printk(KERN_WARNING "%s: firmware ALLOC bug detected " 1411 "(old Symbol firmware?). Trying to work around... ", 1412 dev->name); 1413 1414 priv->nicbuf_size = TX_NICBUF_SIZE_BUG; 1415 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 1416 if (err) 1417 printk("failed!\n"); 1418 else 1419 printk("ok.\n"); 1420 } 1421 1422 return err; 1423} 1424 1425static int __orinoco_hw_set_bitrate(struct orinoco_private *priv) 1426{ 1427 hermes_t *hw = &priv->hw; 1428 int err = 0; 1429 1430 if (priv->bitratemode >= BITRATE_TABLE_SIZE) { 1431 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n", 1432 priv->ndev->name, priv->bitratemode); 1433 return -EINVAL; 1434 } 1435 1436 switch (priv->firmware_type) { 1437 case FIRMWARE_TYPE_AGERE: 1438 err = hermes_write_wordrec(hw, USER_BAP, 1439 HERMES_RID_CNFTXRATECONTROL, 1440 bitrate_table[priv->bitratemode].agere_txratectrl); 1441 break; 1442 case FIRMWARE_TYPE_INTERSIL: 1443 case FIRMWARE_TYPE_SYMBOL: 1444 err = hermes_write_wordrec(hw, USER_BAP, 1445 HERMES_RID_CNFTXRATECONTROL, 1446 bitrate_table[priv->bitratemode].intersil_txratectrl); 1447 break; 1448 default: 1449 BUG(); 1450 } 1451 1452 return err; 1453} 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 1485/* Change the WEP keys and/or the current keys. Can be called 1486 * either from __orinoco_hw_setup_wep() or directly from 1487 * orinoco_ioctl_setiwencode(). In the later case the association 1488 * with the AP is not broken (if the firmware can handle it), 1489 * which is needed for 802.1x implementations. */ 1490static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv) 1491{ 1492 hermes_t *hw = &priv->hw; 1493 int err = 0; 1494 1495 switch (priv->firmware_type) { 1496 case FIRMWARE_TYPE_AGERE: 1497 err = HERMES_WRITE_RECORD(hw, USER_BAP, 1498 HERMES_RID_CNFWEPKEYS_AGERE, 1499 &priv->keys); 1500 if (err) 1501 return err; 1502 err = hermes_write_wordrec(hw, USER_BAP, 1503 HERMES_RID_CNFTXKEY_AGERE, 1504 priv->tx_key); 1505 if (err) 1506 return err; 1507 break; 1508 case FIRMWARE_TYPE_INTERSIL: 1509 case FIRMWARE_TYPE_SYMBOL: 1510 { 1511 int keylen; 1512 int i; 1513 1514 /* Force uniform key length to work around firmware bugs */ 1515 keylen = le16_to_cpu(priv->keys[priv->tx_key].len); 1516 1517 if (keylen > LARGE_KEY_SIZE) { 1518 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n", 1519 priv->ndev->name, priv->tx_key, keylen); 1520 return -E2BIG; 1521 } 1522 1523 /* Write all 4 keys */ 1524 for(i = 0; i < ORINOCO_MAX_KEYS; i++) { 1525 err = hermes_write_ltv(hw, USER_BAP, 1526 HERMES_RID_CNFDEFAULTKEY0 + i, 1527 HERMES_BYTES_TO_RECLEN(keylen), 1528 priv->keys[i].data); 1529 if (err) 1530 return err; 1531 } 1532 1533 /* Write the index of the key used in transmission */ 1534 err = hermes_write_wordrec(hw, USER_BAP, 1535 HERMES_RID_CNFWEPDEFAULTKEYID, 1536 priv->tx_key); 1537 if (err) 1538 return err; 1539 } 1540 break; 1541 } 1542 1543 return 0; 1544} 1545 1546static int __orinoco_hw_setup_wep(struct orinoco_private *priv) 1547{ 1548 hermes_t *hw = &priv->hw; 1549 int err = 0; 1550 int master_wep_flag; 1551 int auth_flag; 1552 1553 if (priv->wep_on) 1554 __orinoco_hw_setup_wepkeys(priv); 1555 1556 if (priv->wep_restrict) 1557 auth_flag = HERMES_AUTH_SHARED_KEY; 1558 else 1559 auth_flag = HERMES_AUTH_OPEN; 1560 1561 switch (priv->firmware_type) { 1562 case FIRMWARE_TYPE_AGERE: /* Agere style WEP */ 1563 if (priv->wep_on) { 1564 /* Enable the shared-key authentication. */ 1565 err = hermes_write_wordrec(hw, USER_BAP, 1566 HERMES_RID_CNFAUTHENTICATION_AGERE, 1567 auth_flag); 1568 } 1569 err = hermes_write_wordrec(hw, USER_BAP, 1570 HERMES_RID_CNFWEPENABLED_AGERE, 1571 priv->wep_on); 1572 if (err) 1573 return err; 1574 break; 1575 1576 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */ 1577 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */ 1578 if (priv->wep_on) { 1579 if (priv->wep_restrict || 1580 (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)) 1581 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED | 1582 HERMES_WEP_EXCL_UNENCRYPTED; 1583 else 1584 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED; 1585 1586 err = hermes_write_wordrec(hw, USER_BAP, 1587 HERMES_RID_CNFAUTHENTICATION, 1588 auth_flag); 1589 if (err) 1590 return err; 1591 } else 1592 master_wep_flag = 0; 1593 1594 if (priv->iw_mode == IW_MODE_MONITOR) 1595 master_wep_flag |= HERMES_WEP_HOST_DECRYPT; 1596 1597 /* Master WEP setting : on/off */ 1598 err = hermes_write_wordrec(hw, USER_BAP, 1599 HERMES_RID_CNFWEPFLAGS_INTERSIL, 1600 master_wep_flag); 1601 if (err) 1602 return err; 1603 1604 break; 1605 } 1606 1607 return 0; 1608} 1609 1610static int __orinoco_program_rids(struct net_device *dev) 1611{ 1612 struct orinoco_private *priv = netdev_priv(dev); 1613 hermes_t *hw = &priv->hw; 1614 int err; 1615 struct hermes_idstring idbuf; 1616 1617 /* Set the MAC address */ 1618 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 1619 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); 1620 if (err) { 1621 printk(KERN_ERR "%s: Error %d setting MAC address\n", 1622 dev->name, err); 1623 return err; 1624 } 1625 1626 /* Set up the link mode */ 1627 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, 1628 priv->port_type); 1629 if (err) { 1630 printk(KERN_ERR "%s: Error %d setting port type\n", 1631 dev->name, err); 1632 return err; 1633 } 1634 /* Set the channel/frequency */ 1635 if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) { 1636 err = hermes_write_wordrec(hw, USER_BAP, 1637 HERMES_RID_CNFOWNCHANNEL, 1638 priv->channel); 1639 if (err) { 1640 printk(KERN_ERR "%s: Error %d setting channel %d\n", 1641 dev->name, err, priv->channel); 1642 return err; 1643 } 1644 } 1645 1646 if (priv->has_ibss) { 1647 u16 createibss; 1648 1649 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) { 1650 printk(KERN_WARNING "%s: This firmware requires an " 1651 "ESSID in IBSS-Ad-Hoc mode.\n", dev->name); 1652 /* With wvlan_cs, in this case, we would crash. 1653 * hopefully, this driver will behave better... 1654 * Jean II */ 1655 createibss = 0; 1656 } else { 1657 createibss = priv->createibss; 1658 } 1659 1660 err = hermes_write_wordrec(hw, USER_BAP, 1661 HERMES_RID_CNFCREATEIBSS, 1662 createibss); 1663 if (err) { 1664 printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", 1665 dev->name, err); 1666 return err; 1667 } 1668 } 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 } 1677 /* Set the desired ESSID */ 1678 idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); 1679 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); 1680 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ 1681 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, 1682 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 1683 &idbuf); 1684 if (err) { 1685 printk(KERN_ERR "%s: Error %d setting OWNSSID\n", 1686 dev->name, err); 1687 return err; 1688 } 1689 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, 1690 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 1691 &idbuf); 1692 if (err) { 1693 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n", 1694 dev->name, err); 1695 return err; 1696 } 1697 1698 /* Set the station name */ 1699 idbuf.len = cpu_to_le16(strlen(priv->nick)); 1700 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); 1701 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 1702 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), 1703 &idbuf); 1704 if (err) { 1705 printk(KERN_ERR "%s: Error %d setting nickname\n", 1706 dev->name, err); 1707 return err; 1708 } 1709 1710 /* Set AP density */ 1711 if (priv->has_sensitivity) { 1712 err = hermes_write_wordrec(hw, USER_BAP, 1713 HERMES_RID_CNFSYSTEMSCALE, 1714 priv->ap_density); 1715 if (err) { 1716 printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. " 1717 "Disabling sensitivity control\n", 1718 dev->name, err); 1719 1720 priv->has_sensitivity = 0; 1721 } 1722 } 1723 1724 /* Set RTS threshold */ 1725 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, 1726 priv->rts_thresh); 1727 if (err) { 1728 printk(KERN_ERR "%s: Error %d setting RTS threshold\n", 1729 dev->name, err); 1730 return err; 1731 } 1732 1733 /* Set fragmentation threshold or MWO robustness */ 1734 if (priv->has_mwo) 1735 err = hermes_write_wordrec(hw, USER_BAP, 1736 HERMES_RID_CNFMWOROBUST_AGERE, 1737 priv->mwo_robust); 1738 else 1739 err = hermes_write_wordrec(hw, USER_BAP, 1740 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, 1741 priv->frag_thresh); 1742 if (err) { 1743 printk(KERN_ERR "%s: Error %d setting fragmentation\n", 1744 dev->name, err); 1745 return err; 1746 } 1747 1748 /* Set bitrate */ 1749 err = __orinoco_hw_set_bitrate(priv); 1750 if (err) { 1751 printk(KERN_ERR "%s: Error %d setting bitrate\n", 1752 dev->name, err); 1753 return err; 1754 } 1755 1756 /* Set power management */ 1757 if (priv->has_pm) { 1758 err = hermes_write_wordrec(hw, USER_BAP, 1759 HERMES_RID_CNFPMENABLED, 1760 priv->pm_on); 1761 if (err) { 1762 printk(KERN_ERR "%s: Error %d setting up PM\n", 1763 dev->name, err); 1764 return err; 1765 } 1766 1767 err = hermes_write_wordrec(hw, USER_BAP, 1768 HERMES_RID_CNFMULTICASTRECEIVE, 1769 priv->pm_mcast); 1770 if (err) { 1771 printk(KERN_ERR "%s: Error %d setting up PM\n", 1772 dev->name, err); 1773 return err; 1774 } 1775 err = hermes_write_wordrec(hw, USER_BAP, 1776 HERMES_RID_CNFMAXSLEEPDURATION, 1777 priv->pm_period); 1778 if (err) { 1779 printk(KERN_ERR "%s: Error %d setting up PM\n", 1780 dev->name, err); 1781 return err; 1782 } 1783 err = hermes_write_wordrec(hw, USER_BAP, 1784 HERMES_RID_CNFPMHOLDOVERDURATION, 1785 priv->pm_timeout); 1786 if (err) { 1787 printk(KERN_ERR "%s: Error %d setting up PM\n", 1788 dev->name, err); 1789 return err; 1790 } 1791 } 1792 1793 /* Set preamble - only for Symbol so far... */ 1794 if (priv->has_preamble) { 1795 err = hermes_write_wordrec(hw, USER_BAP, 1796 HERMES_RID_CNFPREAMBLE_SYMBOL, 1797 priv->preamble); 1798 if (err) { 1799 printk(KERN_ERR "%s: Error %d setting preamble\n", 1800 dev->name, err); 1801 return err; 1802 } 1803 } 1804 1805 /* Set up encryption */ 1806 if (priv->has_wep) { 1807 err = __orinoco_hw_setup_wep(priv); 1808 if (err) { 1809 printk(KERN_ERR "%s: Error %d activating WEP\n", 1810 dev->name, err); 1811 return err; 1812 } 1813 } 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 1829 /* Set promiscuity / multicast*/ 1830 priv->promiscuous = 0; 1831 priv->mc_count = 0; 1832 __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ 1833 1834 return 0; 1835} 1836 1837/* FIXME: return int? */ 1838static void 1839__orinoco_set_multicast_list(struct net_device *dev) 1840{ 1841 struct orinoco_private *priv = netdev_priv(dev); 1842 hermes_t *hw = &priv->hw; 1843 int err = 0; 1844 int promisc, mc_count; 1845 1846 /* The Hermes doesn't seem to have an allmulti mode, so we go 1847 * into promiscuous mode and let the upper levels deal. */ 1848 if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) || 1849 (dev->mc_count > MAX_MULTICAST(priv)) ) { 1850 promisc = 1; 1851 mc_count = 0; 1852 } else { 1853 promisc = 0; 1854 mc_count = dev->mc_count; 1855 } 1856 1857 if (promisc != priv->promiscuous) { 1858 err = hermes_write_wordrec(hw, USER_BAP, 1859 HERMES_RID_CNFPROMISCUOUSMODE, 1860 promisc); 1861 if (err) { 1862 printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n", 1863 dev->name, err); 1864 } else 1865 priv->promiscuous = promisc; 1866 } 1867 1868 if (! promisc && (mc_count || priv->mc_count) ) { 1869 struct dev_mc_list *p = dev->mc_list; 1870 struct hermes_multicast mclist; 1871 int i; 1872 1873 for (i = 0; i < mc_count; i++) { 1874 /* paranoia: is list shorter than mc_count? */ 1875 BUG_ON(! p); 1876 /* paranoia: bad address size in list? */ 1877 BUG_ON(p->dmi_addrlen != ETH_ALEN); 1878 1879 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN); 1880 p = p->next; 1881 } 1882 1883 if (p) 1884 printk(KERN_WARNING "%s: Multicast list is " 1885 "longer than mc_count\n", dev->name); 1886 1887 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES, 1888 HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN), 1889 &mclist); 1890 if (err) 1891 printk(KERN_ERR "%s: Error %d setting multicast list.\n", 1892 dev->name, err); 1893 else 1894 priv->mc_count = mc_count; 1895 } 1896 1897 /* Since we can set the promiscuous flag when it wasn't asked 1898 for, make sure the net_device knows about it. */ 1899 if (priv->promiscuous) 1900 dev->flags |= IFF_PROMISC; 1901 else 1902 dev->flags &= ~IFF_PROMISC; 1903} 1904 1905/* This must be called from user context, without locks held - use 1906 * schedule_work() */ 1907static void orinoco_reset(struct net_device *dev) 1908{ 1909 struct orinoco_private *priv = netdev_priv(dev); 1910 struct hermes *hw = &priv->hw; 1911 int err; 1912 unsigned long flags; 1913 1914 if (orinoco_lock(priv, &flags) != 0) 1915 /* When the hardware becomes available again, whatever 1916 * detects that is responsible for re-initializing 1917 * it. So no need for anything further */ 1918 return; 1919 1920 netif_stop_queue(dev); 1921 1922 /* Shut off interrupts. Depending on what state the hardware 1923 * is in, this might not work, but we'll try anyway */ 1924 hermes_set_irqmask(hw, 0); 1925 hermes_write_regn(hw, EVACK, 0xffff); 1926 1927 priv->hw_unavailable++; 1928 priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */ 1929 netif_carrier_off(dev); 1930 1931 orinoco_unlock(priv, &flags); 1932 1933 /* Scanning support: Cleanup of driver struct */ 1934 kfree(priv->scan_result); 1935 priv->scan_result = NULL; 1936 priv->scan_inprogress = 0; 1937 1938 if (priv->hard_reset) { 1939 err = (*priv->hard_reset)(priv); 1940 if (err) { 1941 printk(KERN_ERR "%s: orinoco_reset: Error %d " 1942 "performing hard reset\n", dev->name, err); 1943 goto disable; 1944 } 1945 } 1946 1947 err = orinoco_reinit_firmware(dev); 1948 if (err) { 1949 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", 1950 dev->name, err); 1951 goto disable; 1952 } 1953 1954 spin_lock_irq(&priv->lock); /* This has to be called from user context */ 1955 1956 priv->hw_unavailable--; 1957 1958 /* priv->open or priv->hw_unavailable might have changed while 1959 * we dropped the lock */ 1960 if (priv->open && (! priv->hw_unavailable)) { 1961 err = __orinoco_up(dev); 1962 if (err) { 1963 printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n", 1964 dev->name, err); 1965 } else 1966 dev->trans_start = jiffies; 1967 } 1968 1969 spin_unlock_irq(&priv->lock); 1970 1971 return; 1972 disable: 1973 hermes_set_irqmask(hw, 0); 1974 netif_device_detach(dev); 1975 printk(KERN_ERR "%s: Device has been disabled!\n", dev->name); 1976} 1977 1978/********************************************************************/ 1979/* Interrupt handler */ 1980/********************************************************************/ 1981 1982static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw) 1983{ 1984 printk(KERN_DEBUG "%s: TICK\n", dev->name); 1985} 1986 1987static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw) 1988{ 1989 /* This seems to happen a fair bit under load, but ignoring it 1990 seems to work fine...*/ 1991 printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n", 1992 dev->name); 1993} 1994 1995irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs) 1996{ 1997 struct net_device *dev = (struct net_device *)dev_id; 1998 struct orinoco_private *priv = netdev_priv(dev); 1999 hermes_t *hw = &priv->hw; 2000 int count = MAX_IRQLOOPS_PER_IRQ; 2001 u16 evstat, events; 2002 /* These are used to detect a runaway interrupt situation */ 2003 /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy, 2004 * we panic and shut down the hardware */ 2005 static int last_irq_jiffy = 0; /* jiffies value the last time 2006 * we were called */ 2007 static int loops_this_jiffy = 0; 2008 unsigned long flags; 2009 2010 if (orinoco_lock(priv, &flags) != 0) { 2011 /* If hw is unavailable - we don't know if the irq was 2012 * for us or not */ 2013 return IRQ_HANDLED; 2014 } 2015 2016 evstat = hermes_read_regn(hw, EVSTAT); 2017 events = evstat & hw->inten; 2018 if (! events) { 2019 orinoco_unlock(priv, &flags); 2020 return IRQ_NONE; 2021 } 2022 2023 if (jiffies != last_irq_jiffy) 2024 loops_this_jiffy = 0; 2025 last_irq_jiffy = jiffies; 2026 2027 while (events && count--) { 2028 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) { 2029 printk(KERN_WARNING "%s: IRQ handler is looping too " 2030 "much! Resetting.\n", dev->name); 2031 /* Disable interrupts for now */ 2032 hermes_set_irqmask(hw, 0); 2033 schedule_work(&priv->reset_work); 2034 break; 2035 } 2036 2037 /* Check the card hasn't been removed */ 2038 if (! hermes_present(hw)) { 2039 DEBUG(0, "orinoco_interrupt(): card removed\n"); 2040 break; 2041 } 2042 2043 if (events & HERMES_EV_TICK) 2044 __orinoco_ev_tick(dev, hw); 2045 if (events & HERMES_EV_WTERR) 2046 __orinoco_ev_wterr(dev, hw); 2047 if (events & HERMES_EV_INFDROP) 2048 __orinoco_ev_infdrop(dev, hw); 2049 if (events & HERMES_EV_INFO) 2050 __orinoco_ev_info(dev, hw); 2051 if (events & HERMES_EV_RX) 2052 __orinoco_ev_rx(dev, hw); 2053 if (events & HERMES_EV_TXEXC) 2054 __orinoco_ev_txexc(dev, hw); 2055 if (events & HERMES_EV_TX) 2056 __orinoco_ev_tx(dev, hw); 2057 if (events & HERMES_EV_ALLOC) 2058 __orinoco_ev_alloc(dev, hw); 2059 2060 hermes_write_regn(hw, EVACK, evstat); 2061 2062 evstat = hermes_read_regn(hw, EVSTAT); 2063 events = evstat & hw->inten; 2064 }; 2065 2066 orinoco_unlock(priv, &flags); 2067 return IRQ_HANDLED; 2068} 2069 2070/********************************************************************/ 2071/* Initialization */ 2072/********************************************************************/ 2073 2074struct comp_id { 2075 u16 id, variant, major, minor; 2076} __attribute__ ((packed)); 2077 2078static inline fwtype_t determine_firmware_type(struct comp_id *nic_id) 2079{ 2080 if (nic_id->id < 0x8000) 2081 return FIRMWARE_TYPE_AGERE; 2082 else if (nic_id->id == 0x8000 && nic_id->major == 0) 2083 return FIRMWARE_TYPE_SYMBOL; 2084 else 2085 return FIRMWARE_TYPE_INTERSIL; 2086} 2087 2088/* Set priv->firmware type, determine firmware properties */ 2089static int determine_firmware(struct net_device *dev) 2090{ 2091 struct orinoco_private *priv = netdev_priv(dev); 2092 hermes_t *hw = &priv->hw; 2093 int err; 2094 struct comp_id nic_id, sta_id; 2095 unsigned int firmver; 2096 char tmp[SYMBOL_MAX_VER_LEN+1]; 2097 2098 /* Get the hardware version */ 2099 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id); 2100 if (err) { 2101 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n", 2102 dev->name, err); 2103 return err; 2104 } 2105 2106 le16_to_cpus(&nic_id.id); 2107 le16_to_cpus(&nic_id.variant); 2108 le16_to_cpus(&nic_id.major); 2109 le16_to_cpus(&nic_id.minor); 2110 printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n", 2111 dev->name, nic_id.id, nic_id.variant, 2112 nic_id.major, nic_id.minor); 2113 2114 priv->firmware_type = determine_firmware_type(&nic_id); 2115 2116 /* Get the firmware version */ 2117 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id); 2118 if (err) { 2119 printk(KERN_ERR "%s: Cannot read station identity: error %d\n", 2120 dev->name, err); 2121 return err; 2122 } 2123 2124 le16_to_cpus(&sta_id.id); 2125 le16_to_cpus(&sta_id.variant); 2126 le16_to_cpus(&sta_id.major); 2127 le16_to_cpus(&sta_id.minor); 2128 printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n", 2129 dev->name, sta_id.id, sta_id.variant, 2130 sta_id.major, sta_id.minor); 2131 2132 switch (sta_id.id) { 2133 case 0x15: 2134 printk(KERN_ERR "%s: Primary firmware is active\n", 2135 dev->name); 2136 return -ENODEV; 2137 case 0x14b: 2138 printk(KERN_ERR "%s: Tertiary firmware is active\n", 2139 dev->name); 2140 return -ENODEV; 2141 case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */ 2142 case 0x21: /* Symbol Spectrum24 Trilogy */ 2143 break; 2144 default: 2145 printk(KERN_NOTICE "%s: Unknown station ID, please report\n", 2146 dev->name); 2147 break; 2148 } 2149 2150 /* Default capabilities */ 2151 priv->has_sensitivity = 1; 2152 priv->has_mwo = 0; 2153 priv->has_preamble = 0; 2154 priv->has_port3 = 1; 2155 priv->has_ibss = 1; 2156 priv->has_wep = 0; 2157 priv->has_big_wep = 0; 2158 2159 /* Determine capabilities from the firmware version */ 2160 switch (priv->firmware_type) { 2161 case FIRMWARE_TYPE_AGERE: 2162 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout, 2163 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */ 2164 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 2165 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor); 2166 2167 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor; 2168 2169 priv->has_ibss = (firmver >= 0x60006); 2170 priv->has_wep = (firmver >= 0x40020); 2171 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell 2172 Gold cards from the others? */ 2173 priv->has_mwo = (firmver >= 0x60000); 2174 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */ 2175 priv->ibss_port = 1; 2176 priv->has_hostscan = (firmver >= 0x8000a); 2177 priv->broken_monitor = (firmver >= 0x80000); 2178 2179 /* Tested with Agere firmware : 2180 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II 2181 * Tested CableTron firmware : 4.32 => Anton */ 2182 break; 2183 case FIRMWARE_TYPE_SYMBOL: 2184 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */ 2185 /* Intel MAC : 00:02:B3:* */ 2186 /* 3Com MAC : 00:50:DA:* */ 2187 memset(tmp, 0, sizeof(tmp)); 2188 /* Get the Symbol firmware version */ 2189 err = hermes_read_ltv(hw, USER_BAP, 2190 HERMES_RID_SECONDARYVERSION_SYMBOL, 2191 SYMBOL_MAX_VER_LEN, NULL, &tmp); 2192 if (err) { 2193 printk(KERN_WARNING 2194 "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n", 2195 dev->name, err); 2196 firmver = 0; 2197 tmp[0] = '\0'; 2198 } else { 2199 /* The firmware revision is a string, the format is 2200 * something like : "V2.20-01". 2201 * Quick and dirty parsing... - Jean II 2202 */ 2203 firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12) 2204 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4) 2205 | (tmp[7] - '0'); 2206 2207 tmp[SYMBOL_MAX_VER_LEN] = '\0'; 2208 } 2209 2210 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 2211 "Symbol %s", tmp); 2212 2213 priv->has_ibss = (firmver >= 0x20000); 2214 priv->has_wep = (firmver >= 0x15012); 2215 priv->has_big_wep = (firmver >= 0x20000); 2216 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 2217 (firmver >= 0x29000 && firmver < 0x30000) || 2218 firmver >= 0x31000; 2219 priv->has_preamble = (firmver >= 0x20000); 2220 priv->ibss_port = 4; 2221 priv->broken_disableport = (firmver == 0x25013) || 2222 (firmver >= 0x30000 && firmver <= 0x31000); 2223 priv->has_hostscan = (firmver >= 0x31001) || 2224 (firmver >= 0x29057 && firmver < 0x30000); 2225 /* Tested with Intel firmware : 0x20015 => Jean II */ 2226 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ 2227 break; 2228 case FIRMWARE_TYPE_INTERSIL: 2229 /* D-Link, Linksys, Adtron, ZoomAir, and many others... 2230 * Samsung, Compaq 100/200 and Proxim are slightly 2231 * different and less well tested */ 2232 /* D-Link MAC : 00:40:05:* */ 2233 /* Addtron MAC : 00:90:D1:* */ 2234 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 2235 "Intersil %d.%d.%d", sta_id.major, sta_id.minor, 2236 sta_id.variant); 2237 2238 firmver = ((unsigned long)sta_id.major << 16) | 2239 ((unsigned long)sta_id.minor << 8) | sta_id.variant; 2240 2241 priv->has_ibss = (firmver >= 0x000700); /* FIXME */ 2242 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800); 2243 priv->has_pm = (firmver >= 0x000700); 2244 priv->has_hostscan = (firmver >= 0x010301); 2245 2246 if (firmver >= 0x000800) 2247 priv->ibss_port = 0; 2248 else { 2249 printk(KERN_NOTICE "%s: Intersil firmware earlier " 2250 "than v0.8.x - several features not supported\n", 2251 dev->name); 2252 priv->ibss_port = 1; 2253 } 2254 break; 2255 } 2256 printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name, 2257 priv->fw_name); 2258 2259 return 0; 2260} 2261 2262static int orinoco_init(struct net_device *dev) 2263{ 2264 struct orinoco_private *priv = netdev_priv(dev); 2265 hermes_t *hw = &priv->hw; 2266 int err = 0; 2267 struct hermes_idstring nickbuf; 2268 u16 reclen; 2269 int len; 2270 2271 TRACE_ENTER(dev->name); 2272 2273 /* No need to lock, the hw_unavailable flag is already set in 2274 * alloc_orinocodev() */ 2275 priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; 2276 2277 /* Initialize the firmware */ 2278 err = orinoco_reinit_firmware(dev); 2279 if (err != 0) { 2280 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", 2281 dev->name, err); 2282 goto out; 2283 } 2284 2285 err = determine_firmware(dev); 2286 if (err != 0) { 2287 printk(KERN_ERR "%s: Incompatible firmware, aborting\n", 2288 dev->name); 2289 goto out; 2290 } 2291 2292 if (priv->has_port3) 2293 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name); 2294 if (priv->has_ibss) 2295 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n", 2296 dev->name); 2297 if (priv->has_wep) { 2298 printk(KERN_DEBUG "%s: WEP supported, ", dev->name); 2299 if (priv->has_big_wep) 2300 printk("104-bit key\n"); 2301 else 2302 printk("40-bit key\n"); 2303 } 2304 2305 /* Get the MAC address */ 2306 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 2307 ETH_ALEN, NULL, dev->dev_addr); 2308 if (err) { 2309 printk(KERN_WARNING "%s: failed to read MAC address!\n", 2310 dev->name); 2311 goto out; 2312 } 2313 2314 printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", 2315 dev->name, dev->dev_addr[0], dev->dev_addr[1], 2316 dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], 2317 dev->dev_addr[5]); 2318 2319 /* Get the station name */ 2320 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 2321 sizeof(nickbuf), &reclen, &nickbuf); 2322 if (err) { 2323 printk(KERN_ERR "%s: failed to read station name\n", 2324 dev->name); 2325 goto out; 2326 } 2327 if (nickbuf.len) 2328 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len)); 2329 else 2330 len = min(IW_ESSID_MAX_SIZE, 2 * reclen); 2331 memcpy(priv->nick, &nickbuf.val, len); 2332 priv->nick[len] = '\0'; 2333 2334 printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick); 2335 2336 /* Get allowed channels */ 2337 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST, 2338 &priv->channel_mask); 2339 if (err) { 2340 printk(KERN_ERR "%s: failed to read channel list!\n", 2341 dev->name); 2342 goto out; 2343 } 2344 2345 /* Get initial AP density */ 2346 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, 2347 &priv->ap_density); 2348 if (err || priv->ap_density < 1 || priv->ap_density > 3) { 2349 priv->has_sensitivity = 0; 2350 } 2351 2352 /* Get initial RTS threshold */ 2353 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, 2354 &priv->rts_thresh); 2355 if (err) { 2356 printk(KERN_ERR "%s: failed to read RTS threshold!\n", 2357 dev->name); 2358 goto out; 2359 } 2360 2361 /* Get initial fragmentation settings */ 2362 if (priv->has_mwo) 2363 err = hermes_read_wordrec(hw, USER_BAP, 2364 HERMES_RID_CNFMWOROBUST_AGERE, 2365 &priv->mwo_robust); 2366 else 2367 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, 2368 &priv->frag_thresh); 2369 if (err) { 2370 printk(KERN_ERR "%s: failed to read fragmentation settings!\n", 2371 dev->name); 2372 goto out; 2373 } 2374 2375 /* Power management setup */ 2376 if (priv->has_pm) { 2377 priv->pm_on = 0; 2378 priv->pm_mcast = 1; 2379 err = hermes_read_wordrec(hw, USER_BAP, 2380 HERMES_RID_CNFMAXSLEEPDURATION, 2381 &priv->pm_period); 2382 if (err) { 2383 printk(KERN_ERR "%s: failed to read power management period!\n", 2384 dev->name); 2385 goto out; 2386 } 2387 err = hermes_read_wordrec(hw, USER_BAP, 2388 HERMES_RID_CNFPMHOLDOVERDURATION, 2389 &priv->pm_timeout); 2390 if (err) { 2391 printk(KERN_ERR "%s: failed to read power management timeout!\n", 2392 dev->name); 2393 goto out; 2394 } 2395 } 2396 2397 /* Preamble setup */ 2398 if (priv->has_preamble) { 2399 err = hermes_read_wordrec(hw, USER_BAP, 2400 HERMES_RID_CNFPREAMBLE_SYMBOL, 2401 &priv->preamble); 2402 if (err) 2403 goto out; 2404 } 2405 2406 /* Set up the default configuration */ 2407 priv->iw_mode = IW_MODE_INFRA; 2408 /* By default use IEEE/IBSS ad-hoc mode if we have it */ 2409 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); 2410 set_port_type(priv); 2411 priv->channel = 0; /* use firmware default */ 2412 2413 priv->promiscuous = 0; 2414 priv->wep_on = 0; 2415 priv->tx_key = 0; 2416 2417 /* Make the hardware available, as long as it hasn't been 2418 * removed elsewhere (e.g. by PCMCIA hot unplug) */ 2419 spin_lock_irq(&priv->lock); 2420 priv->hw_unavailable--; 2421 spin_unlock_irq(&priv->lock); 2422 2423 printk(KERN_DEBUG "%s: ready\n", dev->name); 2424 2425 out: 2426 TRACE_EXIT(dev->name); 2427 return err; 2428} 2429 2430struct net_device *alloc_orinocodev(int sizeof_card, 2431 int (*hard_reset)(struct orinoco_private *)) 2432{ 2433 struct net_device *dev; 2434 struct orinoco_private *priv; 2435 2436 dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card); 2437 if (! dev) 2438 return NULL; 2439 priv = netdev_priv(dev); 2440 priv->ndev = dev; 2441 if (sizeof_card) 2442 priv->card = (void *)((unsigned long)priv 2443 + sizeof(struct orinoco_private)); 2444 else 2445 priv->card = NULL; 2446 2447 /* Setup / override net_device fields */ 2448 dev->init = orinoco_init; 2449 dev->hard_start_xmit = orinoco_xmit; 2450 dev->tx_timeout = orinoco_tx_timeout; 2451 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2452 dev->get_stats = orinoco_get_stats; 2453 dev->ethtool_ops = &orinoco_ethtool_ops; 2454 dev->get_wireless_stats = orinoco_get_wireless_stats; 2455 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; 2456 dev->change_mtu = orinoco_change_mtu; 2457 dev->set_multicast_list = orinoco_set_multicast_list; 2458 /* we use the default eth_mac_addr for setting the MAC addr */ 2459 2460 /* Set up default callbacks */ 2461 dev->open = orinoco_open; 2462 dev->stop = orinoco_stop; 2463 priv->hard_reset = hard_reset; 2464 2465 spin_lock_init(&priv->lock); 2466 priv->open = 0; 2467 priv->hw_unavailable = 1; /* orinoco_init() must clear this 2468 * before anything else touches the 2469 * hardware */ 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); 2473 2474 netif_carrier_off(dev); 2475 priv->last_linkstatus = 0xffff; 2476 2477 return dev; 2478 2479} 2480 2481void free_orinocodev(struct net_device *dev) 2482{ 2483 struct orinoco_private *priv = netdev_priv(dev); 2484 2485 kfree(priv->scan_result); 2486 free_netdev(dev); 2487} 2488 2489/********************************************************************/ 2490/* Wireless extensions */ 2491/********************************************************************/ 2492 2493static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, 2494 char buf[IW_ESSID_MAX_SIZE+1]) 2495{ 2496 hermes_t *hw = &priv->hw; 2497 int err = 0; 2498 struct hermes_idstring essidbuf; 2499 char *p = (char *)(&essidbuf.val); 2500 int len; 2501 unsigned long flags; 2502 2503 if (orinoco_lock(priv, &flags) != 0) 2504 return -EBUSY; 2505 2506 if (strlen(priv->desired_essid) > 0) { 2507 /* We read the desired SSID from the hardware rather 2508 than from priv->desired_essid, just in case the 2509 firmware is allowed to change it on us. I'm not 2510 sure about this */ 2511 /* My guess is that the OWNSSID should always be whatever 2512 * we set to the card, whereas CURRENT_SSID is the one that 2513 * may change... - Jean II */ 2514 u16 rid; 2515 2516 *active = 1; 2517 2518 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : 2519 HERMES_RID_CNFDESIREDSSID; 2520 2521 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), 2522 NULL, &essidbuf); 2523 if (err) 2524 goto fail_unlock; 2525 } else { 2526 *active = 0; 2527 2528 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, 2529 sizeof(essidbuf), NULL, &essidbuf); 2530 if (err) 2531 goto fail_unlock; 2532 } 2533 2534 len = le16_to_cpu(essidbuf.len); 2535 BUG_ON(len > IW_ESSID_MAX_SIZE); 2536 2537 memset(buf, 0, IW_ESSID_MAX_SIZE+1); 2538 memcpy(buf, p, len); 2539 buf[len] = '\0'; 2540 2541 fail_unlock: 2542 orinoco_unlock(priv, &flags); 2543 2544 return err; 2545} 2546 2547static long orinoco_hw_get_freq(struct orinoco_private *priv) 2548{ 2549 2550 hermes_t *hw = &priv->hw; 2551 int err = 0; 2552 u16 channel; 2553 long freq = 0; 2554 unsigned long flags; 2555 2556 if (orinoco_lock(priv, &flags) != 0) 2557 return -EBUSY; 2558 2559 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel); 2560 if (err) 2561 goto out; 2562 2563 /* Intersil firmware 1.3.5 returns 0 when the interface is down */ 2564 if (channel == 0) { 2565 err = -EBUSY; 2566 goto out; 2567 } 2568 2569 if ( (channel < 1) || (channel > NUM_CHANNELS) ) { 2570 printk(KERN_WARNING "%s: Channel out of range (%d)!\n", 2571 priv->ndev->name, channel); 2572 err = -EBUSY; 2573 goto out; 2574 2575 } 2576 freq = channel_frequency[channel-1] * 100000; 2577 2578 out: 2579 orinoco_unlock(priv, &flags); 2580 2581 if (err > 0) 2582 err = -EBUSY; 2583 return err ? err : freq; 2584} 2585 2586static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, 2587 int *numrates, s32 *rates, int max) 2588{ 2589 hermes_t *hw = &priv->hw; 2590 struct hermes_idstring list; 2591 unsigned char *p = (unsigned char *)&list.val; 2592 int err = 0; 2593 int num; 2594 int i; 2595 unsigned long flags; 2596 2597 if (orinoco_lock(priv, &flags) != 0) 2598 return -EBUSY; 2599 2600 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, 2601 sizeof(list), NULL, &list); 2602 orinoco_unlock(priv, &flags); 2603 2604 if (err) 2605 return err; 2606 2607 num = le16_to_cpu(list.len); 2608 *numrates = num; 2609 num = min(num, max); 2610 2611 for (i = 0; i < num; i++) { 2612 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */ 2613 } 2614 2615 return 0; 2616} 2617 2618static int orinoco_ioctl_getname(struct net_device *dev, 2619 struct iw_request_info *info, 2620 char *name, 2621 char *extra) 2622{ 2623 struct orinoco_private *priv = netdev_priv(dev); 2624 int numrates; 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; 2645 static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 2646 static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2647 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} 2720 2721static int orinoco_ioctl_setmode(struct net_device *dev, 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; 2729 2730 if (priv->iw_mode == *mode) 2731 return 0; 2732 2733 if (orinoco_lock(priv, &flags) != 0) 2734 return -EBUSY; 2735 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 2764 orinoco_unlock(priv, &flags); 2765 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); 2792 2793 rrq->length = sizeof(struct iw_range); 2794 memset(range, 0, sizeof(struct iw_range)); 2795 2796 range->we_version_compiled = WIRELESS_EXT; 2797 range->we_version_source = 14; 2798 2799 /* Set available channels/frequencies */ 2800 range->num_channels = NUM_CHANNELS; 2801 k = 0; 2802 for (i = 0; i < NUM_CHANNELS; i++) { 2803 if (priv->channel_mask & (1 << i)) { 2804 range->freq[k].i = i + 1; 2805 range->freq[k].m = channel_frequency[i] * 100000; 2806 range->freq[k].e = 1; 2807 k++; 2808 } 2809 2810 if (k >= IW_MAX_FREQUENCIES) 2811 break; 2812 } 2813 range->num_frequency = k; 2814 range->sensitivity = 3; 2815 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; 2820 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)){ 2828 /* Quality stats meaningless in ad-hoc mode */ 2829 } else { 2830 range->max_qual.qual = 0x8b - 0x2f; 2831 range->max_qual.level = 0x2f - 0x95 - 1; 2832 range->max_qual.noise = 0x2f - 0x95 - 1; 2833 /* Need to get better values */ 2834 range->avg_qual.qual = 0x24; 2835 range->avg_qual.level = 0xC2; 2836 range->avg_qual.noise = 0x9E; 2837 } 2838 2839 err = orinoco_hw_get_bitratelist(priv, &numrates, 2840 range->bitrate, IW_MAX_BITRATES); 2841 if (err) 2842 return err; 2843 range->num_bitrates = numrates; 2844 2845 /* Set an indication of the max TCP throughput in bit/s that we can 2846 * expect using this interface. May be use for QoS stuff... 2847 * Jean II */ 2848 if (numrates > 2) 2849 range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */ 2850 else 2851 range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */ 2852 2853 range->min_rts = 0; 2854 range->max_rts = 2347; 2855 range->min_frag = 256; 2856 range->max_frag = 2346; 2857 2858 range->min_pmp = 0; 2859 range->max_pmp = 65535000; 2860 range->min_pmt = 0; 2861 range->max_pmt = 65535 * 1000; /* ??? */ 2862 range->pmp_flags = IW_POWER_PERIOD; 2863 range->pmt_flags = IW_POWER_TIMEOUT; 2864 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R; 2865 2866 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; 2867 range->retry_flags = IW_RETRY_LIMIT; 2868 range->r_time_flags = IW_RETRY_LIFETIME; 2869 range->min_retry = 0; 2870 range->max_retry = 65535; /* ??? */ 2871 range->min_r_time = 0; 2872 range->max_r_time = 65535 * 1000; /* ??? */ 2873 2874 TRACE_EXIT(dev->name); 2875 2876 return 0; 2877} 2878 2879static int orinoco_ioctl_setiwencode(struct net_device *dev, 2880 struct iw_request_info *info, 2881 struct iw_point *erq, 2882 char *keybuf) 2883{ 2884 struct orinoco_private *priv = netdev_priv(dev); 2885 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 2886 int setindex = priv->tx_key; 2887 int enable = priv->wep_on; 2888 int restricted = priv->wep_restrict; 2889 u16 xlen = 0; 2890 int err = -EINPROGRESS; /* Call commit handler */ 2891 unsigned long flags; 2892 2893 if (! priv->has_wep) 2894 return -EOPNOTSUPP; 2895 2896 if (erq->pointer) { 2897 /* We actually have a key to set - check its length */ 2898 if (erq->length > LARGE_KEY_SIZE) 2899 return -E2BIG; 2900 2901 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep ) 2902 return -E2BIG; 2903 } 2904 2905 if (orinoco_lock(priv, &flags) != 0) 2906 return -EBUSY; 2907 2908 if (erq->pointer) { 2909 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 2910 index = priv->tx_key; 2911 2912 /* Adjust key length to a supported value */ 2913 if (erq->length > SMALL_KEY_SIZE) { 2914 xlen = LARGE_KEY_SIZE; 2915 } else if (erq->length > 0) { 2916 xlen = SMALL_KEY_SIZE; 2917 } else 2918 xlen = 0; 2919 2920 /* Switch on WEP if off */ 2921 if ((!enable) && (xlen > 0)) { 2922 setindex = index; 2923 enable = 1; 2924 } 2925 } else { 2926 /* Important note : if the user do "iwconfig eth0 enc off", 2927 * we will arrive there with an index of -1. This is valid 2928 * but need to be taken care off... Jean II */ 2929 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) { 2930 if((index != -1) || (erq->flags == 0)) { 2931 err = -EINVAL; 2932 goto out; 2933 } 2934 } else { 2935 /* Set the index : Check that the key is valid */ 2936 if(priv->keys[index].len == 0) { 2937 err = -EINVAL; 2938 goto out; 2939 } 2940 setindex = index; 2941 } 2942 } 2943 2944 if (erq->flags & IW_ENCODE_DISABLED) 2945 enable = 0; 2946 if (erq->flags & IW_ENCODE_OPEN) 2947 restricted = 0; 2948 if (erq->flags & IW_ENCODE_RESTRICTED) 2949 restricted = 1; 2950 2951 if (erq->pointer) { 2952 priv->keys[index].len = cpu_to_le16(xlen); 2953 memset(priv->keys[index].data, 0, 2954 sizeof(priv->keys[index].data)); 2955 memcpy(priv->keys[index].data, keybuf, erq->length); 2956 } 2957 priv->tx_key = setindex; 2958 2959 /* Try fast key change if connected and only keys are changed */ 2960 if (priv->wep_on && enable && (priv->wep_restrict == restricted) && 2961 netif_carrier_ok(dev)) { 2962 err = __orinoco_hw_setup_wepkeys(priv); 2963 /* No need to commit if successful */ 2964 goto out; 2965 } 2966 2967 priv->wep_on = enable; 2968 priv->wep_restrict = restricted; 2969 2970 out: 2971 orinoco_unlock(priv, &flags); 2972 2973 return err; 2974} 2975 2976static int orinoco_ioctl_getiwencode(struct net_device *dev, 2977 struct iw_request_info *info, 2978 struct iw_point *erq, 2979 char *keybuf) 2980{ 2981 struct orinoco_private *priv = netdev_priv(dev); 2982 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 2983 u16 xlen = 0; 2984 unsigned long flags; 2985 2986 if (! priv->has_wep) 2987 return -EOPNOTSUPP; 2988 2989 if (orinoco_lock(priv, &flags) != 0) 2990 return -EBUSY; 2991 2992 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 2993 index = priv->tx_key; 2994 2995 erq->flags = 0; 2996 if (! priv->wep_on) 2997 erq->flags |= IW_ENCODE_DISABLED; 2998 erq->flags |= index + 1; 2999 3000 if (priv->wep_restrict) 3001 erq->flags |= IW_ENCODE_RESTRICTED; 3002 else 3003 erq->flags |= IW_ENCODE_OPEN; 3004 3005 xlen = le16_to_cpu(priv->keys[index].len); 3006 3007 erq->length = xlen; 3008 3009 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE); 3010 3011 orinoco_unlock(priv, &flags); 3012 return 0; 3013} 3014 3015static int orinoco_ioctl_setessid(struct net_device *dev, 3016 struct iw_request_info *info, 3017 struct iw_point *erq, 3018 char *essidbuf) 3019{ 3020 struct orinoco_private *priv = netdev_priv(dev); 3021 unsigned long flags; 3022 3023 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it 3024 * anyway... - Jean II */ 3025 3026 /* Hum... Should not use Wireless Extension constant (may change), 3027 * should use our own... - Jean II */ 3028 if (erq->length > IW_ESSID_MAX_SIZE) 3029 return -E2BIG; 3030 3031 if (orinoco_lock(priv, &flags) != 0) 3032 return -EBUSY; 3033 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 } 3041 3042 orinoco_unlock(priv, &flags); 3043 3044 return -EINPROGRESS; /* Call commit handler */ 3045} 3046 3047static int orinoco_ioctl_getessid(struct net_device *dev, 3048 struct iw_request_info *info, 3049 struct iw_point *erq, 3050 char *essidbuf) 3051{ 3052 struct orinoco_private *priv = netdev_priv(dev); 3053 int active; 3054 int err = 0; 3055 unsigned long flags; 3056 3057 TRACE_ENTER(dev->name); 3058 3059 if (netif_running(dev)) { 3060 err = orinoco_hw_get_essid(priv, &active, essidbuf); 3061 if (err) 3062 return err; 3063 } else { 3064 if (orinoco_lock(priv, &flags) != 0) 3065 return -EBUSY; 3066 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1); 3067 orinoco_unlock(priv, &flags); 3068 } 3069 3070 erq->flags = 1; 3071 erq->length = strlen(essidbuf) + 1; 3072 3073 TRACE_EXIT(dev->name); 3074 3075 return 0; 3076} 3077 3078static int orinoco_ioctl_setnick(struct net_device *dev, 3079 struct iw_request_info *info, 3080 struct iw_point *nrq, 3081 char *nickbuf) 3082{ 3083 struct orinoco_private *priv = netdev_priv(dev); 3084 unsigned long flags; 3085 3086 if (nrq->length > IW_ESSID_MAX_SIZE) 3087 return -E2BIG; 3088 3089 if (orinoco_lock(priv, &flags) != 0) 3090 return -EBUSY; 3091 3092 memset(priv->nick, 0, sizeof(priv->nick)); 3093 memcpy(priv->nick, nickbuf, nrq->length); 3094 3095 orinoco_unlock(priv, &flags); 3096 3097 return -EINPROGRESS; /* Call commit handler */ 3098} 3099 3100static int orinoco_ioctl_getnick(struct net_device *dev, 3101 struct iw_request_info *info, 3102 struct iw_point *nrq, 3103 char *nickbuf) 3104{ 3105 struct orinoco_private *priv = netdev_priv(dev); 3106 unsigned long flags; 3107 3108 if (orinoco_lock(priv, &flags) != 0) 3109 return -EBUSY; 3110 3111 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); 3112 orinoco_unlock(priv, &flags); 3113 3114 nrq->length = strlen(nickbuf)+1; 3115 3116 return 0; 3117} 3118 3119static int orinoco_ioctl_setfreq(struct net_device *dev, 3120 struct iw_request_info *info, 3121 struct iw_freq *frq, 3122 char *extra) 3123{ 3124 struct orinoco_private *priv = netdev_priv(dev); 3125 int chan = -1; 3126 unsigned long flags; 3127 int err = -EINPROGRESS; /* Call commit handler */ 3128 3129 /* In infrastructure mode the AP sets the channel */ 3130 if (priv->iw_mode == IW_MODE_INFRA) 3131 return -EBUSY; 3132 3133 if ( (frq->e == 0) && (frq->m <= 1000) ) { 3134 /* Setting by channel number */ 3135 chan = frq->m; 3136 } else { 3137 /* Setting by frequency - search the table */ 3138 int mult = 1; 3139 int i; 3140 3141 for (i = 0; i < (6 - frq->e); i++) 3142 mult *= 10; 3143 3144 for (i = 0; i < NUM_CHANNELS; i++) 3145 if (frq->m == (channel_frequency[i] * mult)) 3146 chan = i+1; 3147 } 3148 3149 if ( (chan < 1) || (chan > NUM_CHANNELS) || 3150 ! (priv->channel_mask & (1 << (chan-1)) ) ) 3151 return -EINVAL; 3152 3153 if (orinoco_lock(priv, &flags) != 0) 3154 return -EBUSY; 3155 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 } 3164 orinoco_unlock(priv, &flags); 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 3186 return 0; 3187} 3188 3189static int orinoco_ioctl_getsens(struct net_device *dev, 3190 struct iw_request_info *info, 3191 struct iw_param *srq, 3192 char *extra) 3193{ 3194 struct orinoco_private *priv = netdev_priv(dev); 3195 hermes_t *hw = &priv->hw; 3196 u16 val; 3197 int err; 3198 unsigned long flags; 3199 3200 if (!priv->has_sensitivity) 3201 return -EOPNOTSUPP; 3202 3203 if (orinoco_lock(priv, &flags) != 0) 3204 return -EBUSY; 3205 err = hermes_read_wordrec(hw, USER_BAP, 3206 HERMES_RID_CNFSYSTEMSCALE, &val); 3207 orinoco_unlock(priv, &flags); 3208 3209 if (err) 3210 return err; 3211 3212 srq->value = val; 3213 srq->fixed = 0; /* auto */ 3214 3215 return 0; 3216} 3217 3218static int orinoco_ioctl_setsens(struct net_device *dev, 3219 struct iw_request_info *info, 3220 struct iw_param *srq, 3221 char *extra) 3222{ 3223 struct orinoco_private *priv = netdev_priv(dev); 3224 int val = srq->value; 3225 unsigned long flags; 3226 3227 if (!priv->has_sensitivity) 3228 return -EOPNOTSUPP; 3229 3230 if ((val < 1) || (val > 3)) 3231 return -EINVAL; 3232 3233 if (orinoco_lock(priv, &flags) != 0) 3234 return -EBUSY; 3235 priv->ap_density = val; 3236 orinoco_unlock(priv, &flags); 3237 3238 return -EINPROGRESS; /* Call commit handler */ 3239} 3240 3241static int orinoco_ioctl_setrts(struct net_device *dev, 3242 struct iw_request_info *info, 3243 struct iw_param *rrq, 3244 char *extra) 3245{ 3246 struct orinoco_private *priv = netdev_priv(dev); 3247 int val = rrq->value; 3248 unsigned long flags; 3249 3250 if (rrq->disabled) 3251 val = 2347; 3252 3253 if ( (val < 0) || (val > 2347) ) 3254 return -EINVAL; 3255 3256 if (orinoco_lock(priv, &flags) != 0) 3257 return -EBUSY; 3258 3259 priv->rts_thresh = val; 3260 orinoco_unlock(priv, &flags); 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 3276 return 0; 3277} 3278 3279static int orinoco_ioctl_setfrag(struct net_device *dev, 3280 struct iw_request_info *info, 3281 struct iw_param *frq, 3282 char *extra) 3283{ 3284 struct orinoco_private *priv = netdev_priv(dev); 3285 int err = -EINPROGRESS; /* Call commit handler */ 3286 unsigned long flags; 3287 3288 if (orinoco_lock(priv, &flags) != 0) 3289 return -EBUSY; 3290 3291 if (priv->has_mwo) { 3292 if (frq->disabled) 3293 priv->mwo_robust = 0; 3294 else { 3295 if (frq->fixed) 3296 printk(KERN_WARNING "%s: Fixed fragmentation is " 3297 "not supported on this firmware. " 3298 "Using MWO robust instead.\n", dev->name); 3299 priv->mwo_robust = 1; 3300 } 3301 } else { 3302 if (frq->disabled) 3303 priv->frag_thresh = 2346; 3304 else { 3305 if ( (frq->value < 256) || (frq->value > 2346) ) 3306 err = -EINVAL; 3307 else 3308 priv->frag_thresh = frq->value & ~0x1; /* must be even */ 3309 } 3310 } 3311 3312 orinoco_unlock(priv, &flags); 3313 3314 return err; 3315} 3316 3317static int orinoco_ioctl_getfrag(struct net_device *dev, 3318 struct iw_request_info *info, 3319 struct iw_param *frq, 3320 char *extra) 3321{ 3322 struct orinoco_private *priv = netdev_priv(dev); 3323 hermes_t *hw = &priv->hw; 3324 int err; 3325 u16 val; 3326 unsigned long flags; 3327 3328 if (orinoco_lock(priv, &flags) != 0) 3329 return -EBUSY; 3330 3331 if (priv->has_mwo) { 3332 err = hermes_read_wordrec(hw, USER_BAP, 3333 HERMES_RID_CNFMWOROBUST_AGERE, 3334 &val); 3335 if (err) 3336 val = 0; 3337 3338 frq->value = val ? 2347 : 0; 3339 frq->disabled = ! val; 3340 frq->fixed = 0; 3341 } else { 3342 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, 3343 &val); 3344 if (err) 3345 val = 0; 3346 3347 frq->value = val; 3348 frq->disabled = (val >= 2346); 3349 frq->fixed = 1; 3350 } 3351 3352 orinoco_unlock(priv, &flags); 3353 3354 return err; 3355} 3356 3357static int orinoco_ioctl_setrate(struct net_device *dev, 3358 struct iw_request_info *info, 3359 struct iw_param *rrq, 3360 char *extra) 3361{ 3362 struct orinoco_private *priv = netdev_priv(dev); 3363 int ratemode = -1; 3364 int bitrate; /* 100s of kilobits */ 3365 int i; 3366 unsigned long flags; 3367 3368 /* As the user space doesn't know our highest rate, it uses -1 3369 * to ask us to set the highest rate. Test it using "iwconfig 3370 * ethX rate auto" - Jean II */ 3371 if (rrq->value == -1) 3372 bitrate = 110; 3373 else { 3374 if (rrq->value % 100000) 3375 return -EINVAL; 3376 bitrate = rrq->value / 100000; 3377 } 3378 3379 if ( (bitrate != 10) && (bitrate != 20) && 3380 (bitrate != 55) && (bitrate != 110) ) 3381 return -EINVAL; 3382 3383 for (i = 0; i < BITRATE_TABLE_SIZE; i++) 3384 if ( (bitrate_table[i].bitrate == bitrate) && 3385 (bitrate_table[i].automatic == ! rrq->fixed) ) { 3386 ratemode = i; 3387 break; 3388 } 3389 3390 if (ratemode == -1) 3391 return -EINVAL; 3392 3393 if (orinoco_lock(priv, &flags) != 0) 3394 return -EBUSY; 3395 priv->bitratemode = ratemode; 3396 orinoco_unlock(priv, &flags); 3397 3398 return -EINPROGRESS; 3399} 3400 3401static int orinoco_ioctl_getrate(struct net_device *dev, 3402 struct iw_request_info *info, 3403 struct iw_param *rrq, 3404 char *extra) 3405{ 3406 struct orinoco_private *priv = netdev_priv(dev); 3407 hermes_t *hw = &priv->hw; 3408 int err = 0; 3409 int ratemode; 3410 int i; 3411 u16 val; 3412 unsigned long flags; 3413 3414 if (orinoco_lock(priv, &flags) != 0) 3415 return -EBUSY; 3416 3417 ratemode = priv->bitratemode; 3418 3419 BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE)); 3420 3421 rrq->value = bitrate_table[ratemode].bitrate * 100000; 3422 rrq->fixed = ! bitrate_table[ratemode].automatic; 3423 rrq->disabled = 0; 3424 3425 /* If the interface is running we try to find more about the 3426 current mode */ 3427 if (netif_running(dev)) { 3428 err = hermes_read_wordrec(hw, USER_BAP, 3429 HERMES_RID_CURRENTTXRATE, &val); 3430 if (err) 3431 goto out; 3432 3433 switch (priv->firmware_type) { 3434 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */ 3435 /* Note : in Lucent firmware, the return value of 3436 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s, 3437 * and therefore is totally different from the 3438 * encoding of HERMES_RID_CNFTXRATECONTROL. 3439 * Don't forget that 6Mb/s is really 5.5Mb/s */ 3440 if (val == 6) 3441 rrq->value = 5500000; 3442 else 3443 rrq->value = val * 1000000; 3444 break; 3445 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */ 3446 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */ 3447 for (i = 0; i < BITRATE_TABLE_SIZE; i++) 3448 if (bitrate_table[i].intersil_txratectrl == val) { 3449 ratemode = i; 3450 break; 3451 } 3452 if (i >= BITRATE_TABLE_SIZE) 3453 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n", 3454 dev->name, val); 3455 3456 rrq->value = bitrate_table[ratemode].bitrate * 100000; 3457 break; 3458 default: 3459 BUG(); 3460 } 3461 } 3462 3463 out: 3464 orinoco_unlock(priv, &flags); 3465 3466 return err; 3467} 3468 3469static int orinoco_ioctl_setpower(struct net_device *dev, 3470 struct iw_request_info *info, 3471 struct iw_param *prq, 3472 char *extra) 3473{ 3474 struct orinoco_private *priv = netdev_priv(dev); 3475 int err = -EINPROGRESS; /* Call commit handler */ 3476 unsigned long flags; 3477 3478 if (orinoco_lock(priv, &flags) != 0) 3479 return -EBUSY; 3480 3481 if (prq->disabled) { 3482 priv->pm_on = 0; 3483 } else { 3484 switch (prq->flags & IW_POWER_MODE) { 3485 case IW_POWER_UNICAST_R: 3486 priv->pm_mcast = 0; 3487 priv->pm_on = 1; 3488 break; 3489 case IW_POWER_ALL_R: 3490 priv->pm_mcast = 1; 3491 priv->pm_on = 1; 3492 break; 3493 case IW_POWER_ON: 3494 /* No flags : but we may have a value - Jean II */ 3495 break; 3496 default: 3497 err = -EINVAL; 3498 } 3499 if (err) 3500 goto out; 3501 3502 if (prq->flags & IW_POWER_TIMEOUT) { 3503 priv->pm_on = 1; 3504 priv->pm_timeout = prq->value / 1000; 3505 } 3506 if (prq->flags & IW_POWER_PERIOD) { 3507 priv->pm_on = 1; 3508 priv->pm_period = prq->value / 1000; 3509 } 3510 /* It's valid to not have a value if we are just toggling 3511 * the flags... Jean II */ 3512 if(!priv->pm_on) { 3513 err = -EINVAL; 3514 goto out; 3515 } 3516 } 3517 3518 out: 3519 orinoco_unlock(priv, &flags); 3520 3521 return err; 3522} 3523 3524static int orinoco_ioctl_getpower(struct net_device *dev, 3525 struct iw_request_info *info, 3526 struct iw_param *prq, 3527 char *extra) 3528{ 3529 struct orinoco_private *priv = netdev_priv(dev); 3530 hermes_t *hw = &priv->hw; 3531 int err = 0; 3532 u16 enable, period, timeout, mcast; 3533 unsigned long flags; 3534 3535 if (orinoco_lock(priv, &flags) != 0) 3536 return -EBUSY; 3537 3538 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable); 3539 if (err) 3540 goto out; 3541 3542 err = hermes_read_wordrec(hw, USER_BAP, 3543 HERMES_RID_CNFMAXSLEEPDURATION, &period); 3544 if (err) 3545 goto out; 3546 3547 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout); 3548 if (err) 3549 goto out; 3550 3551 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast); 3552 if (err) 3553 goto out; 3554 3555 prq->disabled = !enable; 3556 /* Note : by default, display the period */ 3557 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 3558 prq->flags = IW_POWER_TIMEOUT; 3559 prq->value = timeout * 1000; 3560 } else { 3561 prq->flags = IW_POWER_PERIOD; 3562 prq->value = period * 1000; 3563 } 3564 if (mcast) 3565 prq->flags |= IW_POWER_ALL_R; 3566 else 3567 prq->flags |= IW_POWER_UNICAST_R; 3568 3569 out: 3570 orinoco_unlock(priv, &flags); 3571 3572 return err; 3573} 3574 3575static int orinoco_ioctl_getretry(struct net_device *dev, 3576 struct iw_request_info *info, 3577 struct iw_param *rrq, 3578 char *extra) 3579{ 3580 struct orinoco_private *priv = netdev_priv(dev); 3581 hermes_t *hw = &priv->hw; 3582 int err = 0; 3583 u16 short_limit, long_limit, lifetime; 3584 unsigned long flags; 3585 3586 if (orinoco_lock(priv, &flags) != 0) 3587 return -EBUSY; 3588 3589 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT, 3590 &short_limit); 3591 if (err) 3592 goto out; 3593 3594 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT, 3595 &long_limit); 3596 if (err) 3597 goto out; 3598 3599 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME, 3600 &lifetime); 3601 if (err) 3602 goto out; 3603 3604 rrq->disabled = 0; /* Can't be disabled */ 3605 3606 /* Note : by default, display the retry number */ 3607 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { 3608 rrq->flags = IW_RETRY_LIFETIME; 3609 rrq->value = lifetime * 1000; /* ??? */ 3610 } else { 3611 /* By default, display the min number */ 3612 if ((rrq->flags & IW_RETRY_MAX)) { 3613 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 3614 rrq->value = long_limit; 3615 } else { 3616 rrq->flags = IW_RETRY_LIMIT; 3617 rrq->value = short_limit; 3618 if(short_limit != long_limit) 3619 rrq->flags |= IW_RETRY_MIN; 3620 } 3621 } 3622 3623 out: 3624 orinoco_unlock(priv, &flags); 3625 3626 return err; 3627} 3628 3629static int orinoco_ioctl_reset(struct net_device *dev, 3630 struct iw_request_info *info, 3631 void *wrqu, 3632 char *extra) 3633{ 3634 struct orinoco_private *priv = netdev_priv(dev); 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 ); 3661 unsigned long flags; 3662 3663 if (orinoco_lock(priv, &flags) != 0) 3664 return -EBUSY; 3665 3666 priv->ibss_port = val ; 3667 3668 /* Actually update the mode we are using */ 3669 set_port_type(priv); 3670 3671 orinoco_unlock(priv, &flags); 3672 return -EINPROGRESS; /* Call commit handler */ 3673} 3674 3675static int orinoco_ioctl_getibssport(struct net_device *dev, 3676 struct iw_request_info *info, 3677 void *wrqu, 3678 char *extra) 3679{ 3680 struct orinoco_private *priv = netdev_priv(dev); 3681 int *val = (int *) extra; 3682 3683 *val = priv->ibss_port; 3684 return 0; 3685} 3686 3687static int orinoco_ioctl_setport3(struct net_device *dev, 3688 struct iw_request_info *info, 3689 void *wrqu, 3690 char *extra) 3691{ 3692 struct orinoco_private *priv = netdev_priv(dev); 3693 int val = *( (int *) extra ); 3694 int err = 0; 3695 unsigned long flags; 3696 3697 if (orinoco_lock(priv, &flags) != 0) 3698 return -EBUSY; 3699 3700 switch (val) { 3701 case 0: /* Try to do IEEE ad-hoc mode */ 3702 if (! priv->has_ibss) { 3703 err = -EINVAL; 3704 break; 3705 } 3706 priv->prefer_port3 = 0; 3707 3708 break; 3709 3710 case 1: /* Try to do Lucent proprietary ad-hoc mode */ 3711 if (! priv->has_port3) { 3712 err = -EINVAL; 3713 break; 3714 } 3715 priv->prefer_port3 = 1; 3716 break; 3717 3718 default: 3719 err = -EINVAL; 3720 } 3721 3722 if (! err) { 3723 /* Actually update the mode we are using */ 3724 set_port_type(priv); 3725 err = -EINPROGRESS; 3726 } 3727 3728 orinoco_unlock(priv, &flags); 3729 3730 return err; 3731} 3732 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) 3749{ 3750 struct orinoco_private *priv = netdev_priv(dev); 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 ); 3763 3764 if (orinoco_lock(priv, &flags) != 0) 3765 return -EBUSY; 3766 3767 if (val) 3768 priv->preamble = 1; 3769 else 3770 priv->preamble = 0; 3771 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; 3789 return 0; 3790} 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 3833/* Spy is used for link quality/strength measurements in Ad-Hoc mode 3834 * Jean II */ 3835static int orinoco_ioctl_setspy(struct net_device *dev, 3836 struct iw_request_info *info, 3837 struct iw_point *srq, 3838 char *extra) 3839 3840{ 3841 struct orinoco_private *priv = netdev_priv(dev); 3842 struct sockaddr *address = (struct sockaddr *) extra; 3843 int number = srq->length; 3844 int i; 3845 unsigned long flags; 3846 3847 /* Make sure nobody mess with the structure while we do */ 3848 if (orinoco_lock(priv, &flags) != 0) 3849 return -EBUSY; 3850 3851 /* orinoco_lock() doesn't disable interrupts, so make sure the 3852 * interrupt rx path don't get confused while we copy */ 3853 priv->spy_number = 0; 3854 3855 if (number > 0) { 3856 /* Extract the addresses */ 3857 for (i = 0; i < number; i++) 3858 memcpy(priv->spy_address[i], address[i].sa_data, 3859 ETH_ALEN); 3860 /* Reset stats */ 3861 memset(priv->spy_stat, 0, 3862 sizeof(struct iw_quality) * IW_MAX_SPY); 3863 /* Set number of addresses */ 3864 priv->spy_number = number; 3865 } 3866 3867 /* Now, let the others play */ 3868 orinoco_unlock(priv, &flags); 3869 3870 /* Do NOT call commit handler */ 3871 return 0; 3872} 3873 3874static int orinoco_ioctl_getspy(struct net_device *dev, 3875 struct iw_request_info *info, 3876 struct iw_point *srq, 3877 char *extra) 3878{ 3879 struct orinoco_private *priv = netdev_priv(dev); 3880 struct sockaddr *address = (struct sockaddr *) extra; 3881 int number; 3882 int i; 3883 unsigned long flags; 3884 3885 if (orinoco_lock(priv, &flags) != 0) 3886 return -EBUSY; 3887 3888 number = priv->spy_number; 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) { 3895 /* Create address struct */ 3896 for (i = 0; i < number; i++) { 3897 memcpy(address[i].sa_data, priv->spy_address[i], 3898 ETH_ALEN); 3899 address[i].sa_family = AF_UNIX; 3900 } 3901 /* Copy stats */ 3902 /* In theory, we should disable irqs while copying the stats 3903 * because the rx path might update it in the middle... 3904 * Bah, who care ? - Jean II */ 3905 memcpy(extra + (sizeof(struct sockaddr) * number), 3906 priv->spy_stat, sizeof(struct iw_quality) * number); 3907 } 3908 /* Reset updated flags. */ 3909 for (i = 0; i < number; i++) 3910 priv->spy_stat[i].updated = 0; 3911 3912 orinoco_unlock(priv, &flags); 3913 3914 srq->length = number; 3915 3916 return 0; 3917} 3918 3919/* Trigger a scan (look for other cells in the vicinity */ 3920static int orinoco_ioctl_setscan(struct net_device *dev, 3921 struct iw_request_info *info, 3922 struct iw_param *srq, 3923 char *extra) 3924{ 3925 struct orinoco_private *priv = netdev_priv(dev); 3926 hermes_t *hw = &priv->hw; 3927 int err = 0; 3928 unsigned long flags; 3929 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 */ 3936 3937 if (orinoco_lock(priv, &flags) != 0) 3938 return -EBUSY; 3939 3940 /* Scanning with port 0 disabled would fail */ 3941 if (!netif_running(dev)) { 3942 err = -ENETDOWN; 3943 goto out; 3944 } 3945 3946 /* In monitor mode, the scan results are always empty. 3947 * Probe responses are passed to the driver as received 3948 * frames and could be processed in software. */ 3949 if (priv->iw_mode == IW_MODE_MONITOR) { 3950 err = -EOPNOTSUPP; 3951 goto out; 3952 } 3953 3954 /* Note : because we don't lock out the irq handler, the way 3955 * we access scan variables in priv is critical. 3956 * o scan_inprogress : not touched by irq handler 3957 * o scan_mode : not touched by irq handler 3958 * o scan_result : irq is strict producer, non-irq is strict 3959 * consumer. 3960 * o scan_len : synchronised with scan_result 3961 * Before modifying anything on those variables, please think hard ! 3962 * Jean II */ 3963 3964 /* If there is still some left-over scan results, get rid of it */ 3965 if (priv->scan_result != NULL) { 3966 /* What's likely is that a client did crash or was killed 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 } 3974 3975 /* Save flags */ 3976 priv->scan_mode = srq->flags; 3977 3978 /* Always trigger scanning, even if it's in progress. 3979 * This way, if the info frame get lost, we will recover somewhat 3980 * gracefully - Jean II */ 3981 3982 if (priv->has_hostscan) { 3983 switch (priv->firmware_type) { 3984 case FIRMWARE_TYPE_SYMBOL: 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 } 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; 4006 4007 err = hermes_inquire(hw, HERMES_INQ_SCAN); 4008 break; 4009 } 4010 } else 4011 err = hermes_inquire(hw, HERMES_INQ_SCAN); 4012 4013 /* One more client */ 4014 if (! err) 4015 priv->scan_inprogress = 1; 4016 4017 out: 4018 orinoco_unlock(priv, &flags); 4019 return err; 4020} 4021 4022/* Translate scan data returned from the card to a card independant 4023 * format that the Wireless Tools will understand - Jean II */ 4024static inline int orinoco_translate_scan(struct net_device *dev, 4025 char *buffer, 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; 4038 4039 switch (priv->firmware_type) { 4040 case FIRMWARE_TYPE_AGERE: 4041 atom_len = sizeof(struct agere_scan_apinfo); 4042 offset = 0; 4043 break; 4044 case FIRMWARE_TYPE_SYMBOL: 4045 /* Lack of documentation necessitates this hack. 4046 * Different firmwares have 68 or 76 byte long atoms. 4047 * We try modulo first. If the length divides by both, 4048 * we check what would be the channel in the second 4049 * frame for a 68-byte atom. 76-byte atoms have 0 there. 4050 * Valid channel cannot be 0. */ 4051 if (scan_len % 76) 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; 4060 break; 4061 case FIRMWARE_TYPE_INTERSIL: 4062 offset = 4; 4063 if (priv->has_hostscan) 4064 atom_len = scan[0] + (scan[1] << 8); 4065 else 4066 atom_len = offsetof(struct prism2_scan_apinfo, atim); 4067 break; 4068 default: 4069 return 0; 4070 } 4071 4072 /* Check that we got an whole number of atoms */ 4073 if ((scan_len - offset) % atom_len) { 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 } 4079 4080 /* Read the entries one by one */ 4081 for (; offset + atom_len <= scan_len; offset += atom_len) { 4082 /* Get next atom */ 4083 atom = (union hermes_scan_info *) (scan + offset); 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 } 4111 4112 channel = atom->s.channel; 4113 if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) { 4114 /* Add frequency */ 4115 iwe.cmd = SIOCGIWFREQ; 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 } 4121 4122 /* Add quality statistics */ 4123 iwe.cmd = IWEVQUAL; 4124 iwe.u.qual.updated = 0x10; /* no link quality */ 4125 iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95; 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); 4134 4135 /* Add encryption capability */ 4136 iwe.cmd = SIOCGIWENCODE; 4137 if (capabilities & 0x10) 4138 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 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 } 4173 4174 /* The other data in the scan result are not really 4175 * interesting, so for now drop it - Jean II */ 4176 } 4177 return current_ev - buffer; 4178} 4179 4180/* Return results of a scan */ 4181static int orinoco_ioctl_getscan(struct net_device *dev, 4182 struct iw_request_info *info, 4183 struct iw_point *srq, 4184 char *extra) 4185{ 4186 struct orinoco_private *priv = netdev_priv(dev); 4187 int err = 0; 4188 unsigned long flags; 4189 4190 if (orinoco_lock(priv, &flags) != 0) 4191 return -EBUSY; 4192 4193 /* If no results yet, ask to try again later */ 4194 if (priv->scan_result == NULL) { 4195 if (priv->scan_inprogress) 4196 /* Important note : we don't want to block the caller 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} 4244 4245/* Commit handler, called after set operations */ 4246static int orinoco_ioctl_commit(struct net_device *dev, 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; 4255 4256 if (!priv->open) 4257 return 0; 4258 4259 if (priv->broken_disableport) { 4260 orinoco_reset(dev); 4261 return 0; 4262 } 4263 4264 if (orinoco_lock(priv, &flags) != 0) 4265 return err; 4266 4267 err = hermes_disable_port(hw, 0); 4268 if (err) { 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 } 4274 4275 err = __orinoco_program_rids(dev); 4276 if (err) { 4277 printk(KERN_WARNING "%s: Unable to reconfigure card\n", 4278 dev->name); 4279 goto out; 4280 } 4281 4282 err = hermes_enable_port(hw, 0); 4283 if (err) { 4284 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n", 4285 dev->name); 4286 goto out; 4287 } 4288 4289 out: 4290 if (err) { 4291 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name); 4292 schedule_work(&priv->reset_work); 4293 err = 0; 4294 } 4295 4296 orinoco_unlock(priv, &flags); 4297 return err; 4298} 4299 4300static const struct iw_priv_args orinoco_privtab[] = { 4301 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" }, 4302 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" }, 4303 { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 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}; 4318 4319 4320/* 4321 * Structures to export the Wireless Handlers 4322 */ 4323 4324static const iw_handler orinoco_handler[] = { 4325 [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit, 4326 [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname, 4327 [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq, 4328 [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq, 4329 [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode, 4330 [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode, 4331 [SIOCSIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens, 4332 [SIOCGIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens, 4333 [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange, 4334 [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy, 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}; 4356 4357 4358/* 4359 Added typecasting since we no longer use iwreq_data -- Moustafa 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}; 4372 4373static const struct iw_handler_def orinoco_handler_def = { 4374 .num_standard = ARRAY_SIZE(orinoco_handler), 4375 .num_private = ARRAY_SIZE(orinoco_private_handler), 4376 .num_private_args = ARRAY_SIZE(orinoco_privtab), 4377 .standard = orinoco_handler, 4378 .private = orinoco_private_handler, 4379 .private_args = orinoco_privtab, 4380}; 4381 4382static void orinoco_get_drvinfo(struct net_device *dev, 4383 struct ethtool_drvinfo *info) 4384{ 4385 struct orinoco_private *priv = netdev_priv(dev); 4386 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); 4396} 4397 4398static struct ethtool_ops orinoco_ethtool_ops = { 4399 .get_drvinfo = orinoco_get_drvinfo, 4400 .get_link = ethtool_op_get_link, 4401}; 4402 4403/********************************************************************/ 4404/* Debugging */ 4405/********************************************************************/ 4406 4407#if 0 4408static void show_rx_frame(struct orinoco_rxframe_hdr *frame) 4409{ 4410 printk(KERN_DEBUG "RX descriptor:\n"); 4411 printk(KERN_DEBUG " status = 0x%04x\n", frame->desc.status); 4412 printk(KERN_DEBUG " time = 0x%08x\n", frame->desc.time); 4413 printk(KERN_DEBUG " silence = 0x%02x\n", frame->desc.silence); 4414 printk(KERN_DEBUG " signal = 0x%02x\n", frame->desc.signal); 4415 printk(KERN_DEBUG " rate = 0x%02x\n", frame->desc.rate); 4416 printk(KERN_DEBUG " rxflow = 0x%02x\n", frame->desc.rxflow); 4417 printk(KERN_DEBUG " reserved = 0x%08x\n", frame->desc.reserved); 4418 4419 printk(KERN_DEBUG "IEEE 802.11 header:\n"); 4420 printk(KERN_DEBUG " frame_ctl = 0x%04x\n", 4421 frame->p80211.frame_ctl); 4422 printk(KERN_DEBUG " duration_id = 0x%04x\n", 4423 frame->p80211.duration_id); 4424 printk(KERN_DEBUG " addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n", 4425 frame->p80211.addr1[0], frame->p80211.addr1[1], 4426 frame->p80211.addr1[2], frame->p80211.addr1[3], 4427 frame->p80211.addr1[4], frame->p80211.addr1[5]); 4428 printk(KERN_DEBUG " addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n", 4429 frame->p80211.addr2[0], frame->p80211.addr2[1], 4430 frame->p80211.addr2[2], frame->p80211.addr2[3], 4431 frame->p80211.addr2[4], frame->p80211.addr2[5]); 4432 printk(KERN_DEBUG " addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n", 4433 frame->p80211.addr3[0], frame->p80211.addr3[1], 4434 frame->p80211.addr3[2], frame->p80211.addr3[3], 4435 frame->p80211.addr3[4], frame->p80211.addr3[5]); 4436 printk(KERN_DEBUG " seq_ctl = 0x%04x\n", 4437 frame->p80211.seq_ctl); 4438 printk(KERN_DEBUG " addr4 = %02x:%02x:%02x:%02x:%02x:%02x\n", 4439 frame->p80211.addr4[0], frame->p80211.addr4[1], 4440 frame->p80211.addr4[2], frame->p80211.addr4[3], 4441 frame->p80211.addr4[4], frame->p80211.addr4[5]); 4442 printk(KERN_DEBUG " data_len = 0x%04x\n", 4443 frame->p80211.data_len); 4444 4445 printk(KERN_DEBUG "IEEE 802.3 header:\n"); 4446 printk(KERN_DEBUG " dest = %02x:%02x:%02x:%02x:%02x:%02x\n", 4447 frame->p8023.h_dest[0], frame->p8023.h_dest[1], 4448 frame->p8023.h_dest[2], frame->p8023.h_dest[3], 4449 frame->p8023.h_dest[4], frame->p8023.h_dest[5]); 4450 printk(KERN_DEBUG " src = %02x:%02x:%02x:%02x:%02x:%02x\n", 4451 frame->p8023.h_source[0], frame->p8023.h_source[1], 4452 frame->p8023.h_source[2], frame->p8023.h_source[3], 4453 frame->p8023.h_source[4], frame->p8023.h_source[5]); 4454 printk(KERN_DEBUG " len = 0x%04x\n", frame->p8023.h_proto); 4455 4456 printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n"); 4457 printk(KERN_DEBUG " DSAP = 0x%02x\n", frame->p8022.dsap); 4458 printk(KERN_DEBUG " SSAP = 0x%02x\n", frame->p8022.ssap); 4459 printk(KERN_DEBUG " ctrl = 0x%02x\n", frame->p8022.ctrl); 4460 printk(KERN_DEBUG " OUI = %02x:%02x:%02x\n", 4461 frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]); 4462 printk(KERN_DEBUG " ethertype = 0x%04x\n", frame->ethertype); 4463} 4464#endif /* 0 */ 4465 4466/********************************************************************/ 4467/* Module initialization */ 4468/********************************************************************/ 4469 4470EXPORT_SYMBOL(alloc_orinocodev); 4471EXPORT_SYMBOL(free_orinocodev); 4472 4473EXPORT_SYMBOL(__orinoco_up); 4474EXPORT_SYMBOL(__orinoco_down); 4475EXPORT_SYMBOL(orinoco_reinit_firmware); 4476 4477EXPORT_SYMBOL(orinoco_interrupt); 4478 4479/* Can't be declared "const" or the whole __initdata section will 4480 * become const */ 4481static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION 4482 " (David Gibson <hermes@gibson.dropbear.id.au>, " 4483 "Pavel Roskin <proski@gnu.org>, et al)"; 4484 4485static int __init init_orinoco(void) 4486{ 4487 printk(KERN_DEBUG "%s\n", version); 4488 return 0; 4489} 4490 4491static void __exit exit_orinoco(void) 4492{ 4493} 4494 4495module_init(init_orinoco); 4496module_exit(exit_orinoco);