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 989a7241df87526bfef0396567e71ebe53a84ae4 4405 lines 118 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/module.h> 80#include <linux/kernel.h> 81#include <linux/init.h> 82#include <linux/netdevice.h> 83#include <linux/etherdevice.h> 84#include <linux/ethtool.h> 85#include <linux/if_arp.h> 86#include <linux/wireless.h> 87#include <net/iw_handler.h> 88#include <net/ieee80211.h> 89 90#include "hermes_rid.h" 91#include "orinoco.h" 92 93/********************************************************************/ 94/* Module information */ 95/********************************************************************/ 96 97MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>"); 98MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards"); 99MODULE_LICENSE("Dual MPL/GPL"); 100 101/* Level of debugging. Used in the macros in orinoco.h */ 102#ifdef ORINOCO_DEBUG 103int orinoco_debug = ORINOCO_DEBUG; 104module_param(orinoco_debug, int, 0644); 105MODULE_PARM_DESC(orinoco_debug, "Debug level"); 106EXPORT_SYMBOL(orinoco_debug); 107#endif 108 109static int suppress_linkstatus; /* = 0 */ 110module_param(suppress_linkstatus, bool, 0644); 111MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); 112static int ignore_disconnect; /* = 0 */ 113module_param(ignore_disconnect, int, 0644); 114MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer"); 115 116static int force_monitor; /* = 0 */ 117module_param(force_monitor, int, 0644); 118MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions"); 119 120/********************************************************************/ 121/* Compile time configuration and compatibility stuff */ 122/********************************************************************/ 123 124/* We do this this way to avoid ifdefs in the actual code */ 125#ifdef WIRELESS_SPY 126#define SPY_NUMBER(priv) (priv->spy_data.spy_number) 127#else 128#define SPY_NUMBER(priv) 0 129#endif /* WIRELESS_SPY */ 130 131/********************************************************************/ 132/* Internal constants */ 133/********************************************************************/ 134 135/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */ 136static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; 137#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2) 138 139#define ORINOCO_MIN_MTU 256 140#define ORINOCO_MAX_MTU (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD) 141 142#define SYMBOL_MAX_VER_LEN (14) 143#define USER_BAP 0 144#define IRQ_BAP 1 145#define MAX_IRQLOOPS_PER_IRQ 10 146#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of 147 * how many events the 148 * device could 149 * legitimately generate */ 150#define SMALL_KEY_SIZE 5 151#define LARGE_KEY_SIZE 13 152#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */ 153 154#define DUMMY_FID 0xFFFF 155 156/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \ 157 HERMES_MAX_MULTICAST : 0)*/ 158#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST) 159 160#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \ 161 | HERMES_EV_TX | HERMES_EV_TXEXC \ 162 | HERMES_EV_WTERR | HERMES_EV_INFO \ 163 | HERMES_EV_INFDROP ) 164 165#define MAX_RID_LEN 1024 166 167static const struct iw_handler_def orinoco_handler_def; 168static const struct ethtool_ops orinoco_ethtool_ops; 169 170/********************************************************************/ 171/* Data tables */ 172/********************************************************************/ 173 174/* The frequency of each channel in MHz */ 175static const long channel_frequency[] = { 176 2412, 2417, 2422, 2427, 2432, 2437, 2442, 177 2447, 2452, 2457, 2462, 2467, 2472, 2484 178}; 179#define NUM_CHANNELS ARRAY_SIZE(channel_frequency) 180 181/* This tables gives the actual meanings of the bitrate IDs returned 182 * by the firmware. */ 183static struct { 184 int bitrate; /* in 100s of kilobits */ 185 int automatic; 186 u16 agere_txratectrl; 187 u16 intersil_txratectrl; 188} bitrate_table[] = { 189 {110, 1, 3, 15}, /* Entry 0 is the default */ 190 {10, 0, 1, 1}, 191 {10, 1, 1, 1}, 192 {20, 0, 2, 2}, 193 {20, 1, 6, 3}, 194 {55, 0, 4, 4}, 195 {55, 1, 7, 7}, 196 {110, 0, 5, 8}, 197}; 198#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table) 199 200/********************************************************************/ 201/* Data types */ 202/********************************************************************/ 203 204/* Beginning of the Tx descriptor, used in TxExc handling */ 205struct hermes_txexc_data { 206 struct hermes_tx_descriptor desc; 207 __le16 frame_ctl; 208 __le16 duration_id; 209 u8 addr1[ETH_ALEN]; 210} __attribute__ ((packed)); 211 212/* Rx frame header except compatibility 802.3 header */ 213struct hermes_rx_descriptor { 214 /* Control */ 215 __le16 status; 216 __le32 time; 217 u8 silence; 218 u8 signal; 219 u8 rate; 220 u8 rxflow; 221 __le32 reserved; 222 223 /* 802.11 header */ 224 __le16 frame_ctl; 225 __le16 duration_id; 226 u8 addr1[ETH_ALEN]; 227 u8 addr2[ETH_ALEN]; 228 u8 addr3[ETH_ALEN]; 229 __le16 seq_ctl; 230 u8 addr4[ETH_ALEN]; 231 232 /* Data length */ 233 __le16 data_len; 234} __attribute__ ((packed)); 235 236/********************************************************************/ 237/* Function prototypes */ 238/********************************************************************/ 239 240static int __orinoco_program_rids(struct net_device *dev); 241static void __orinoco_set_multicast_list(struct net_device *dev); 242 243/********************************************************************/ 244/* Internal helper functions */ 245/********************************************************************/ 246 247static inline void set_port_type(struct orinoco_private *priv) 248{ 249 switch (priv->iw_mode) { 250 case IW_MODE_INFRA: 251 priv->port_type = 1; 252 priv->createibss = 0; 253 break; 254 case IW_MODE_ADHOC: 255 if (priv->prefer_port3) { 256 priv->port_type = 3; 257 priv->createibss = 0; 258 } else { 259 priv->port_type = priv->ibss_port; 260 priv->createibss = 1; 261 } 262 break; 263 case IW_MODE_MONITOR: 264 priv->port_type = 3; 265 priv->createibss = 0; 266 break; 267 default: 268 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n", 269 priv->ndev->name); 270 } 271} 272 273#define ORINOCO_MAX_BSS_COUNT 64 274static int orinoco_bss_data_allocate(struct orinoco_private *priv) 275{ 276 if (priv->bss_data) 277 return 0; 278 279 priv->bss_data = 280 kzalloc(ORINOCO_MAX_BSS_COUNT * sizeof(bss_element), GFP_KERNEL); 281 if (!priv->bss_data) { 282 printk(KERN_WARNING "Out of memory allocating beacons"); 283 return -ENOMEM; 284 } 285 return 0; 286} 287 288static void orinoco_bss_data_free(struct orinoco_private *priv) 289{ 290 kfree(priv->bss_data); 291 priv->bss_data = NULL; 292} 293 294static void orinoco_bss_data_init(struct orinoco_private *priv) 295{ 296 int i; 297 298 INIT_LIST_HEAD(&priv->bss_free_list); 299 INIT_LIST_HEAD(&priv->bss_list); 300 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++) 301 list_add_tail(&priv->bss_data[i].list, &priv->bss_free_list); 302} 303 304/********************************************************************/ 305/* Device methods */ 306/********************************************************************/ 307 308static int orinoco_open(struct net_device *dev) 309{ 310 struct orinoco_private *priv = netdev_priv(dev); 311 unsigned long flags; 312 int err; 313 314 if (orinoco_lock(priv, &flags) != 0) 315 return -EBUSY; 316 317 err = __orinoco_up(dev); 318 319 if (! err) 320 priv->open = 1; 321 322 orinoco_unlock(priv, &flags); 323 324 return err; 325} 326 327static int orinoco_stop(struct net_device *dev) 328{ 329 struct orinoco_private *priv = netdev_priv(dev); 330 int err = 0; 331 332 /* We mustn't use orinoco_lock() here, because we need to be 333 able to close the interface even if hw_unavailable is set 334 (e.g. as we're released after a PC Card removal) */ 335 spin_lock_irq(&priv->lock); 336 337 priv->open = 0; 338 339 err = __orinoco_down(dev); 340 341 spin_unlock_irq(&priv->lock); 342 343 return err; 344} 345 346static struct net_device_stats *orinoco_get_stats(struct net_device *dev) 347{ 348 struct orinoco_private *priv = netdev_priv(dev); 349 350 return &priv->stats; 351} 352 353static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) 354{ 355 struct orinoco_private *priv = netdev_priv(dev); 356 hermes_t *hw = &priv->hw; 357 struct iw_statistics *wstats = &priv->wstats; 358 int err; 359 unsigned long flags; 360 361 if (! netif_device_present(dev)) { 362 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n", 363 dev->name); 364 return NULL; /* FIXME: Can we do better than this? */ 365 } 366 367 /* If busy, return the old stats. Returning NULL may cause 368 * the interface to disappear from /proc/net/wireless */ 369 if (orinoco_lock(priv, &flags) != 0) 370 return wstats; 371 372 /* We can't really wait for the tallies inquiry command to 373 * complete, so we just use the previous results and trigger 374 * a new tallies inquiry command for next time - Jean II */ 375 /* FIXME: Really we should wait for the inquiry to come back - 376 * as it is the stats we give don't make a whole lot of sense. 377 * Unfortunately, it's not clear how to do that within the 378 * wireless extensions framework: I think we're in user 379 * context, but a lock seems to be held by the time we get in 380 * here so we're not safe to sleep here. */ 381 hermes_inquire(hw, HERMES_INQ_TALLIES); 382 383 if (priv->iw_mode == IW_MODE_ADHOC) { 384 memset(&wstats->qual, 0, sizeof(wstats->qual)); 385 /* If a spy address is defined, we report stats of the 386 * first spy address - Jean II */ 387 if (SPY_NUMBER(priv)) { 388 wstats->qual.qual = priv->spy_data.spy_stat[0].qual; 389 wstats->qual.level = priv->spy_data.spy_stat[0].level; 390 wstats->qual.noise = priv->spy_data.spy_stat[0].noise; 391 wstats->qual.updated = priv->spy_data.spy_stat[0].updated; 392 } 393 } else { 394 struct { 395 __le16 qual, signal, noise, unused; 396 } __attribute__ ((packed)) cq; 397 398 err = HERMES_READ_RECORD(hw, USER_BAP, 399 HERMES_RID_COMMSQUALITY, &cq); 400 401 if (!err) { 402 wstats->qual.qual = (int)le16_to_cpu(cq.qual); 403 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; 404 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; 405 wstats->qual.updated = 7; 406 } 407 } 408 409 orinoco_unlock(priv, &flags); 410 return wstats; 411} 412 413static void orinoco_set_multicast_list(struct net_device *dev) 414{ 415 struct orinoco_private *priv = netdev_priv(dev); 416 unsigned long flags; 417 418 if (orinoco_lock(priv, &flags) != 0) { 419 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() " 420 "called when hw_unavailable\n", dev->name); 421 return; 422 } 423 424 __orinoco_set_multicast_list(dev); 425 orinoco_unlock(priv, &flags); 426} 427 428static int orinoco_change_mtu(struct net_device *dev, int new_mtu) 429{ 430 struct orinoco_private *priv = netdev_priv(dev); 431 432 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) 433 return -EINVAL; 434 435 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) > 436 (priv->nicbuf_size - ETH_HLEN) ) 437 return -EINVAL; 438 439 dev->mtu = new_mtu; 440 441 return 0; 442} 443 444/********************************************************************/ 445/* Tx path */ 446/********************************************************************/ 447 448static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) 449{ 450 struct orinoco_private *priv = netdev_priv(dev); 451 struct net_device_stats *stats = &priv->stats; 452 hermes_t *hw = &priv->hw; 453 int err = 0; 454 u16 txfid = priv->txfid; 455 struct ethhdr *eh; 456 int data_off; 457 struct hermes_tx_descriptor desc; 458 unsigned long flags; 459 460 if (! netif_running(dev)) { 461 printk(KERN_ERR "%s: Tx on stopped device!\n", 462 dev->name); 463 return NETDEV_TX_BUSY; 464 } 465 466 if (netif_queue_stopped(dev)) { 467 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 468 dev->name); 469 return NETDEV_TX_BUSY; 470 } 471 472 if (orinoco_lock(priv, &flags) != 0) { 473 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n", 474 dev->name); 475 return NETDEV_TX_BUSY; 476 } 477 478 if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) { 479 /* Oops, the firmware hasn't established a connection, 480 silently drop the packet (this seems to be the 481 safest approach). */ 482 goto drop; 483 } 484 485 /* Check packet length */ 486 if (skb->len < ETH_HLEN) 487 goto drop; 488 489 eh = (struct ethhdr *)skb->data; 490 491 memset(&desc, 0, sizeof(desc)); 492 desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX); 493 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0); 494 if (err) { 495 if (net_ratelimit()) 496 printk(KERN_ERR "%s: Error %d writing Tx descriptor " 497 "to BAP\n", dev->name, err); 498 goto busy; 499 } 500 501 /* Clear the 802.11 header and data length fields - some 502 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused 503 * if this isn't done. */ 504 hermes_clear_words(hw, HERMES_DATA0, 505 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); 506 507 /* Encapsulate Ethernet-II frames */ 508 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ 509 struct header_struct { 510 struct ethhdr eth; /* 802.3 header */ 511 u8 encap[6]; /* 802.2 header */ 512 } __attribute__ ((packed)) hdr; 513 514 /* Strip destination and source from the data */ 515 skb_pull(skb, 2 * ETH_ALEN); 516 data_off = HERMES_802_2_OFFSET + sizeof(encaps_hdr); 517 518 /* And move them to a separate header */ 519 memcpy(&hdr.eth, eh, 2 * ETH_ALEN); 520 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len); 521 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr)); 522 523 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr), 524 txfid, HERMES_802_3_OFFSET); 525 if (err) { 526 if (net_ratelimit()) 527 printk(KERN_ERR "%s: Error %d writing packet " 528 "header to BAP\n", dev->name, err); 529 goto busy; 530 } 531 } else { /* IEEE 802.3 frame */ 532 data_off = HERMES_802_3_OFFSET; 533 } 534 535 err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len, 536 txfid, data_off); 537 if (err) { 538 printk(KERN_ERR "%s: Error %d writing packet to BAP\n", 539 dev->name, err); 540 goto busy; 541 } 542 543 /* Finally, we actually initiate the send */ 544 netif_stop_queue(dev); 545 546 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, 547 txfid, NULL); 548 if (err) { 549 netif_start_queue(dev); 550 if (net_ratelimit()) 551 printk(KERN_ERR "%s: Error %d transmitting packet\n", 552 dev->name, err); 553 goto busy; 554 } 555 556 dev->trans_start = jiffies; 557 stats->tx_bytes += data_off + skb->len; 558 goto ok; 559 560 drop: 561 stats->tx_errors++; 562 stats->tx_dropped++; 563 564 ok: 565 orinoco_unlock(priv, &flags); 566 dev_kfree_skb(skb); 567 return NETDEV_TX_OK; 568 569 busy: 570 if (err == -EIO) 571 schedule_work(&priv->reset_work); 572 orinoco_unlock(priv, &flags); 573 return NETDEV_TX_BUSY; 574} 575 576static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw) 577{ 578 struct orinoco_private *priv = netdev_priv(dev); 579 u16 fid = hermes_read_regn(hw, ALLOCFID); 580 581 if (fid != priv->txfid) { 582 if (fid != DUMMY_FID) 583 printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n", 584 dev->name, fid); 585 return; 586 } 587 588 hermes_write_regn(hw, ALLOCFID, DUMMY_FID); 589} 590 591static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw) 592{ 593 struct orinoco_private *priv = netdev_priv(dev); 594 struct net_device_stats *stats = &priv->stats; 595 596 stats->tx_packets++; 597 598 netif_wake_queue(dev); 599 600 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 601} 602 603static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) 604{ 605 struct orinoco_private *priv = netdev_priv(dev); 606 struct net_device_stats *stats = &priv->stats; 607 u16 fid = hermes_read_regn(hw, TXCOMPLFID); 608 u16 status; 609 struct hermes_txexc_data hdr; 610 int err = 0; 611 612 if (fid == DUMMY_FID) 613 return; /* Nothing's really happened */ 614 615 /* Read part of the frame header - we need status and addr1 */ 616 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, 617 sizeof(struct hermes_txexc_data), 618 fid, 0); 619 620 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 621 stats->tx_errors++; 622 623 if (err) { 624 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error " 625 "(FID=%04X error %d)\n", 626 dev->name, fid, err); 627 return; 628 } 629 630 DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name, 631 err, fid); 632 633 /* We produce a TXDROP event only for retry or lifetime 634 * exceeded, because that's the only status that really mean 635 * that this particular node went away. 636 * Other errors means that *we* screwed up. - Jean II */ 637 status = le16_to_cpu(hdr.desc.status); 638 if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) { 639 union iwreq_data wrqu; 640 641 /* Copy 802.11 dest address. 642 * We use the 802.11 header because the frame may 643 * not be 802.3 or may be mangled... 644 * In Ad-Hoc mode, it will be the node address. 645 * In managed mode, it will be most likely the AP addr 646 * User space will figure out how to convert it to 647 * whatever it needs (IP address or else). 648 * - Jean II */ 649 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN); 650 wrqu.addr.sa_family = ARPHRD_ETHER; 651 652 /* Send event to user space */ 653 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL); 654 } 655 656 netif_wake_queue(dev); 657} 658 659static void orinoco_tx_timeout(struct net_device *dev) 660{ 661 struct orinoco_private *priv = netdev_priv(dev); 662 struct net_device_stats *stats = &priv->stats; 663 struct hermes *hw = &priv->hw; 664 665 printk(KERN_WARNING "%s: Tx timeout! " 666 "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n", 667 dev->name, hermes_read_regn(hw, ALLOCFID), 668 hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT)); 669 670 stats->tx_errors++; 671 672 schedule_work(&priv->reset_work); 673} 674 675/********************************************************************/ 676/* Rx path (data frames) */ 677/********************************************************************/ 678 679/* Does the frame have a SNAP header indicating it should be 680 * de-encapsulated to Ethernet-II? */ 681static inline int is_ethersnap(void *_hdr) 682{ 683 u8 *hdr = _hdr; 684 685 /* We de-encapsulate all packets which, a) have SNAP headers 686 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header 687 * and where b) the OUI of the SNAP header is 00:00:00 or 688 * 00:00:f8 - we need both because different APs appear to use 689 * different OUIs for some reason */ 690 return (memcmp(hdr, &encaps_hdr, 5) == 0) 691 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) ); 692} 693 694static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, 695 int level, int noise) 696{ 697 struct iw_quality wstats; 698 wstats.level = level - 0x95; 699 wstats.noise = noise - 0x95; 700 wstats.qual = (level > noise) ? (level - noise) : 0; 701 wstats.updated = 7; 702 /* Update spy records */ 703 wireless_spy_update(dev, mac, &wstats); 704} 705 706static void orinoco_stat_gather(struct net_device *dev, 707 struct sk_buff *skb, 708 struct hermes_rx_descriptor *desc) 709{ 710 struct orinoco_private *priv = netdev_priv(dev); 711 712 /* Using spy support with lots of Rx packets, like in an 713 * infrastructure (AP), will really slow down everything, because 714 * the MAC address must be compared to each entry of the spy list. 715 * If the user really asks for it (set some address in the 716 * spy list), we do it, but he will pay the price. 717 * Note that to get here, you need both WIRELESS_SPY 718 * compiled in AND some addresses in the list !!! 719 */ 720 /* Note : gcc will optimise the whole section away if 721 * WIRELESS_SPY is not defined... - Jean II */ 722 if (SPY_NUMBER(priv)) { 723 orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN, 724 desc->signal, desc->silence); 725 } 726} 727 728/* 729 * orinoco_rx_monitor - handle received monitor frames. 730 * 731 * Arguments: 732 * dev network device 733 * rxfid received FID 734 * desc rx descriptor of the frame 735 * 736 * Call context: interrupt 737 */ 738static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, 739 struct hermes_rx_descriptor *desc) 740{ 741 u32 hdrlen = 30; /* return full header by default */ 742 u32 datalen = 0; 743 u16 fc; 744 int err; 745 int len; 746 struct sk_buff *skb; 747 struct orinoco_private *priv = netdev_priv(dev); 748 struct net_device_stats *stats = &priv->stats; 749 hermes_t *hw = &priv->hw; 750 751 len = le16_to_cpu(desc->data_len); 752 753 /* Determine the size of the header and the data */ 754 fc = le16_to_cpu(desc->frame_ctl); 755 switch (fc & IEEE80211_FCTL_FTYPE) { 756 case IEEE80211_FTYPE_DATA: 757 if ((fc & IEEE80211_FCTL_TODS) 758 && (fc & IEEE80211_FCTL_FROMDS)) 759 hdrlen = 30; 760 else 761 hdrlen = 24; 762 datalen = len; 763 break; 764 case IEEE80211_FTYPE_MGMT: 765 hdrlen = 24; 766 datalen = len; 767 break; 768 case IEEE80211_FTYPE_CTL: 769 switch (fc & IEEE80211_FCTL_STYPE) { 770 case IEEE80211_STYPE_PSPOLL: 771 case IEEE80211_STYPE_RTS: 772 case IEEE80211_STYPE_CFEND: 773 case IEEE80211_STYPE_CFENDACK: 774 hdrlen = 16; 775 break; 776 case IEEE80211_STYPE_CTS: 777 case IEEE80211_STYPE_ACK: 778 hdrlen = 10; 779 break; 780 } 781 break; 782 default: 783 /* Unknown frame type */ 784 break; 785 } 786 787 /* sanity check the length */ 788 if (datalen > IEEE80211_DATA_LEN + 12) { 789 printk(KERN_DEBUG "%s: oversized monitor frame, " 790 "data length = %d\n", dev->name, datalen); 791 stats->rx_length_errors++; 792 goto update_stats; 793 } 794 795 skb = dev_alloc_skb(hdrlen + datalen); 796 if (!skb) { 797 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n", 798 dev->name); 799 goto update_stats; 800 } 801 802 /* Copy the 802.11 header to the skb */ 803 memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen); 804 skb_reset_mac_header(skb); 805 806 /* If any, copy the data from the card to the skb */ 807 if (datalen > 0) { 808 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), 809 ALIGN(datalen, 2), rxfid, 810 HERMES_802_2_OFFSET); 811 if (err) { 812 printk(KERN_ERR "%s: error %d reading monitor frame\n", 813 dev->name, err); 814 goto drop; 815 } 816 } 817 818 skb->dev = dev; 819 skb->ip_summed = CHECKSUM_NONE; 820 skb->pkt_type = PACKET_OTHERHOST; 821 skb->protocol = __constant_htons(ETH_P_802_2); 822 823 dev->last_rx = jiffies; 824 stats->rx_packets++; 825 stats->rx_bytes += skb->len; 826 827 netif_rx(skb); 828 return; 829 830 drop: 831 dev_kfree_skb_irq(skb); 832 update_stats: 833 stats->rx_errors++; 834 stats->rx_dropped++; 835} 836 837static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) 838{ 839 struct orinoco_private *priv = netdev_priv(dev); 840 struct net_device_stats *stats = &priv->stats; 841 struct iw_statistics *wstats = &priv->wstats; 842 struct sk_buff *skb = NULL; 843 u16 rxfid, status, fc; 844 int length; 845 struct hermes_rx_descriptor desc; 846 struct ethhdr *hdr; 847 int err; 848 849 rxfid = hermes_read_regn(hw, RXFID); 850 851 err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), 852 rxfid, 0); 853 if (err) { 854 printk(KERN_ERR "%s: error %d reading Rx descriptor. " 855 "Frame dropped.\n", dev->name, err); 856 goto update_stats; 857 } 858 859 status = le16_to_cpu(desc.status); 860 861 if (status & HERMES_RXSTAT_BADCRC) { 862 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", 863 dev->name); 864 stats->rx_crc_errors++; 865 goto update_stats; 866 } 867 868 /* Handle frames in monitor mode */ 869 if (priv->iw_mode == IW_MODE_MONITOR) { 870 orinoco_rx_monitor(dev, rxfid, &desc); 871 return; 872 } 873 874 if (status & HERMES_RXSTAT_UNDECRYPTABLE) { 875 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n", 876 dev->name); 877 wstats->discard.code++; 878 goto update_stats; 879 } 880 881 length = le16_to_cpu(desc.data_len); 882 fc = le16_to_cpu(desc.frame_ctl); 883 884 /* Sanity checks */ 885 if (length < 3) { /* No for even an 802.2 LLC header */ 886 /* At least on Symbol firmware with PCF we get quite a 887 lot of these legitimately - Poll frames with no 888 data. */ 889 return; 890 } 891 if (length > IEEE80211_DATA_LEN) { 892 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", 893 dev->name, length); 894 stats->rx_length_errors++; 895 goto update_stats; 896 } 897 898 /* We need space for the packet data itself, plus an ethernet 899 header, plus 2 bytes so we can align the IP header on a 900 32bit boundary, plus 1 byte so we can read in odd length 901 packets from the card, which has an IO granularity of 16 902 bits */ 903 skb = dev_alloc_skb(length+ETH_HLEN+2+1); 904 if (!skb) { 905 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n", 906 dev->name); 907 goto update_stats; 908 } 909 910 /* We'll prepend the header, so reserve space for it. The worst 911 case is no decapsulation, when 802.3 header is prepended and 912 nothing is removed. 2 is for aligning the IP header. */ 913 skb_reserve(skb, ETH_HLEN + 2); 914 915 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length), 916 ALIGN(length, 2), rxfid, 917 HERMES_802_2_OFFSET); 918 if (err) { 919 printk(KERN_ERR "%s: error %d reading frame. " 920 "Frame dropped.\n", dev->name, err); 921 goto drop; 922 } 923 924 /* Handle decapsulation 925 * In most cases, the firmware tell us about SNAP frames. 926 * For some reason, the SNAP frames sent by LinkSys APs 927 * are not properly recognised by most firmwares. 928 * So, check ourselves */ 929 if (length >= ENCAPS_OVERHEAD && 930 (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) || 931 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) || 932 is_ethersnap(skb->data))) { 933 /* These indicate a SNAP within 802.2 LLC within 934 802.11 frame which we'll need to de-encapsulate to 935 the original EthernetII frame. */ 936 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD); 937 } else { 938 /* 802.3 frame - prepend 802.3 header as is */ 939 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN); 940 hdr->h_proto = htons(length); 941 } 942 memcpy(hdr->h_dest, desc.addr1, ETH_ALEN); 943 if (fc & IEEE80211_FCTL_FROMDS) 944 memcpy(hdr->h_source, desc.addr3, ETH_ALEN); 945 else 946 memcpy(hdr->h_source, desc.addr2, ETH_ALEN); 947 948 dev->last_rx = jiffies; 949 skb->protocol = eth_type_trans(skb, dev); 950 skb->ip_summed = CHECKSUM_NONE; 951 if (fc & IEEE80211_FCTL_TODS) 952 skb->pkt_type = PACKET_OTHERHOST; 953 954 /* Process the wireless stats if needed */ 955 orinoco_stat_gather(dev, skb, &desc); 956 957 /* Pass the packet to the networking stack */ 958 netif_rx(skb); 959 stats->rx_packets++; 960 stats->rx_bytes += length; 961 962 return; 963 964 drop: 965 dev_kfree_skb_irq(skb); 966 update_stats: 967 stats->rx_errors++; 968 stats->rx_dropped++; 969} 970 971/********************************************************************/ 972/* Rx path (info frames) */ 973/********************************************************************/ 974 975static void print_linkstatus(struct net_device *dev, u16 status) 976{ 977 char * s; 978 979 if (suppress_linkstatus) 980 return; 981 982 switch (status) { 983 case HERMES_LINKSTATUS_NOT_CONNECTED: 984 s = "Not Connected"; 985 break; 986 case HERMES_LINKSTATUS_CONNECTED: 987 s = "Connected"; 988 break; 989 case HERMES_LINKSTATUS_DISCONNECTED: 990 s = "Disconnected"; 991 break; 992 case HERMES_LINKSTATUS_AP_CHANGE: 993 s = "AP Changed"; 994 break; 995 case HERMES_LINKSTATUS_AP_OUT_OF_RANGE: 996 s = "AP Out of Range"; 997 break; 998 case HERMES_LINKSTATUS_AP_IN_RANGE: 999 s = "AP In Range"; 1000 break; 1001 case HERMES_LINKSTATUS_ASSOC_FAILED: 1002 s = "Association Failed"; 1003 break; 1004 default: 1005 s = "UNKNOWN"; 1006 } 1007 1008 printk(KERN_INFO "%s: New link status: %s (%04x)\n", 1009 dev->name, s, status); 1010} 1011 1012/* Search scan results for requested BSSID, join it if found */ 1013static void orinoco_join_ap(struct work_struct *work) 1014{ 1015 struct orinoco_private *priv = 1016 container_of(work, struct orinoco_private, join_work); 1017 struct net_device *dev = priv->ndev; 1018 struct hermes *hw = &priv->hw; 1019 int err; 1020 unsigned long flags; 1021 struct join_req { 1022 u8 bssid[ETH_ALEN]; 1023 __le16 channel; 1024 } __attribute__ ((packed)) req; 1025 const int atom_len = offsetof(struct prism2_scan_apinfo, atim); 1026 struct prism2_scan_apinfo *atom = NULL; 1027 int offset = 4; 1028 int found = 0; 1029 u8 *buf; 1030 u16 len; 1031 1032 /* Allocate buffer for scan results */ 1033 buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL); 1034 if (! buf) 1035 return; 1036 1037 if (orinoco_lock(priv, &flags) != 0) 1038 goto fail_lock; 1039 1040 /* Sanity checks in case user changed something in the meantime */ 1041 if (! priv->bssid_fixed) 1042 goto out; 1043 1044 if (strlen(priv->desired_essid) == 0) 1045 goto out; 1046 1047 /* Read scan results from the firmware */ 1048 err = hermes_read_ltv(hw, USER_BAP, 1049 HERMES_RID_SCANRESULTSTABLE, 1050 MAX_SCAN_LEN, &len, buf); 1051 if (err) { 1052 printk(KERN_ERR "%s: Cannot read scan results\n", 1053 dev->name); 1054 goto out; 1055 } 1056 1057 len = HERMES_RECLEN_TO_BYTES(len); 1058 1059 /* Go through the scan results looking for the channel of the AP 1060 * we were requested to join */ 1061 for (; offset + atom_len <= len; offset += atom_len) { 1062 atom = (struct prism2_scan_apinfo *) (buf + offset); 1063 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) { 1064 found = 1; 1065 break; 1066 } 1067 } 1068 1069 if (! found) { 1070 DEBUG(1, "%s: Requested AP not found in scan results\n", 1071 dev->name); 1072 goto out; 1073 } 1074 1075 memcpy(req.bssid, priv->desired_bssid, ETH_ALEN); 1076 req.channel = atom->channel; /* both are little-endian */ 1077 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST, 1078 &req); 1079 if (err) 1080 printk(KERN_ERR "%s: Error issuing join request\n", dev->name); 1081 1082 out: 1083 orinoco_unlock(priv, &flags); 1084 1085 fail_lock: 1086 kfree(buf); 1087} 1088 1089/* Send new BSSID to userspace */ 1090static void orinoco_send_wevents(struct work_struct *work) 1091{ 1092 struct orinoco_private *priv = 1093 container_of(work, struct orinoco_private, wevent_work); 1094 struct net_device *dev = priv->ndev; 1095 struct hermes *hw = &priv->hw; 1096 union iwreq_data wrqu; 1097 int err; 1098 unsigned long flags; 1099 1100 if (orinoco_lock(priv, &flags) != 0) 1101 return; 1102 1103 err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID, 1104 ETH_ALEN, NULL, wrqu.ap_addr.sa_data); 1105 if (err != 0) 1106 goto out; 1107 1108 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1109 1110 /* Send event to user space */ 1111 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 1112 1113 out: 1114 orinoco_unlock(priv, &flags); 1115} 1116 1117 1118static inline void orinoco_clear_scan_results(struct orinoco_private *priv, 1119 unsigned long scan_age) 1120{ 1121 bss_element *bss; 1122 bss_element *tmp_bss; 1123 1124 /* Blow away current list of scan results */ 1125 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) { 1126 if (!scan_age || 1127 time_after(jiffies, bss->last_scanned + scan_age)) { 1128 list_move_tail(&bss->list, &priv->bss_free_list); 1129 /* Don't blow away ->list, just BSS data */ 1130 memset(bss, 0, sizeof(bss->bss)); 1131 bss->last_scanned = 0; 1132 } 1133 } 1134} 1135 1136static int orinoco_process_scan_results(struct net_device *dev, 1137 unsigned char *buf, 1138 int len) 1139{ 1140 struct orinoco_private *priv = netdev_priv(dev); 1141 int offset; /* In the scan data */ 1142 union hermes_scan_info *atom; 1143 int atom_len; 1144 1145 switch (priv->firmware_type) { 1146 case FIRMWARE_TYPE_AGERE: 1147 atom_len = sizeof(struct agere_scan_apinfo); 1148 offset = 0; 1149 break; 1150 case FIRMWARE_TYPE_SYMBOL: 1151 /* Lack of documentation necessitates this hack. 1152 * Different firmwares have 68 or 76 byte long atoms. 1153 * We try modulo first. If the length divides by both, 1154 * we check what would be the channel in the second 1155 * frame for a 68-byte atom. 76-byte atoms have 0 there. 1156 * Valid channel cannot be 0. */ 1157 if (len % 76) 1158 atom_len = 68; 1159 else if (len % 68) 1160 atom_len = 76; 1161 else if (len >= 1292 && buf[68] == 0) 1162 atom_len = 76; 1163 else 1164 atom_len = 68; 1165 offset = 0; 1166 break; 1167 case FIRMWARE_TYPE_INTERSIL: 1168 offset = 4; 1169 if (priv->has_hostscan) { 1170 atom_len = le16_to_cpup((__le16 *)buf); 1171 /* Sanity check for atom_len */ 1172 if (atom_len < sizeof(struct prism2_scan_apinfo)) { 1173 printk(KERN_ERR "%s: Invalid atom_len in scan " 1174 "data: %d\n", dev->name, atom_len); 1175 return -EIO; 1176 } 1177 } else 1178 atom_len = offsetof(struct prism2_scan_apinfo, atim); 1179 break; 1180 default: 1181 return -EOPNOTSUPP; 1182 } 1183 1184 /* Check that we got an whole number of atoms */ 1185 if ((len - offset) % atom_len) { 1186 printk(KERN_ERR "%s: Unexpected scan data length %d, " 1187 "atom_len %d, offset %d\n", dev->name, len, 1188 atom_len, offset); 1189 return -EIO; 1190 } 1191 1192 orinoco_clear_scan_results(priv, msecs_to_jiffies(15000)); 1193 1194 /* Read the entries one by one */ 1195 for (; offset + atom_len <= len; offset += atom_len) { 1196 int found = 0; 1197 bss_element *bss = NULL; 1198 1199 /* Get next atom */ 1200 atom = (union hermes_scan_info *) (buf + offset); 1201 1202 /* Try to update an existing bss first */ 1203 list_for_each_entry(bss, &priv->bss_list, list) { 1204 if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid)) 1205 continue; 1206 if (le16_to_cpu(bss->bss.a.essid_len) != 1207 le16_to_cpu(atom->a.essid_len)) 1208 continue; 1209 if (memcmp(bss->bss.a.essid, atom->a.essid, 1210 le16_to_cpu(atom->a.essid_len))) 1211 continue; 1212 found = 1; 1213 break; 1214 } 1215 1216 /* Grab a bss off the free list */ 1217 if (!found && !list_empty(&priv->bss_free_list)) { 1218 bss = list_entry(priv->bss_free_list.next, 1219 bss_element, list); 1220 list_del(priv->bss_free_list.next); 1221 1222 list_add_tail(&bss->list, &priv->bss_list); 1223 } 1224 1225 if (bss) { 1226 /* Always update the BSS to get latest beacon info */ 1227 memcpy(&bss->bss, atom, sizeof(bss->bss)); 1228 bss->last_scanned = jiffies; 1229 } 1230 } 1231 1232 return 0; 1233} 1234 1235static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) 1236{ 1237 struct orinoco_private *priv = netdev_priv(dev); 1238 u16 infofid; 1239 struct { 1240 __le16 len; 1241 __le16 type; 1242 } __attribute__ ((packed)) info; 1243 int len, type; 1244 int err; 1245 1246 /* This is an answer to an INQUIRE command that we did earlier, 1247 * or an information "event" generated by the card 1248 * The controller return to us a pseudo frame containing 1249 * the information in question - Jean II */ 1250 infofid = hermes_read_regn(hw, INFOFID); 1251 1252 /* Read the info frame header - don't try too hard */ 1253 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), 1254 infofid, 0); 1255 if (err) { 1256 printk(KERN_ERR "%s: error %d reading info frame. " 1257 "Frame dropped.\n", dev->name, err); 1258 return; 1259 } 1260 1261 len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len)); 1262 type = le16_to_cpu(info.type); 1263 1264 switch (type) { 1265 case HERMES_INQ_TALLIES: { 1266 struct hermes_tallies_frame tallies; 1267 struct iw_statistics *wstats = &priv->wstats; 1268 1269 if (len > sizeof(tallies)) { 1270 printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n", 1271 dev->name, len); 1272 len = sizeof(tallies); 1273 } 1274 1275 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, 1276 infofid, sizeof(info)); 1277 if (err) 1278 break; 1279 1280 /* Increment our various counters */ 1281 /* wstats->discard.nwid - no wrong BSSID stuff */ 1282 wstats->discard.code += 1283 le16_to_cpu(tallies.RxWEPUndecryptable); 1284 if (len == sizeof(tallies)) 1285 wstats->discard.code += 1286 le16_to_cpu(tallies.RxDiscards_WEPICVError) + 1287 le16_to_cpu(tallies.RxDiscards_WEPExcluded); 1288 wstats->discard.misc += 1289 le16_to_cpu(tallies.TxDiscardsWrongSA); 1290 wstats->discard.fragment += 1291 le16_to_cpu(tallies.RxMsgInBadMsgFragments); 1292 wstats->discard.retries += 1293 le16_to_cpu(tallies.TxRetryLimitExceeded); 1294 /* wstats->miss.beacon - no match */ 1295 } 1296 break; 1297 case HERMES_INQ_LINKSTATUS: { 1298 struct hermes_linkstatus linkstatus; 1299 u16 newstatus; 1300 int connected; 1301 1302 if (priv->iw_mode == IW_MODE_MONITOR) 1303 break; 1304 1305 if (len != sizeof(linkstatus)) { 1306 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n", 1307 dev->name, len); 1308 break; 1309 } 1310 1311 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, 1312 infofid, sizeof(info)); 1313 if (err) 1314 break; 1315 newstatus = le16_to_cpu(linkstatus.linkstatus); 1316 1317 /* Symbol firmware uses "out of range" to signal that 1318 * the hostscan frame can be requested. */ 1319 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE && 1320 priv->firmware_type == FIRMWARE_TYPE_SYMBOL && 1321 priv->has_hostscan && priv->scan_inprogress) { 1322 hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL); 1323 break; 1324 } 1325 1326 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) 1327 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE) 1328 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE); 1329 1330 if (connected) 1331 netif_carrier_on(dev); 1332 else if (!ignore_disconnect) 1333 netif_carrier_off(dev); 1334 1335 if (newstatus != priv->last_linkstatus) { 1336 priv->last_linkstatus = newstatus; 1337 print_linkstatus(dev, newstatus); 1338 /* The info frame contains only one word which is the 1339 * status (see hermes.h). The status is pretty boring 1340 * in itself, that's why we export the new BSSID... 1341 * Jean II */ 1342 schedule_work(&priv->wevent_work); 1343 } 1344 } 1345 break; 1346 case HERMES_INQ_SCAN: 1347 if (!priv->scan_inprogress && priv->bssid_fixed && 1348 priv->firmware_type == FIRMWARE_TYPE_INTERSIL) { 1349 schedule_work(&priv->join_work); 1350 break; 1351 } 1352 /* fall through */ 1353 case HERMES_INQ_HOSTSCAN: 1354 case HERMES_INQ_HOSTSCAN_SYMBOL: { 1355 /* Result of a scanning. Contains information about 1356 * cells in the vicinity - Jean II */ 1357 union iwreq_data wrqu; 1358 unsigned char *buf; 1359 1360 /* Scan is no longer in progress */ 1361 priv->scan_inprogress = 0; 1362 1363 /* Sanity check */ 1364 if (len > 4096) { 1365 printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n", 1366 dev->name, len); 1367 break; 1368 } 1369 1370 /* Allocate buffer for results */ 1371 buf = kmalloc(len, GFP_ATOMIC); 1372 if (buf == NULL) 1373 /* No memory, so can't printk()... */ 1374 break; 1375 1376 /* Read scan data */ 1377 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, 1378 infofid, sizeof(info)); 1379 if (err) { 1380 kfree(buf); 1381 break; 1382 } 1383 1384#ifdef ORINOCO_DEBUG 1385 { 1386 int i; 1387 printk(KERN_DEBUG "Scan result [%02X", buf[0]); 1388 for(i = 1; i < (len * 2); i++) 1389 printk(":%02X", buf[i]); 1390 printk("]\n"); 1391 } 1392#endif /* ORINOCO_DEBUG */ 1393 1394 if (orinoco_process_scan_results(dev, buf, len) == 0) { 1395 /* Send an empty event to user space. 1396 * We don't send the received data on the event because 1397 * it would require us to do complex transcoding, and 1398 * we want to minimise the work done in the irq handler 1399 * Use a request to extract the data - Jean II */ 1400 wrqu.data.length = 0; 1401 wrqu.data.flags = 0; 1402 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); 1403 } 1404 kfree(buf); 1405 } 1406 break; 1407 case HERMES_INQ_SEC_STAT_AGERE: 1408 /* Security status (Agere specific) */ 1409 /* Ignore this frame for now */ 1410 if (priv->firmware_type == FIRMWARE_TYPE_AGERE) 1411 break; 1412 /* fall through */ 1413 default: 1414 printk(KERN_DEBUG "%s: Unknown information frame received: " 1415 "type 0x%04x, length %d\n", dev->name, type, len); 1416 /* We don't actually do anything about it */ 1417 break; 1418 } 1419} 1420 1421static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) 1422{ 1423 if (net_ratelimit()) 1424 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name); 1425} 1426 1427/********************************************************************/ 1428/* Internal hardware control routines */ 1429/********************************************************************/ 1430 1431int __orinoco_up(struct net_device *dev) 1432{ 1433 struct orinoco_private *priv = netdev_priv(dev); 1434 struct hermes *hw = &priv->hw; 1435 int err; 1436 1437 netif_carrier_off(dev); /* just to make sure */ 1438 1439 err = __orinoco_program_rids(dev); 1440 if (err) { 1441 printk(KERN_ERR "%s: Error %d configuring card\n", 1442 dev->name, err); 1443 return err; 1444 } 1445 1446 /* Fire things up again */ 1447 hermes_set_irqmask(hw, ORINOCO_INTEN); 1448 err = hermes_enable_port(hw, 0); 1449 if (err) { 1450 printk(KERN_ERR "%s: Error %d enabling MAC port\n", 1451 dev->name, err); 1452 return err; 1453 } 1454 1455 netif_start_queue(dev); 1456 1457 return 0; 1458} 1459 1460int __orinoco_down(struct net_device *dev) 1461{ 1462 struct orinoco_private *priv = netdev_priv(dev); 1463 struct hermes *hw = &priv->hw; 1464 int err; 1465 1466 netif_stop_queue(dev); 1467 1468 if (! priv->hw_unavailable) { 1469 if (! priv->broken_disableport) { 1470 err = hermes_disable_port(hw, 0); 1471 if (err) { 1472 /* Some firmwares (e.g. Intersil 1.3.x) seem 1473 * to have problems disabling the port, oh 1474 * well, too bad. */ 1475 printk(KERN_WARNING "%s: Error %d disabling MAC port\n", 1476 dev->name, err); 1477 priv->broken_disableport = 1; 1478 } 1479 } 1480 hermes_set_irqmask(hw, 0); 1481 hermes_write_regn(hw, EVACK, 0xffff); 1482 } 1483 1484 /* firmware will have to reassociate */ 1485 netif_carrier_off(dev); 1486 priv->last_linkstatus = 0xffff; 1487 1488 return 0; 1489} 1490 1491static int orinoco_allocate_fid(struct net_device *dev) 1492{ 1493 struct orinoco_private *priv = netdev_priv(dev); 1494 struct hermes *hw = &priv->hw; 1495 int err; 1496 1497 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 1498 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { 1499 /* Try workaround for old Symbol firmware bug */ 1500 printk(KERN_WARNING "%s: firmware ALLOC bug detected " 1501 "(old Symbol firmware?). Trying to work around... ", 1502 dev->name); 1503 1504 priv->nicbuf_size = TX_NICBUF_SIZE_BUG; 1505 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 1506 if (err) 1507 printk("failed!\n"); 1508 else 1509 printk("ok.\n"); 1510 } 1511 1512 return err; 1513} 1514 1515int orinoco_reinit_firmware(struct net_device *dev) 1516{ 1517 struct orinoco_private *priv = netdev_priv(dev); 1518 struct hermes *hw = &priv->hw; 1519 int err; 1520 1521 err = hermes_init(hw); 1522 if (!err) 1523 err = orinoco_allocate_fid(dev); 1524 1525 return err; 1526} 1527 1528static int __orinoco_hw_set_bitrate(struct orinoco_private *priv) 1529{ 1530 hermes_t *hw = &priv->hw; 1531 int err = 0; 1532 1533 if (priv->bitratemode >= BITRATE_TABLE_SIZE) { 1534 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n", 1535 priv->ndev->name, priv->bitratemode); 1536 return -EINVAL; 1537 } 1538 1539 switch (priv->firmware_type) { 1540 case FIRMWARE_TYPE_AGERE: 1541 err = hermes_write_wordrec(hw, USER_BAP, 1542 HERMES_RID_CNFTXRATECONTROL, 1543 bitrate_table[priv->bitratemode].agere_txratectrl); 1544 break; 1545 case FIRMWARE_TYPE_INTERSIL: 1546 case FIRMWARE_TYPE_SYMBOL: 1547 err = hermes_write_wordrec(hw, USER_BAP, 1548 HERMES_RID_CNFTXRATECONTROL, 1549 bitrate_table[priv->bitratemode].intersil_txratectrl); 1550 break; 1551 default: 1552 BUG(); 1553 } 1554 1555 return err; 1556} 1557 1558/* Set fixed AP address */ 1559static int __orinoco_hw_set_wap(struct orinoco_private *priv) 1560{ 1561 int roaming_flag; 1562 int err = 0; 1563 hermes_t *hw = &priv->hw; 1564 1565 switch (priv->firmware_type) { 1566 case FIRMWARE_TYPE_AGERE: 1567 /* not supported */ 1568 break; 1569 case FIRMWARE_TYPE_INTERSIL: 1570 if (priv->bssid_fixed) 1571 roaming_flag = 2; 1572 else 1573 roaming_flag = 1; 1574 1575 err = hermes_write_wordrec(hw, USER_BAP, 1576 HERMES_RID_CNFROAMINGMODE, 1577 roaming_flag); 1578 break; 1579 case FIRMWARE_TYPE_SYMBOL: 1580 err = HERMES_WRITE_RECORD(hw, USER_BAP, 1581 HERMES_RID_CNFMANDATORYBSSID_SYMBOL, 1582 &priv->desired_bssid); 1583 break; 1584 } 1585 return err; 1586} 1587 1588/* Change the WEP keys and/or the current keys. Can be called 1589 * either from __orinoco_hw_setup_wep() or directly from 1590 * orinoco_ioctl_setiwencode(). In the later case the association 1591 * with the AP is not broken (if the firmware can handle it), 1592 * which is needed for 802.1x implementations. */ 1593static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv) 1594{ 1595 hermes_t *hw = &priv->hw; 1596 int err = 0; 1597 1598 switch (priv->firmware_type) { 1599 case FIRMWARE_TYPE_AGERE: 1600 err = HERMES_WRITE_RECORD(hw, USER_BAP, 1601 HERMES_RID_CNFWEPKEYS_AGERE, 1602 &priv->keys); 1603 if (err) 1604 return err; 1605 err = hermes_write_wordrec(hw, USER_BAP, 1606 HERMES_RID_CNFTXKEY_AGERE, 1607 priv->tx_key); 1608 if (err) 1609 return err; 1610 break; 1611 case FIRMWARE_TYPE_INTERSIL: 1612 case FIRMWARE_TYPE_SYMBOL: 1613 { 1614 int keylen; 1615 int i; 1616 1617 /* Force uniform key length to work around firmware bugs */ 1618 keylen = le16_to_cpu(priv->keys[priv->tx_key].len); 1619 1620 if (keylen > LARGE_KEY_SIZE) { 1621 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n", 1622 priv->ndev->name, priv->tx_key, keylen); 1623 return -E2BIG; 1624 } 1625 1626 /* Write all 4 keys */ 1627 for(i = 0; i < ORINOCO_MAX_KEYS; i++) { 1628 err = hermes_write_ltv(hw, USER_BAP, 1629 HERMES_RID_CNFDEFAULTKEY0 + i, 1630 HERMES_BYTES_TO_RECLEN(keylen), 1631 priv->keys[i].data); 1632 if (err) 1633 return err; 1634 } 1635 1636 /* Write the index of the key used in transmission */ 1637 err = hermes_write_wordrec(hw, USER_BAP, 1638 HERMES_RID_CNFWEPDEFAULTKEYID, 1639 priv->tx_key); 1640 if (err) 1641 return err; 1642 } 1643 break; 1644 } 1645 1646 return 0; 1647} 1648 1649static int __orinoco_hw_setup_wep(struct orinoco_private *priv) 1650{ 1651 hermes_t *hw = &priv->hw; 1652 int err = 0; 1653 int master_wep_flag; 1654 int auth_flag; 1655 1656 if (priv->wep_on) 1657 __orinoco_hw_setup_wepkeys(priv); 1658 1659 if (priv->wep_restrict) 1660 auth_flag = HERMES_AUTH_SHARED_KEY; 1661 else 1662 auth_flag = HERMES_AUTH_OPEN; 1663 1664 switch (priv->firmware_type) { 1665 case FIRMWARE_TYPE_AGERE: /* Agere style WEP */ 1666 if (priv->wep_on) { 1667 /* Enable the shared-key authentication. */ 1668 err = hermes_write_wordrec(hw, USER_BAP, 1669 HERMES_RID_CNFAUTHENTICATION_AGERE, 1670 auth_flag); 1671 } 1672 err = hermes_write_wordrec(hw, USER_BAP, 1673 HERMES_RID_CNFWEPENABLED_AGERE, 1674 priv->wep_on); 1675 if (err) 1676 return err; 1677 break; 1678 1679 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */ 1680 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */ 1681 if (priv->wep_on) { 1682 if (priv->wep_restrict || 1683 (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)) 1684 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED | 1685 HERMES_WEP_EXCL_UNENCRYPTED; 1686 else 1687 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED; 1688 1689 err = hermes_write_wordrec(hw, USER_BAP, 1690 HERMES_RID_CNFAUTHENTICATION, 1691 auth_flag); 1692 if (err) 1693 return err; 1694 } else 1695 master_wep_flag = 0; 1696 1697 if (priv->iw_mode == IW_MODE_MONITOR) 1698 master_wep_flag |= HERMES_WEP_HOST_DECRYPT; 1699 1700 /* Master WEP setting : on/off */ 1701 err = hermes_write_wordrec(hw, USER_BAP, 1702 HERMES_RID_CNFWEPFLAGS_INTERSIL, 1703 master_wep_flag); 1704 if (err) 1705 return err; 1706 1707 break; 1708 } 1709 1710 return 0; 1711} 1712 1713static int __orinoco_program_rids(struct net_device *dev) 1714{ 1715 struct orinoco_private *priv = netdev_priv(dev); 1716 hermes_t *hw = &priv->hw; 1717 int err; 1718 struct hermes_idstring idbuf; 1719 1720 /* Set the MAC address */ 1721 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 1722 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); 1723 if (err) { 1724 printk(KERN_ERR "%s: Error %d setting MAC address\n", 1725 dev->name, err); 1726 return err; 1727 } 1728 1729 /* Set up the link mode */ 1730 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, 1731 priv->port_type); 1732 if (err) { 1733 printk(KERN_ERR "%s: Error %d setting port type\n", 1734 dev->name, err); 1735 return err; 1736 } 1737 /* Set the channel/frequency */ 1738 if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) { 1739 err = hermes_write_wordrec(hw, USER_BAP, 1740 HERMES_RID_CNFOWNCHANNEL, 1741 priv->channel); 1742 if (err) { 1743 printk(KERN_ERR "%s: Error %d setting channel %d\n", 1744 dev->name, err, priv->channel); 1745 return err; 1746 } 1747 } 1748 1749 if (priv->has_ibss) { 1750 u16 createibss; 1751 1752 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) { 1753 printk(KERN_WARNING "%s: This firmware requires an " 1754 "ESSID in IBSS-Ad-Hoc mode.\n", dev->name); 1755 /* With wvlan_cs, in this case, we would crash. 1756 * hopefully, this driver will behave better... 1757 * Jean II */ 1758 createibss = 0; 1759 } else { 1760 createibss = priv->createibss; 1761 } 1762 1763 err = hermes_write_wordrec(hw, USER_BAP, 1764 HERMES_RID_CNFCREATEIBSS, 1765 createibss); 1766 if (err) { 1767 printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", 1768 dev->name, err); 1769 return err; 1770 } 1771 } 1772 1773 /* Set the desired BSSID */ 1774 err = __orinoco_hw_set_wap(priv); 1775 if (err) { 1776 printk(KERN_ERR "%s: Error %d setting AP address\n", 1777 dev->name, err); 1778 return err; 1779 } 1780 /* Set the desired ESSID */ 1781 idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); 1782 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); 1783 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ 1784 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, 1785 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 1786 &idbuf); 1787 if (err) { 1788 printk(KERN_ERR "%s: Error %d setting OWNSSID\n", 1789 dev->name, err); 1790 return err; 1791 } 1792 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, 1793 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 1794 &idbuf); 1795 if (err) { 1796 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n", 1797 dev->name, err); 1798 return err; 1799 } 1800 1801 /* Set the station name */ 1802 idbuf.len = cpu_to_le16(strlen(priv->nick)); 1803 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); 1804 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 1805 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), 1806 &idbuf); 1807 if (err) { 1808 printk(KERN_ERR "%s: Error %d setting nickname\n", 1809 dev->name, err); 1810 return err; 1811 } 1812 1813 /* Set AP density */ 1814 if (priv->has_sensitivity) { 1815 err = hermes_write_wordrec(hw, USER_BAP, 1816 HERMES_RID_CNFSYSTEMSCALE, 1817 priv->ap_density); 1818 if (err) { 1819 printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. " 1820 "Disabling sensitivity control\n", 1821 dev->name, err); 1822 1823 priv->has_sensitivity = 0; 1824 } 1825 } 1826 1827 /* Set RTS threshold */ 1828 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, 1829 priv->rts_thresh); 1830 if (err) { 1831 printk(KERN_ERR "%s: Error %d setting RTS threshold\n", 1832 dev->name, err); 1833 return err; 1834 } 1835 1836 /* Set fragmentation threshold or MWO robustness */ 1837 if (priv->has_mwo) 1838 err = hermes_write_wordrec(hw, USER_BAP, 1839 HERMES_RID_CNFMWOROBUST_AGERE, 1840 priv->mwo_robust); 1841 else 1842 err = hermes_write_wordrec(hw, USER_BAP, 1843 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, 1844 priv->frag_thresh); 1845 if (err) { 1846 printk(KERN_ERR "%s: Error %d setting fragmentation\n", 1847 dev->name, err); 1848 return err; 1849 } 1850 1851 /* Set bitrate */ 1852 err = __orinoco_hw_set_bitrate(priv); 1853 if (err) { 1854 printk(KERN_ERR "%s: Error %d setting bitrate\n", 1855 dev->name, err); 1856 return err; 1857 } 1858 1859 /* Set power management */ 1860 if (priv->has_pm) { 1861 err = hermes_write_wordrec(hw, USER_BAP, 1862 HERMES_RID_CNFPMENABLED, 1863 priv->pm_on); 1864 if (err) { 1865 printk(KERN_ERR "%s: Error %d setting up PM\n", 1866 dev->name, err); 1867 return err; 1868 } 1869 1870 err = hermes_write_wordrec(hw, USER_BAP, 1871 HERMES_RID_CNFMULTICASTRECEIVE, 1872 priv->pm_mcast); 1873 if (err) { 1874 printk(KERN_ERR "%s: Error %d setting up PM\n", 1875 dev->name, err); 1876 return err; 1877 } 1878 err = hermes_write_wordrec(hw, USER_BAP, 1879 HERMES_RID_CNFMAXSLEEPDURATION, 1880 priv->pm_period); 1881 if (err) { 1882 printk(KERN_ERR "%s: Error %d setting up PM\n", 1883 dev->name, err); 1884 return err; 1885 } 1886 err = hermes_write_wordrec(hw, USER_BAP, 1887 HERMES_RID_CNFPMHOLDOVERDURATION, 1888 priv->pm_timeout); 1889 if (err) { 1890 printk(KERN_ERR "%s: Error %d setting up PM\n", 1891 dev->name, err); 1892 return err; 1893 } 1894 } 1895 1896 /* Set preamble - only for Symbol so far... */ 1897 if (priv->has_preamble) { 1898 err = hermes_write_wordrec(hw, USER_BAP, 1899 HERMES_RID_CNFPREAMBLE_SYMBOL, 1900 priv->preamble); 1901 if (err) { 1902 printk(KERN_ERR "%s: Error %d setting preamble\n", 1903 dev->name, err); 1904 return err; 1905 } 1906 } 1907 1908 /* Set up encryption */ 1909 if (priv->has_wep) { 1910 err = __orinoco_hw_setup_wep(priv); 1911 if (err) { 1912 printk(KERN_ERR "%s: Error %d activating WEP\n", 1913 dev->name, err); 1914 return err; 1915 } 1916 } 1917 1918 if (priv->iw_mode == IW_MODE_MONITOR) { 1919 /* Enable monitor mode */ 1920 dev->type = ARPHRD_IEEE80211; 1921 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 1922 HERMES_TEST_MONITOR, 0, NULL); 1923 } else { 1924 /* Disable monitor mode */ 1925 dev->type = ARPHRD_ETHER; 1926 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 1927 HERMES_TEST_STOP, 0, NULL); 1928 } 1929 if (err) 1930 return err; 1931 1932 /* Set promiscuity / multicast*/ 1933 priv->promiscuous = 0; 1934 priv->mc_count = 0; 1935 1936 /* FIXME: what about netif_tx_lock */ 1937 __orinoco_set_multicast_list(dev); 1938 1939 return 0; 1940} 1941 1942/* FIXME: return int? */ 1943static void 1944__orinoco_set_multicast_list(struct net_device *dev) 1945{ 1946 struct orinoco_private *priv = netdev_priv(dev); 1947 hermes_t *hw = &priv->hw; 1948 int err = 0; 1949 int promisc, mc_count; 1950 1951 /* The Hermes doesn't seem to have an allmulti mode, so we go 1952 * into promiscuous mode and let the upper levels deal. */ 1953 if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) || 1954 (dev->mc_count > MAX_MULTICAST(priv)) ) { 1955 promisc = 1; 1956 mc_count = 0; 1957 } else { 1958 promisc = 0; 1959 mc_count = dev->mc_count; 1960 } 1961 1962 if (promisc != priv->promiscuous) { 1963 err = hermes_write_wordrec(hw, USER_BAP, 1964 HERMES_RID_CNFPROMISCUOUSMODE, 1965 promisc); 1966 if (err) { 1967 printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n", 1968 dev->name, err); 1969 } else 1970 priv->promiscuous = promisc; 1971 } 1972 1973 if (! promisc && (mc_count || priv->mc_count) ) { 1974 struct dev_mc_list *p = dev->mc_list; 1975 struct hermes_multicast mclist; 1976 int i; 1977 1978 for (i = 0; i < mc_count; i++) { 1979 /* paranoia: is list shorter than mc_count? */ 1980 BUG_ON(! p); 1981 /* paranoia: bad address size in list? */ 1982 BUG_ON(p->dmi_addrlen != ETH_ALEN); 1983 1984 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN); 1985 p = p->next; 1986 } 1987 1988 if (p) 1989 printk(KERN_WARNING "%s: Multicast list is " 1990 "longer than mc_count\n", dev->name); 1991 1992 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES, 1993 HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN), 1994 &mclist); 1995 if (err) 1996 printk(KERN_ERR "%s: Error %d setting multicast list.\n", 1997 dev->name, err); 1998 else 1999 priv->mc_count = mc_count; 2000 } 2001 2002 /* Since we can set the promiscuous flag when it wasn't asked 2003 for, make sure the net_device knows about it. */ 2004 if (priv->promiscuous) 2005 dev->flags |= IFF_PROMISC; 2006 else 2007 dev->flags &= ~IFF_PROMISC; 2008} 2009 2010/* This must be called from user context, without locks held - use 2011 * schedule_work() */ 2012static void orinoco_reset(struct work_struct *work) 2013{ 2014 struct orinoco_private *priv = 2015 container_of(work, struct orinoco_private, reset_work); 2016 struct net_device *dev = priv->ndev; 2017 struct hermes *hw = &priv->hw; 2018 int err; 2019 unsigned long flags; 2020 2021 if (orinoco_lock(priv, &flags) != 0) 2022 /* When the hardware becomes available again, whatever 2023 * detects that is responsible for re-initializing 2024 * it. So no need for anything further */ 2025 return; 2026 2027 netif_stop_queue(dev); 2028 2029 /* Shut off interrupts. Depending on what state the hardware 2030 * is in, this might not work, but we'll try anyway */ 2031 hermes_set_irqmask(hw, 0); 2032 hermes_write_regn(hw, EVACK, 0xffff); 2033 2034 priv->hw_unavailable++; 2035 priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */ 2036 netif_carrier_off(dev); 2037 2038 orinoco_unlock(priv, &flags); 2039 2040 /* Scanning support: Cleanup of driver struct */ 2041 orinoco_clear_scan_results(priv, 0); 2042 priv->scan_inprogress = 0; 2043 2044 if (priv->hard_reset) { 2045 err = (*priv->hard_reset)(priv); 2046 if (err) { 2047 printk(KERN_ERR "%s: orinoco_reset: Error %d " 2048 "performing hard reset\n", dev->name, err); 2049 goto disable; 2050 } 2051 } 2052 2053 err = orinoco_reinit_firmware(dev); 2054 if (err) { 2055 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", 2056 dev->name, err); 2057 goto disable; 2058 } 2059 2060 spin_lock_irq(&priv->lock); /* This has to be called from user context */ 2061 2062 priv->hw_unavailable--; 2063 2064 /* priv->open or priv->hw_unavailable might have changed while 2065 * we dropped the lock */ 2066 if (priv->open && (! priv->hw_unavailable)) { 2067 err = __orinoco_up(dev); 2068 if (err) { 2069 printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n", 2070 dev->name, err); 2071 } else 2072 dev->trans_start = jiffies; 2073 } 2074 2075 spin_unlock_irq(&priv->lock); 2076 2077 return; 2078 disable: 2079 hermes_set_irqmask(hw, 0); 2080 netif_device_detach(dev); 2081 printk(KERN_ERR "%s: Device has been disabled!\n", dev->name); 2082} 2083 2084/********************************************************************/ 2085/* Interrupt handler */ 2086/********************************************************************/ 2087 2088static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw) 2089{ 2090 printk(KERN_DEBUG "%s: TICK\n", dev->name); 2091} 2092 2093static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw) 2094{ 2095 /* This seems to happen a fair bit under load, but ignoring it 2096 seems to work fine...*/ 2097 printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n", 2098 dev->name); 2099} 2100 2101irqreturn_t orinoco_interrupt(int irq, void *dev_id) 2102{ 2103 struct net_device *dev = dev_id; 2104 struct orinoco_private *priv = netdev_priv(dev); 2105 hermes_t *hw = &priv->hw; 2106 int count = MAX_IRQLOOPS_PER_IRQ; 2107 u16 evstat, events; 2108 /* These are used to detect a runaway interrupt situation */ 2109 /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy, 2110 * we panic and shut down the hardware */ 2111 static int last_irq_jiffy = 0; /* jiffies value the last time 2112 * we were called */ 2113 static int loops_this_jiffy = 0; 2114 unsigned long flags; 2115 2116 if (orinoco_lock(priv, &flags) != 0) { 2117 /* If hw is unavailable - we don't know if the irq was 2118 * for us or not */ 2119 return IRQ_HANDLED; 2120 } 2121 2122 evstat = hermes_read_regn(hw, EVSTAT); 2123 events = evstat & hw->inten; 2124 if (! events) { 2125 orinoco_unlock(priv, &flags); 2126 return IRQ_NONE; 2127 } 2128 2129 if (jiffies != last_irq_jiffy) 2130 loops_this_jiffy = 0; 2131 last_irq_jiffy = jiffies; 2132 2133 while (events && count--) { 2134 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) { 2135 printk(KERN_WARNING "%s: IRQ handler is looping too " 2136 "much! Resetting.\n", dev->name); 2137 /* Disable interrupts for now */ 2138 hermes_set_irqmask(hw, 0); 2139 schedule_work(&priv->reset_work); 2140 break; 2141 } 2142 2143 /* Check the card hasn't been removed */ 2144 if (! hermes_present(hw)) { 2145 DEBUG(0, "orinoco_interrupt(): card removed\n"); 2146 break; 2147 } 2148 2149 if (events & HERMES_EV_TICK) 2150 __orinoco_ev_tick(dev, hw); 2151 if (events & HERMES_EV_WTERR) 2152 __orinoco_ev_wterr(dev, hw); 2153 if (events & HERMES_EV_INFDROP) 2154 __orinoco_ev_infdrop(dev, hw); 2155 if (events & HERMES_EV_INFO) 2156 __orinoco_ev_info(dev, hw); 2157 if (events & HERMES_EV_RX) 2158 __orinoco_ev_rx(dev, hw); 2159 if (events & HERMES_EV_TXEXC) 2160 __orinoco_ev_txexc(dev, hw); 2161 if (events & HERMES_EV_TX) 2162 __orinoco_ev_tx(dev, hw); 2163 if (events & HERMES_EV_ALLOC) 2164 __orinoco_ev_alloc(dev, hw); 2165 2166 hermes_write_regn(hw, EVACK, evstat); 2167 2168 evstat = hermes_read_regn(hw, EVSTAT); 2169 events = evstat & hw->inten; 2170 }; 2171 2172 orinoco_unlock(priv, &flags); 2173 return IRQ_HANDLED; 2174} 2175 2176/********************************************************************/ 2177/* Initialization */ 2178/********************************************************************/ 2179 2180struct comp_id { 2181 u16 id, variant, major, minor; 2182} __attribute__ ((packed)); 2183 2184static inline fwtype_t determine_firmware_type(struct comp_id *nic_id) 2185{ 2186 if (nic_id->id < 0x8000) 2187 return FIRMWARE_TYPE_AGERE; 2188 else if (nic_id->id == 0x8000 && nic_id->major == 0) 2189 return FIRMWARE_TYPE_SYMBOL; 2190 else 2191 return FIRMWARE_TYPE_INTERSIL; 2192} 2193 2194/* Set priv->firmware type, determine firmware properties */ 2195static int determine_firmware(struct net_device *dev) 2196{ 2197 struct orinoco_private *priv = netdev_priv(dev); 2198 hermes_t *hw = &priv->hw; 2199 int err; 2200 struct comp_id nic_id, sta_id; 2201 unsigned int firmver; 2202 char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2))); 2203 2204 /* Get the hardware version */ 2205 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id); 2206 if (err) { 2207 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n", 2208 dev->name, err); 2209 return err; 2210 } 2211 2212 le16_to_cpus(&nic_id.id); 2213 le16_to_cpus(&nic_id.variant); 2214 le16_to_cpus(&nic_id.major); 2215 le16_to_cpus(&nic_id.minor); 2216 printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n", 2217 dev->name, nic_id.id, nic_id.variant, 2218 nic_id.major, nic_id.minor); 2219 2220 priv->firmware_type = determine_firmware_type(&nic_id); 2221 2222 /* Get the firmware version */ 2223 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id); 2224 if (err) { 2225 printk(KERN_ERR "%s: Cannot read station identity: error %d\n", 2226 dev->name, err); 2227 return err; 2228 } 2229 2230 le16_to_cpus(&sta_id.id); 2231 le16_to_cpus(&sta_id.variant); 2232 le16_to_cpus(&sta_id.major); 2233 le16_to_cpus(&sta_id.minor); 2234 printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n", 2235 dev->name, sta_id.id, sta_id.variant, 2236 sta_id.major, sta_id.minor); 2237 2238 switch (sta_id.id) { 2239 case 0x15: 2240 printk(KERN_ERR "%s: Primary firmware is active\n", 2241 dev->name); 2242 return -ENODEV; 2243 case 0x14b: 2244 printk(KERN_ERR "%s: Tertiary firmware is active\n", 2245 dev->name); 2246 return -ENODEV; 2247 case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */ 2248 case 0x21: /* Symbol Spectrum24 Trilogy */ 2249 break; 2250 default: 2251 printk(KERN_NOTICE "%s: Unknown station ID, please report\n", 2252 dev->name); 2253 break; 2254 } 2255 2256 /* Default capabilities */ 2257 priv->has_sensitivity = 1; 2258 priv->has_mwo = 0; 2259 priv->has_preamble = 0; 2260 priv->has_port3 = 1; 2261 priv->has_ibss = 1; 2262 priv->has_wep = 0; 2263 priv->has_big_wep = 0; 2264 2265 /* Determine capabilities from the firmware version */ 2266 switch (priv->firmware_type) { 2267 case FIRMWARE_TYPE_AGERE: 2268 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout, 2269 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */ 2270 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 2271 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor); 2272 2273 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor; 2274 2275 priv->has_ibss = (firmver >= 0x60006); 2276 priv->has_wep = (firmver >= 0x40020); 2277 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell 2278 Gold cards from the others? */ 2279 priv->has_mwo = (firmver >= 0x60000); 2280 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */ 2281 priv->ibss_port = 1; 2282 priv->has_hostscan = (firmver >= 0x8000a); 2283 priv->broken_monitor = (firmver >= 0x80000); 2284 2285 /* Tested with Agere firmware : 2286 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II 2287 * Tested CableTron firmware : 4.32 => Anton */ 2288 break; 2289 case FIRMWARE_TYPE_SYMBOL: 2290 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */ 2291 /* Intel MAC : 00:02:B3:* */ 2292 /* 3Com MAC : 00:50:DA:* */ 2293 memset(tmp, 0, sizeof(tmp)); 2294 /* Get the Symbol firmware version */ 2295 err = hermes_read_ltv(hw, USER_BAP, 2296 HERMES_RID_SECONDARYVERSION_SYMBOL, 2297 SYMBOL_MAX_VER_LEN, NULL, &tmp); 2298 if (err) { 2299 printk(KERN_WARNING 2300 "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n", 2301 dev->name, err); 2302 firmver = 0; 2303 tmp[0] = '\0'; 2304 } else { 2305 /* The firmware revision is a string, the format is 2306 * something like : "V2.20-01". 2307 * Quick and dirty parsing... - Jean II 2308 */ 2309 firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12) 2310 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4) 2311 | (tmp[7] - '0'); 2312 2313 tmp[SYMBOL_MAX_VER_LEN] = '\0'; 2314 } 2315 2316 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 2317 "Symbol %s", tmp); 2318 2319 priv->has_ibss = (firmver >= 0x20000); 2320 priv->has_wep = (firmver >= 0x15012); 2321 priv->has_big_wep = (firmver >= 0x20000); 2322 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 2323 (firmver >= 0x29000 && firmver < 0x30000) || 2324 firmver >= 0x31000; 2325 priv->has_preamble = (firmver >= 0x20000); 2326 priv->ibss_port = 4; 2327 priv->broken_disableport = (firmver == 0x25013) || 2328 (firmver >= 0x30000 && firmver <= 0x31000); 2329 priv->has_hostscan = (firmver >= 0x31001) || 2330 (firmver >= 0x29057 && firmver < 0x30000); 2331 /* Tested with Intel firmware : 0x20015 => Jean II */ 2332 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ 2333 break; 2334 case FIRMWARE_TYPE_INTERSIL: 2335 /* D-Link, Linksys, Adtron, ZoomAir, and many others... 2336 * Samsung, Compaq 100/200 and Proxim are slightly 2337 * different and less well tested */ 2338 /* D-Link MAC : 00:40:05:* */ 2339 /* Addtron MAC : 00:90:D1:* */ 2340 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 2341 "Intersil %d.%d.%d", sta_id.major, sta_id.minor, 2342 sta_id.variant); 2343 2344 firmver = ((unsigned long)sta_id.major << 16) | 2345 ((unsigned long)sta_id.minor << 8) | sta_id.variant; 2346 2347 priv->has_ibss = (firmver >= 0x000700); /* FIXME */ 2348 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800); 2349 priv->has_pm = (firmver >= 0x000700); 2350 priv->has_hostscan = (firmver >= 0x010301); 2351 2352 if (firmver >= 0x000800) 2353 priv->ibss_port = 0; 2354 else { 2355 printk(KERN_NOTICE "%s: Intersil firmware earlier " 2356 "than v0.8.x - several features not supported\n", 2357 dev->name); 2358 priv->ibss_port = 1; 2359 } 2360 break; 2361 } 2362 printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name, 2363 priv->fw_name); 2364 2365 return 0; 2366} 2367 2368static int orinoco_init(struct net_device *dev) 2369{ 2370 struct orinoco_private *priv = netdev_priv(dev); 2371 hermes_t *hw = &priv->hw; 2372 int err = 0; 2373 struct hermes_idstring nickbuf; 2374 u16 reclen; 2375 int len; 2376 DECLARE_MAC_BUF(mac); 2377 2378 /* No need to lock, the hw_unavailable flag is already set in 2379 * alloc_orinocodev() */ 2380 priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN; 2381 2382 /* Initialize the firmware */ 2383 err = hermes_init(hw); 2384 if (err != 0) { 2385 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", 2386 dev->name, err); 2387 goto out; 2388 } 2389 2390 err = determine_firmware(dev); 2391 if (err != 0) { 2392 printk(KERN_ERR "%s: Incompatible firmware, aborting\n", 2393 dev->name); 2394 goto out; 2395 } 2396 2397 if (priv->has_port3) 2398 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name); 2399 if (priv->has_ibss) 2400 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n", 2401 dev->name); 2402 if (priv->has_wep) { 2403 printk(KERN_DEBUG "%s: WEP supported, ", dev->name); 2404 if (priv->has_big_wep) 2405 printk("104-bit key\n"); 2406 else 2407 printk("40-bit key\n"); 2408 } 2409 2410 /* Get the MAC address */ 2411 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 2412 ETH_ALEN, NULL, dev->dev_addr); 2413 if (err) { 2414 printk(KERN_WARNING "%s: failed to read MAC address!\n", 2415 dev->name); 2416 goto out; 2417 } 2418 2419 printk(KERN_DEBUG "%s: MAC address %s\n", 2420 dev->name, print_mac(mac, dev->dev_addr)); 2421 2422 /* Get the station name */ 2423 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 2424 sizeof(nickbuf), &reclen, &nickbuf); 2425 if (err) { 2426 printk(KERN_ERR "%s: failed to read station name\n", 2427 dev->name); 2428 goto out; 2429 } 2430 if (nickbuf.len) 2431 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len)); 2432 else 2433 len = min(IW_ESSID_MAX_SIZE, 2 * reclen); 2434 memcpy(priv->nick, &nickbuf.val, len); 2435 priv->nick[len] = '\0'; 2436 2437 printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick); 2438 2439 err = orinoco_allocate_fid(dev); 2440 if (err) { 2441 printk(KERN_ERR "%s: failed to allocate NIC buffer!\n", 2442 dev->name); 2443 goto out; 2444 } 2445 2446 /* Get allowed channels */ 2447 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST, 2448 &priv->channel_mask); 2449 if (err) { 2450 printk(KERN_ERR "%s: failed to read channel list!\n", 2451 dev->name); 2452 goto out; 2453 } 2454 2455 /* Get initial AP density */ 2456 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, 2457 &priv->ap_density); 2458 if (err || priv->ap_density < 1 || priv->ap_density > 3) { 2459 priv->has_sensitivity = 0; 2460 } 2461 2462 /* Get initial RTS threshold */ 2463 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, 2464 &priv->rts_thresh); 2465 if (err) { 2466 printk(KERN_ERR "%s: failed to read RTS threshold!\n", 2467 dev->name); 2468 goto out; 2469 } 2470 2471 /* Get initial fragmentation settings */ 2472 if (priv->has_mwo) 2473 err = hermes_read_wordrec(hw, USER_BAP, 2474 HERMES_RID_CNFMWOROBUST_AGERE, 2475 &priv->mwo_robust); 2476 else 2477 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, 2478 &priv->frag_thresh); 2479 if (err) { 2480 printk(KERN_ERR "%s: failed to read fragmentation settings!\n", 2481 dev->name); 2482 goto out; 2483 } 2484 2485 /* Power management setup */ 2486 if (priv->has_pm) { 2487 priv->pm_on = 0; 2488 priv->pm_mcast = 1; 2489 err = hermes_read_wordrec(hw, USER_BAP, 2490 HERMES_RID_CNFMAXSLEEPDURATION, 2491 &priv->pm_period); 2492 if (err) { 2493 printk(KERN_ERR "%s: failed to read power management period!\n", 2494 dev->name); 2495 goto out; 2496 } 2497 err = hermes_read_wordrec(hw, USER_BAP, 2498 HERMES_RID_CNFPMHOLDOVERDURATION, 2499 &priv->pm_timeout); 2500 if (err) { 2501 printk(KERN_ERR "%s: failed to read power management timeout!\n", 2502 dev->name); 2503 goto out; 2504 } 2505 } 2506 2507 /* Preamble setup */ 2508 if (priv->has_preamble) { 2509 err = hermes_read_wordrec(hw, USER_BAP, 2510 HERMES_RID_CNFPREAMBLE_SYMBOL, 2511 &priv->preamble); 2512 if (err) 2513 goto out; 2514 } 2515 2516 /* Set up the default configuration */ 2517 priv->iw_mode = IW_MODE_INFRA; 2518 /* By default use IEEE/IBSS ad-hoc mode if we have it */ 2519 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); 2520 set_port_type(priv); 2521 priv->channel = 0; /* use firmware default */ 2522 2523 priv->promiscuous = 0; 2524 priv->wep_on = 0; 2525 priv->tx_key = 0; 2526 2527 /* Make the hardware available, as long as it hasn't been 2528 * removed elsewhere (e.g. by PCMCIA hot unplug) */ 2529 spin_lock_irq(&priv->lock); 2530 priv->hw_unavailable--; 2531 spin_unlock_irq(&priv->lock); 2532 2533 printk(KERN_DEBUG "%s: ready\n", dev->name); 2534 2535 out: 2536 return err; 2537} 2538 2539struct net_device *alloc_orinocodev(int sizeof_card, 2540 int (*hard_reset)(struct orinoco_private *)) 2541{ 2542 struct net_device *dev; 2543 struct orinoco_private *priv; 2544 2545 dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card); 2546 if (! dev) 2547 return NULL; 2548 priv = netdev_priv(dev); 2549 priv->ndev = dev; 2550 if (sizeof_card) 2551 priv->card = (void *)((unsigned long)priv 2552 + sizeof(struct orinoco_private)); 2553 else 2554 priv->card = NULL; 2555 2556 if (orinoco_bss_data_allocate(priv)) 2557 goto err_out_free; 2558 orinoco_bss_data_init(priv); 2559 2560 /* Setup / override net_device fields */ 2561 dev->init = orinoco_init; 2562 dev->hard_start_xmit = orinoco_xmit; 2563 dev->tx_timeout = orinoco_tx_timeout; 2564 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2565 dev->get_stats = orinoco_get_stats; 2566 dev->ethtool_ops = &orinoco_ethtool_ops; 2567 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; 2568#ifdef WIRELESS_SPY 2569 priv->wireless_data.spy_data = &priv->spy_data; 2570 dev->wireless_data = &priv->wireless_data; 2571#endif 2572 dev->change_mtu = orinoco_change_mtu; 2573 dev->set_multicast_list = orinoco_set_multicast_list; 2574 /* we use the default eth_mac_addr for setting the MAC addr */ 2575 2576 /* Set up default callbacks */ 2577 dev->open = orinoco_open; 2578 dev->stop = orinoco_stop; 2579 priv->hard_reset = hard_reset; 2580 2581 spin_lock_init(&priv->lock); 2582 priv->open = 0; 2583 priv->hw_unavailable = 1; /* orinoco_init() must clear this 2584 * before anything else touches the 2585 * hardware */ 2586 INIT_WORK(&priv->reset_work, orinoco_reset); 2587 INIT_WORK(&priv->join_work, orinoco_join_ap); 2588 INIT_WORK(&priv->wevent_work, orinoco_send_wevents); 2589 2590 netif_carrier_off(dev); 2591 priv->last_linkstatus = 0xffff; 2592 2593 return dev; 2594 2595err_out_free: 2596 free_netdev(dev); 2597 return NULL; 2598} 2599 2600void free_orinocodev(struct net_device *dev) 2601{ 2602 struct orinoco_private *priv = netdev_priv(dev); 2603 2604 orinoco_bss_data_free(priv); 2605 free_netdev(dev); 2606} 2607 2608/********************************************************************/ 2609/* Wireless extensions */ 2610/********************************************************************/ 2611 2612/* Return : < 0 -> error code ; >= 0 -> length */ 2613static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, 2614 char buf[IW_ESSID_MAX_SIZE+1]) 2615{ 2616 hermes_t *hw = &priv->hw; 2617 int err = 0; 2618 struct hermes_idstring essidbuf; 2619 char *p = (char *)(&essidbuf.val); 2620 int len; 2621 unsigned long flags; 2622 2623 if (orinoco_lock(priv, &flags) != 0) 2624 return -EBUSY; 2625 2626 if (strlen(priv->desired_essid) > 0) { 2627 /* We read the desired SSID from the hardware rather 2628 than from priv->desired_essid, just in case the 2629 firmware is allowed to change it on us. I'm not 2630 sure about this */ 2631 /* My guess is that the OWNSSID should always be whatever 2632 * we set to the card, whereas CURRENT_SSID is the one that 2633 * may change... - Jean II */ 2634 u16 rid; 2635 2636 *active = 1; 2637 2638 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : 2639 HERMES_RID_CNFDESIREDSSID; 2640 2641 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), 2642 NULL, &essidbuf); 2643 if (err) 2644 goto fail_unlock; 2645 } else { 2646 *active = 0; 2647 2648 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, 2649 sizeof(essidbuf), NULL, &essidbuf); 2650 if (err) 2651 goto fail_unlock; 2652 } 2653 2654 len = le16_to_cpu(essidbuf.len); 2655 BUG_ON(len > IW_ESSID_MAX_SIZE); 2656 2657 memset(buf, 0, IW_ESSID_MAX_SIZE); 2658 memcpy(buf, p, len); 2659 err = len; 2660 2661 fail_unlock: 2662 orinoco_unlock(priv, &flags); 2663 2664 return err; 2665} 2666 2667static long orinoco_hw_get_freq(struct orinoco_private *priv) 2668{ 2669 2670 hermes_t *hw = &priv->hw; 2671 int err = 0; 2672 u16 channel; 2673 long freq = 0; 2674 unsigned long flags; 2675 2676 if (orinoco_lock(priv, &flags) != 0) 2677 return -EBUSY; 2678 2679 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel); 2680 if (err) 2681 goto out; 2682 2683 /* Intersil firmware 1.3.5 returns 0 when the interface is down */ 2684 if (channel == 0) { 2685 err = -EBUSY; 2686 goto out; 2687 } 2688 2689 if ( (channel < 1) || (channel > NUM_CHANNELS) ) { 2690 printk(KERN_WARNING "%s: Channel out of range (%d)!\n", 2691 priv->ndev->name, channel); 2692 err = -EBUSY; 2693 goto out; 2694 2695 } 2696 freq = channel_frequency[channel-1] * 100000; 2697 2698 out: 2699 orinoco_unlock(priv, &flags); 2700 2701 if (err > 0) 2702 err = -EBUSY; 2703 return err ? err : freq; 2704} 2705 2706static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, 2707 int *numrates, s32 *rates, int max) 2708{ 2709 hermes_t *hw = &priv->hw; 2710 struct hermes_idstring list; 2711 unsigned char *p = (unsigned char *)&list.val; 2712 int err = 0; 2713 int num; 2714 int i; 2715 unsigned long flags; 2716 2717 if (orinoco_lock(priv, &flags) != 0) 2718 return -EBUSY; 2719 2720 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, 2721 sizeof(list), NULL, &list); 2722 orinoco_unlock(priv, &flags); 2723 2724 if (err) 2725 return err; 2726 2727 num = le16_to_cpu(list.len); 2728 *numrates = num; 2729 num = min(num, max); 2730 2731 for (i = 0; i < num; i++) { 2732 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */ 2733 } 2734 2735 return 0; 2736} 2737 2738static int orinoco_ioctl_getname(struct net_device *dev, 2739 struct iw_request_info *info, 2740 char *name, 2741 char *extra) 2742{ 2743 struct orinoco_private *priv = netdev_priv(dev); 2744 int numrates; 2745 int err; 2746 2747 err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0); 2748 2749 if (!err && (numrates > 2)) 2750 strcpy(name, "IEEE 802.11b"); 2751 else 2752 strcpy(name, "IEEE 802.11-DS"); 2753 2754 return 0; 2755} 2756 2757static int orinoco_ioctl_setwap(struct net_device *dev, 2758 struct iw_request_info *info, 2759 struct sockaddr *ap_addr, 2760 char *extra) 2761{ 2762 struct orinoco_private *priv = netdev_priv(dev); 2763 int err = -EINPROGRESS; /* Call commit handler */ 2764 unsigned long flags; 2765 static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 2766 static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2767 2768 if (orinoco_lock(priv, &flags) != 0) 2769 return -EBUSY; 2770 2771 /* Enable automatic roaming - no sanity checks are needed */ 2772 if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 || 2773 memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) { 2774 priv->bssid_fixed = 0; 2775 memset(priv->desired_bssid, 0, ETH_ALEN); 2776 2777 /* "off" means keep existing connection */ 2778 if (ap_addr->sa_data[0] == 0) { 2779 __orinoco_hw_set_wap(priv); 2780 err = 0; 2781 } 2782 goto out; 2783 } 2784 2785 if (priv->firmware_type == FIRMWARE_TYPE_AGERE) { 2786 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't " 2787 "support manual roaming\n", 2788 dev->name); 2789 err = -EOPNOTSUPP; 2790 goto out; 2791 } 2792 2793 if (priv->iw_mode != IW_MODE_INFRA) { 2794 printk(KERN_WARNING "%s: Manual roaming supported only in " 2795 "managed mode\n", dev->name); 2796 err = -EOPNOTSUPP; 2797 goto out; 2798 } 2799 2800 /* Intersil firmware hangs without Desired ESSID */ 2801 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL && 2802 strlen(priv->desired_essid) == 0) { 2803 printk(KERN_WARNING "%s: Desired ESSID must be set for " 2804 "manual roaming\n", dev->name); 2805 err = -EOPNOTSUPP; 2806 goto out; 2807 } 2808 2809 /* Finally, enable manual roaming */ 2810 priv->bssid_fixed = 1; 2811 memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN); 2812 2813 out: 2814 orinoco_unlock(priv, &flags); 2815 return err; 2816} 2817 2818static int orinoco_ioctl_getwap(struct net_device *dev, 2819 struct iw_request_info *info, 2820 struct sockaddr *ap_addr, 2821 char *extra) 2822{ 2823 struct orinoco_private *priv = netdev_priv(dev); 2824 2825 hermes_t *hw = &priv->hw; 2826 int err = 0; 2827 unsigned long flags; 2828 2829 if (orinoco_lock(priv, &flags) != 0) 2830 return -EBUSY; 2831 2832 ap_addr->sa_family = ARPHRD_ETHER; 2833 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, 2834 ETH_ALEN, NULL, ap_addr->sa_data); 2835 2836 orinoco_unlock(priv, &flags); 2837 2838 return err; 2839} 2840 2841static int orinoco_ioctl_setmode(struct net_device *dev, 2842 struct iw_request_info *info, 2843 u32 *mode, 2844 char *extra) 2845{ 2846 struct orinoco_private *priv = netdev_priv(dev); 2847 int err = -EINPROGRESS; /* Call commit handler */ 2848 unsigned long flags; 2849 2850 if (priv->iw_mode == *mode) 2851 return 0; 2852 2853 if (orinoco_lock(priv, &flags) != 0) 2854 return -EBUSY; 2855 2856 switch (*mode) { 2857 case IW_MODE_ADHOC: 2858 if (!priv->has_ibss && !priv->has_port3) 2859 err = -EOPNOTSUPP; 2860 break; 2861 2862 case IW_MODE_INFRA: 2863 break; 2864 2865 case IW_MODE_MONITOR: 2866 if (priv->broken_monitor && !force_monitor) { 2867 printk(KERN_WARNING "%s: Monitor mode support is " 2868 "buggy in this firmware, not enabling\n", 2869 dev->name); 2870 err = -EOPNOTSUPP; 2871 } 2872 break; 2873 2874 default: 2875 err = -EOPNOTSUPP; 2876 break; 2877 } 2878 2879 if (err == -EINPROGRESS) { 2880 priv->iw_mode = *mode; 2881 set_port_type(priv); 2882 } 2883 2884 orinoco_unlock(priv, &flags); 2885 2886 return err; 2887} 2888 2889static int orinoco_ioctl_getmode(struct net_device *dev, 2890 struct iw_request_info *info, 2891 u32 *mode, 2892 char *extra) 2893{ 2894 struct orinoco_private *priv = netdev_priv(dev); 2895 2896 *mode = priv->iw_mode; 2897 return 0; 2898} 2899 2900static int orinoco_ioctl_getiwrange(struct net_device *dev, 2901 struct iw_request_info *info, 2902 struct iw_point *rrq, 2903 char *extra) 2904{ 2905 struct orinoco_private *priv = netdev_priv(dev); 2906 int err = 0; 2907 struct iw_range *range = (struct iw_range *) extra; 2908 int numrates; 2909 int i, k; 2910 2911 rrq->length = sizeof(struct iw_range); 2912 memset(range, 0, sizeof(struct iw_range)); 2913 2914 range->we_version_compiled = WIRELESS_EXT; 2915 range->we_version_source = 14; 2916 2917 /* Set available channels/frequencies */ 2918 range->num_channels = NUM_CHANNELS; 2919 k = 0; 2920 for (i = 0; i < NUM_CHANNELS; i++) { 2921 if (priv->channel_mask & (1 << i)) { 2922 range->freq[k].i = i + 1; 2923 range->freq[k].m = channel_frequency[i] * 100000; 2924 range->freq[k].e = 1; 2925 k++; 2926 } 2927 2928 if (k >= IW_MAX_FREQUENCIES) 2929 break; 2930 } 2931 range->num_frequency = k; 2932 range->sensitivity = 3; 2933 2934 if (priv->has_wep) { 2935 range->max_encoding_tokens = ORINOCO_MAX_KEYS; 2936 range->encoding_size[0] = SMALL_KEY_SIZE; 2937 range->num_encoding_sizes = 1; 2938 2939 if (priv->has_big_wep) { 2940 range->encoding_size[1] = LARGE_KEY_SIZE; 2941 range->num_encoding_sizes = 2; 2942 } 2943 } 2944 2945 if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){ 2946 /* Quality stats meaningless in ad-hoc mode */ 2947 } else { 2948 range->max_qual.qual = 0x8b - 0x2f; 2949 range->max_qual.level = 0x2f - 0x95 - 1; 2950 range->max_qual.noise = 0x2f - 0x95 - 1; 2951 /* Need to get better values */ 2952 range->avg_qual.qual = 0x24; 2953 range->avg_qual.level = 0xC2; 2954 range->avg_qual.noise = 0x9E; 2955 } 2956 2957 err = orinoco_hw_get_bitratelist(priv, &numrates, 2958 range->bitrate, IW_MAX_BITRATES); 2959 if (err) 2960 return err; 2961 range->num_bitrates = numrates; 2962 2963 /* Set an indication of the max TCP throughput in bit/s that we can 2964 * expect using this interface. May be use for QoS stuff... 2965 * Jean II */ 2966 if (numrates > 2) 2967 range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */ 2968 else 2969 range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */ 2970 2971 range->min_rts = 0; 2972 range->max_rts = 2347; 2973 range->min_frag = 256; 2974 range->max_frag = 2346; 2975 2976 range->min_pmp = 0; 2977 range->max_pmp = 65535000; 2978 range->min_pmt = 0; 2979 range->max_pmt = 65535 * 1000; /* ??? */ 2980 range->pmp_flags = IW_POWER_PERIOD; 2981 range->pmt_flags = IW_POWER_TIMEOUT; 2982 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R; 2983 2984 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; 2985 range->retry_flags = IW_RETRY_LIMIT; 2986 range->r_time_flags = IW_RETRY_LIFETIME; 2987 range->min_retry = 0; 2988 range->max_retry = 65535; /* ??? */ 2989 range->min_r_time = 0; 2990 range->max_r_time = 65535 * 1000; /* ??? */ 2991 2992 /* Event capability (kernel) */ 2993 IW_EVENT_CAPA_SET_KERNEL(range->event_capa); 2994 /* Event capability (driver) */ 2995 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY); 2996 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); 2997 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); 2998 IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); 2999 3000 return 0; 3001} 3002 3003static int orinoco_ioctl_setiwencode(struct net_device *dev, 3004 struct iw_request_info *info, 3005 struct iw_point *erq, 3006 char *keybuf) 3007{ 3008 struct orinoco_private *priv = netdev_priv(dev); 3009 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 3010 int setindex = priv->tx_key; 3011 int enable = priv->wep_on; 3012 int restricted = priv->wep_restrict; 3013 u16 xlen = 0; 3014 int err = -EINPROGRESS; /* Call commit handler */ 3015 unsigned long flags; 3016 3017 if (! priv->has_wep) 3018 return -EOPNOTSUPP; 3019 3020 if (erq->pointer) { 3021 /* We actually have a key to set - check its length */ 3022 if (erq->length > LARGE_KEY_SIZE) 3023 return -E2BIG; 3024 3025 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep ) 3026 return -E2BIG; 3027 } 3028 3029 if (orinoco_lock(priv, &flags) != 0) 3030 return -EBUSY; 3031 3032 if (erq->length > 0) { 3033 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 3034 index = priv->tx_key; 3035 3036 /* Adjust key length to a supported value */ 3037 if (erq->length > SMALL_KEY_SIZE) { 3038 xlen = LARGE_KEY_SIZE; 3039 } else if (erq->length > 0) { 3040 xlen = SMALL_KEY_SIZE; 3041 } else 3042 xlen = 0; 3043 3044 /* Switch on WEP if off */ 3045 if ((!enable) && (xlen > 0)) { 3046 setindex = index; 3047 enable = 1; 3048 } 3049 } else { 3050 /* Important note : if the user do "iwconfig eth0 enc off", 3051 * we will arrive there with an index of -1. This is valid 3052 * but need to be taken care off... Jean II */ 3053 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) { 3054 if((index != -1) || (erq->flags == 0)) { 3055 err = -EINVAL; 3056 goto out; 3057 } 3058 } else { 3059 /* Set the index : Check that the key is valid */ 3060 if(priv->keys[index].len == 0) { 3061 err = -EINVAL; 3062 goto out; 3063 } 3064 setindex = index; 3065 } 3066 } 3067 3068 if (erq->flags & IW_ENCODE_DISABLED) 3069 enable = 0; 3070 if (erq->flags & IW_ENCODE_OPEN) 3071 restricted = 0; 3072 if (erq->flags & IW_ENCODE_RESTRICTED) 3073 restricted = 1; 3074 3075 if (erq->pointer && erq->length > 0) { 3076 priv->keys[index].len = cpu_to_le16(xlen); 3077 memset(priv->keys[index].data, 0, 3078 sizeof(priv->keys[index].data)); 3079 memcpy(priv->keys[index].data, keybuf, erq->length); 3080 } 3081 priv->tx_key = setindex; 3082 3083 /* Try fast key change if connected and only keys are changed */ 3084 if (priv->wep_on && enable && (priv->wep_restrict == restricted) && 3085 netif_carrier_ok(dev)) { 3086 err = __orinoco_hw_setup_wepkeys(priv); 3087 /* No need to commit if successful */ 3088 goto out; 3089 } 3090 3091 priv->wep_on = enable; 3092 priv->wep_restrict = restricted; 3093 3094 out: 3095 orinoco_unlock(priv, &flags); 3096 3097 return err; 3098} 3099 3100static int orinoco_ioctl_getiwencode(struct net_device *dev, 3101 struct iw_request_info *info, 3102 struct iw_point *erq, 3103 char *keybuf) 3104{ 3105 struct orinoco_private *priv = netdev_priv(dev); 3106 int index = (erq->flags & IW_ENCODE_INDEX) - 1; 3107 u16 xlen = 0; 3108 unsigned long flags; 3109 3110 if (! priv->has_wep) 3111 return -EOPNOTSUPP; 3112 3113 if (orinoco_lock(priv, &flags) != 0) 3114 return -EBUSY; 3115 3116 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 3117 index = priv->tx_key; 3118 3119 erq->flags = 0; 3120 if (! priv->wep_on) 3121 erq->flags |= IW_ENCODE_DISABLED; 3122 erq->flags |= index + 1; 3123 3124 if (priv->wep_restrict) 3125 erq->flags |= IW_ENCODE_RESTRICTED; 3126 else 3127 erq->flags |= IW_ENCODE_OPEN; 3128 3129 xlen = le16_to_cpu(priv->keys[index].len); 3130 3131 erq->length = xlen; 3132 3133 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE); 3134 3135 orinoco_unlock(priv, &flags); 3136 return 0; 3137} 3138 3139static int orinoco_ioctl_setessid(struct net_device *dev, 3140 struct iw_request_info *info, 3141 struct iw_point *erq, 3142 char *essidbuf) 3143{ 3144 struct orinoco_private *priv = netdev_priv(dev); 3145 unsigned long flags; 3146 3147 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it 3148 * anyway... - Jean II */ 3149 3150 /* Hum... Should not use Wireless Extension constant (may change), 3151 * should use our own... - Jean II */ 3152 if (erq->length > IW_ESSID_MAX_SIZE) 3153 return -E2BIG; 3154 3155 if (orinoco_lock(priv, &flags) != 0) 3156 return -EBUSY; 3157 3158 /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */ 3159 memset(priv->desired_essid, 0, sizeof(priv->desired_essid)); 3160 3161 /* If not ANY, get the new ESSID */ 3162 if (erq->flags) { 3163 memcpy(priv->desired_essid, essidbuf, erq->length); 3164 } 3165 3166 orinoco_unlock(priv, &flags); 3167 3168 return -EINPROGRESS; /* Call commit handler */ 3169} 3170 3171static int orinoco_ioctl_getessid(struct net_device *dev, 3172 struct iw_request_info *info, 3173 struct iw_point *erq, 3174 char *essidbuf) 3175{ 3176 struct orinoco_private *priv = netdev_priv(dev); 3177 int active; 3178 int err = 0; 3179 unsigned long flags; 3180 3181 if (netif_running(dev)) { 3182 err = orinoco_hw_get_essid(priv, &active, essidbuf); 3183 if (err < 0) 3184 return err; 3185 erq->length = err; 3186 } else { 3187 if (orinoco_lock(priv, &flags) != 0) 3188 return -EBUSY; 3189 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE); 3190 erq->length = strlen(priv->desired_essid); 3191 orinoco_unlock(priv, &flags); 3192 } 3193 3194 erq->flags = 1; 3195 3196 return 0; 3197} 3198 3199static int orinoco_ioctl_setnick(struct net_device *dev, 3200 struct iw_request_info *info, 3201 struct iw_point *nrq, 3202 char *nickbuf) 3203{ 3204 struct orinoco_private *priv = netdev_priv(dev); 3205 unsigned long flags; 3206 3207 if (nrq->length > IW_ESSID_MAX_SIZE) 3208 return -E2BIG; 3209 3210 if (orinoco_lock(priv, &flags) != 0) 3211 return -EBUSY; 3212 3213 memset(priv->nick, 0, sizeof(priv->nick)); 3214 memcpy(priv->nick, nickbuf, nrq->length); 3215 3216 orinoco_unlock(priv, &flags); 3217 3218 return -EINPROGRESS; /* Call commit handler */ 3219} 3220 3221static int orinoco_ioctl_getnick(struct net_device *dev, 3222 struct iw_request_info *info, 3223 struct iw_point *nrq, 3224 char *nickbuf) 3225{ 3226 struct orinoco_private *priv = netdev_priv(dev); 3227 unsigned long flags; 3228 3229 if (orinoco_lock(priv, &flags) != 0) 3230 return -EBUSY; 3231 3232 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE); 3233 orinoco_unlock(priv, &flags); 3234 3235 nrq->length = strlen(priv->nick); 3236 3237 return 0; 3238} 3239 3240static int orinoco_ioctl_setfreq(struct net_device *dev, 3241 struct iw_request_info *info, 3242 struct iw_freq *frq, 3243 char *extra) 3244{ 3245 struct orinoco_private *priv = netdev_priv(dev); 3246 int chan = -1; 3247 unsigned long flags; 3248 int err = -EINPROGRESS; /* Call commit handler */ 3249 3250 /* In infrastructure mode the AP sets the channel */ 3251 if (priv->iw_mode == IW_MODE_INFRA) 3252 return -EBUSY; 3253 3254 if ( (frq->e == 0) && (frq->m <= 1000) ) { 3255 /* Setting by channel number */ 3256 chan = frq->m; 3257 } else { 3258 /* Setting by frequency - search the table */ 3259 int mult = 1; 3260 int i; 3261 3262 for (i = 0; i < (6 - frq->e); i++) 3263 mult *= 10; 3264 3265 for (i = 0; i < NUM_CHANNELS; i++) 3266 if (frq->m == (channel_frequency[i] * mult)) 3267 chan = i+1; 3268 } 3269 3270 if ( (chan < 1) || (chan > NUM_CHANNELS) || 3271 ! (priv->channel_mask & (1 << (chan-1)) ) ) 3272 return -EINVAL; 3273 3274 if (orinoco_lock(priv, &flags) != 0) 3275 return -EBUSY; 3276 3277 priv->channel = chan; 3278 if (priv->iw_mode == IW_MODE_MONITOR) { 3279 /* Fast channel change - no commit if successful */ 3280 hermes_t *hw = &priv->hw; 3281 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 3282 HERMES_TEST_SET_CHANNEL, 3283 chan, NULL); 3284 } 3285 orinoco_unlock(priv, &flags); 3286 3287 return err; 3288} 3289 3290static int orinoco_ioctl_getfreq(struct net_device *dev, 3291 struct iw_request_info *info, 3292 struct iw_freq *frq, 3293 char *extra) 3294{ 3295 struct orinoco_private *priv = netdev_priv(dev); 3296 int tmp; 3297 3298 /* Locking done in there */ 3299 tmp = orinoco_hw_get_freq(priv); 3300 if (tmp < 0) { 3301 return tmp; 3302 } 3303 3304 frq->m = tmp; 3305 frq->e = 1; 3306 3307 return 0; 3308} 3309 3310static int orinoco_ioctl_getsens(struct net_device *dev, 3311 struct iw_request_info *info, 3312 struct iw_param *srq, 3313 char *extra) 3314{ 3315 struct orinoco_private *priv = netdev_priv(dev); 3316 hermes_t *hw = &priv->hw; 3317 u16 val; 3318 int err; 3319 unsigned long flags; 3320 3321 if (!priv->has_sensitivity) 3322 return -EOPNOTSUPP; 3323 3324 if (orinoco_lock(priv, &flags) != 0) 3325 return -EBUSY; 3326 err = hermes_read_wordrec(hw, USER_BAP, 3327 HERMES_RID_CNFSYSTEMSCALE, &val); 3328 orinoco_unlock(priv, &flags); 3329 3330 if (err) 3331 return err; 3332 3333 srq->value = val; 3334 srq->fixed = 0; /* auto */ 3335 3336 return 0; 3337} 3338 3339static int orinoco_ioctl_setsens(struct net_device *dev, 3340 struct iw_request_info *info, 3341 struct iw_param *srq, 3342 char *extra) 3343{ 3344 struct orinoco_private *priv = netdev_priv(dev); 3345 int val = srq->value; 3346 unsigned long flags; 3347 3348 if (!priv->has_sensitivity) 3349 return -EOPNOTSUPP; 3350 3351 if ((val < 1) || (val > 3)) 3352 return -EINVAL; 3353 3354 if (orinoco_lock(priv, &flags) != 0) 3355 return -EBUSY; 3356 priv->ap_density = val; 3357 orinoco_unlock(priv, &flags); 3358 3359 return -EINPROGRESS; /* Call commit handler */ 3360} 3361 3362static int orinoco_ioctl_setrts(struct net_device *dev, 3363 struct iw_request_info *info, 3364 struct iw_param *rrq, 3365 char *extra) 3366{ 3367 struct orinoco_private *priv = netdev_priv(dev); 3368 int val = rrq->value; 3369 unsigned long flags; 3370 3371 if (rrq->disabled) 3372 val = 2347; 3373 3374 if ( (val < 0) || (val > 2347) ) 3375 return -EINVAL; 3376 3377 if (orinoco_lock(priv, &flags) != 0) 3378 return -EBUSY; 3379 3380 priv->rts_thresh = val; 3381 orinoco_unlock(priv, &flags); 3382 3383 return -EINPROGRESS; /* Call commit handler */ 3384} 3385 3386static int orinoco_ioctl_getrts(struct net_device *dev, 3387 struct iw_request_info *info, 3388 struct iw_param *rrq, 3389 char *extra) 3390{ 3391 struct orinoco_private *priv = netdev_priv(dev); 3392 3393 rrq->value = priv->rts_thresh; 3394 rrq->disabled = (rrq->value == 2347); 3395 rrq->fixed = 1; 3396 3397 return 0; 3398} 3399 3400static int orinoco_ioctl_setfrag(struct net_device *dev, 3401 struct iw_request_info *info, 3402 struct iw_param *frq, 3403 char *extra) 3404{ 3405 struct orinoco_private *priv = netdev_priv(dev); 3406 int err = -EINPROGRESS; /* Call commit handler */ 3407 unsigned long flags; 3408 3409 if (orinoco_lock(priv, &flags) != 0) 3410 return -EBUSY; 3411 3412 if (priv->has_mwo) { 3413 if (frq->disabled) 3414 priv->mwo_robust = 0; 3415 else { 3416 if (frq->fixed) 3417 printk(KERN_WARNING "%s: Fixed fragmentation is " 3418 "not supported on this firmware. " 3419 "Using MWO robust instead.\n", dev->name); 3420 priv->mwo_robust = 1; 3421 } 3422 } else { 3423 if (frq->disabled) 3424 priv->frag_thresh = 2346; 3425 else { 3426 if ( (frq->value < 256) || (frq->value > 2346) ) 3427 err = -EINVAL; 3428 else 3429 priv->frag_thresh = frq->value & ~0x1; /* must be even */ 3430 } 3431 } 3432 3433 orinoco_unlock(priv, &flags); 3434 3435 return err; 3436} 3437 3438static int orinoco_ioctl_getfrag(struct net_device *dev, 3439 struct iw_request_info *info, 3440 struct iw_param *frq, 3441 char *extra) 3442{ 3443 struct orinoco_private *priv = netdev_priv(dev); 3444 hermes_t *hw = &priv->hw; 3445 int err; 3446 u16 val; 3447 unsigned long flags; 3448 3449 if (orinoco_lock(priv, &flags) != 0) 3450 return -EBUSY; 3451 3452 if (priv->has_mwo) { 3453 err = hermes_read_wordrec(hw, USER_BAP, 3454 HERMES_RID_CNFMWOROBUST_AGERE, 3455 &val); 3456 if (err) 3457 val = 0; 3458 3459 frq->value = val ? 2347 : 0; 3460 frq->disabled = ! val; 3461 frq->fixed = 0; 3462 } else { 3463 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD, 3464 &val); 3465 if (err) 3466 val = 0; 3467 3468 frq->value = val; 3469 frq->disabled = (val >= 2346); 3470 frq->fixed = 1; 3471 } 3472 3473 orinoco_unlock(priv, &flags); 3474 3475 return err; 3476} 3477 3478static int orinoco_ioctl_setrate(struct net_device *dev, 3479 struct iw_request_info *info, 3480 struct iw_param *rrq, 3481 char *extra) 3482{ 3483 struct orinoco_private *priv = netdev_priv(dev); 3484 int ratemode = -1; 3485 int bitrate; /* 100s of kilobits */ 3486 int i; 3487 unsigned long flags; 3488 3489 /* As the user space doesn't know our highest rate, it uses -1 3490 * to ask us to set the highest rate. Test it using "iwconfig 3491 * ethX rate auto" - Jean II */ 3492 if (rrq->value == -1) 3493 bitrate = 110; 3494 else { 3495 if (rrq->value % 100000) 3496 return -EINVAL; 3497 bitrate = rrq->value / 100000; 3498 } 3499 3500 if ( (bitrate != 10) && (bitrate != 20) && 3501 (bitrate != 55) && (bitrate != 110) ) 3502 return -EINVAL; 3503 3504 for (i = 0; i < BITRATE_TABLE_SIZE; i++) 3505 if ( (bitrate_table[i].bitrate == bitrate) && 3506 (bitrate_table[i].automatic == ! rrq->fixed) ) { 3507 ratemode = i; 3508 break; 3509 } 3510 3511 if (ratemode == -1) 3512 return -EINVAL; 3513 3514 if (orinoco_lock(priv, &flags) != 0) 3515 return -EBUSY; 3516 priv->bitratemode = ratemode; 3517 orinoco_unlock(priv, &flags); 3518 3519 return -EINPROGRESS; 3520} 3521 3522static int orinoco_ioctl_getrate(struct net_device *dev, 3523 struct iw_request_info *info, 3524 struct iw_param *rrq, 3525 char *extra) 3526{ 3527 struct orinoco_private *priv = netdev_priv(dev); 3528 hermes_t *hw = &priv->hw; 3529 int err = 0; 3530 int ratemode; 3531 int i; 3532 u16 val; 3533 unsigned long flags; 3534 3535 if (orinoco_lock(priv, &flags) != 0) 3536 return -EBUSY; 3537 3538 ratemode = priv->bitratemode; 3539 3540 BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE)); 3541 3542 rrq->value = bitrate_table[ratemode].bitrate * 100000; 3543 rrq->fixed = ! bitrate_table[ratemode].automatic; 3544 rrq->disabled = 0; 3545 3546 /* If the interface is running we try to find more about the 3547 current mode */ 3548 if (netif_running(dev)) { 3549 err = hermes_read_wordrec(hw, USER_BAP, 3550 HERMES_RID_CURRENTTXRATE, &val); 3551 if (err) 3552 goto out; 3553 3554 switch (priv->firmware_type) { 3555 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */ 3556 /* Note : in Lucent firmware, the return value of 3557 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s, 3558 * and therefore is totally different from the 3559 * encoding of HERMES_RID_CNFTXRATECONTROL. 3560 * Don't forget that 6Mb/s is really 5.5Mb/s */ 3561 if (val == 6) 3562 rrq->value = 5500000; 3563 else 3564 rrq->value = val * 1000000; 3565 break; 3566 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */ 3567 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */ 3568 for (i = 0; i < BITRATE_TABLE_SIZE; i++) 3569 if (bitrate_table[i].intersil_txratectrl == val) { 3570 ratemode = i; 3571 break; 3572 } 3573 if (i >= BITRATE_TABLE_SIZE) 3574 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n", 3575 dev->name, val); 3576 3577 rrq->value = bitrate_table[ratemode].bitrate * 100000; 3578 break; 3579 default: 3580 BUG(); 3581 } 3582 } 3583 3584 out: 3585 orinoco_unlock(priv, &flags); 3586 3587 return err; 3588} 3589 3590static int orinoco_ioctl_setpower(struct net_device *dev, 3591 struct iw_request_info *info, 3592 struct iw_param *prq, 3593 char *extra) 3594{ 3595 struct orinoco_private *priv = netdev_priv(dev); 3596 int err = -EINPROGRESS; /* Call commit handler */ 3597 unsigned long flags; 3598 3599 if (orinoco_lock(priv, &flags) != 0) 3600 return -EBUSY; 3601 3602 if (prq->disabled) { 3603 priv->pm_on = 0; 3604 } else { 3605 switch (prq->flags & IW_POWER_MODE) { 3606 case IW_POWER_UNICAST_R: 3607 priv->pm_mcast = 0; 3608 priv->pm_on = 1; 3609 break; 3610 case IW_POWER_ALL_R: 3611 priv->pm_mcast = 1; 3612 priv->pm_on = 1; 3613 break; 3614 case IW_POWER_ON: 3615 /* No flags : but we may have a value - Jean II */ 3616 break; 3617 default: 3618 err = -EINVAL; 3619 goto out; 3620 } 3621 3622 if (prq->flags & IW_POWER_TIMEOUT) { 3623 priv->pm_on = 1; 3624 priv->pm_timeout = prq->value / 1000; 3625 } 3626 if (prq->flags & IW_POWER_PERIOD) { 3627 priv->pm_on = 1; 3628 priv->pm_period = prq->value / 1000; 3629 } 3630 /* It's valid to not have a value if we are just toggling 3631 * the flags... Jean II */ 3632 if(!priv->pm_on) { 3633 err = -EINVAL; 3634 goto out; 3635 } 3636 } 3637 3638 out: 3639 orinoco_unlock(priv, &flags); 3640 3641 return err; 3642} 3643 3644static int orinoco_ioctl_getpower(struct net_device *dev, 3645 struct iw_request_info *info, 3646 struct iw_param *prq, 3647 char *extra) 3648{ 3649 struct orinoco_private *priv = netdev_priv(dev); 3650 hermes_t *hw = &priv->hw; 3651 int err = 0; 3652 u16 enable, period, timeout, mcast; 3653 unsigned long flags; 3654 3655 if (orinoco_lock(priv, &flags) != 0) 3656 return -EBUSY; 3657 3658 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable); 3659 if (err) 3660 goto out; 3661 3662 err = hermes_read_wordrec(hw, USER_BAP, 3663 HERMES_RID_CNFMAXSLEEPDURATION, &period); 3664 if (err) 3665 goto out; 3666 3667 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout); 3668 if (err) 3669 goto out; 3670 3671 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast); 3672 if (err) 3673 goto out; 3674 3675 prq->disabled = !enable; 3676 /* Note : by default, display the period */ 3677 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 3678 prq->flags = IW_POWER_TIMEOUT; 3679 prq->value = timeout * 1000; 3680 } else { 3681 prq->flags = IW_POWER_PERIOD; 3682 prq->value = period * 1000; 3683 } 3684 if (mcast) 3685 prq->flags |= IW_POWER_ALL_R; 3686 else 3687 prq->flags |= IW_POWER_UNICAST_R; 3688 3689 out: 3690 orinoco_unlock(priv, &flags); 3691 3692 return err; 3693} 3694 3695static int orinoco_ioctl_getretry(struct net_device *dev, 3696 struct iw_request_info *info, 3697 struct iw_param *rrq, 3698 char *extra) 3699{ 3700 struct orinoco_private *priv = netdev_priv(dev); 3701 hermes_t *hw = &priv->hw; 3702 int err = 0; 3703 u16 short_limit, long_limit, lifetime; 3704 unsigned long flags; 3705 3706 if (orinoco_lock(priv, &flags) != 0) 3707 return -EBUSY; 3708 3709 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT, 3710 &short_limit); 3711 if (err) 3712 goto out; 3713 3714 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT, 3715 &long_limit); 3716 if (err) 3717 goto out; 3718 3719 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME, 3720 &lifetime); 3721 if (err) 3722 goto out; 3723 3724 rrq->disabled = 0; /* Can't be disabled */ 3725 3726 /* Note : by default, display the retry number */ 3727 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { 3728 rrq->flags = IW_RETRY_LIFETIME; 3729 rrq->value = lifetime * 1000; /* ??? */ 3730 } else { 3731 /* By default, display the min number */ 3732 if ((rrq->flags & IW_RETRY_LONG)) { 3733 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; 3734 rrq->value = long_limit; 3735 } else { 3736 rrq->flags = IW_RETRY_LIMIT; 3737 rrq->value = short_limit; 3738 if(short_limit != long_limit) 3739 rrq->flags |= IW_RETRY_SHORT; 3740 } 3741 } 3742 3743 out: 3744 orinoco_unlock(priv, &flags); 3745 3746 return err; 3747} 3748 3749static int orinoco_ioctl_reset(struct net_device *dev, 3750 struct iw_request_info *info, 3751 void *wrqu, 3752 char *extra) 3753{ 3754 struct orinoco_private *priv = netdev_priv(dev); 3755 3756 if (! capable(CAP_NET_ADMIN)) 3757 return -EPERM; 3758 3759 if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) { 3760 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name); 3761 3762 /* Firmware reset */ 3763 orinoco_reset(&priv->reset_work); 3764 } else { 3765 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name); 3766 3767 schedule_work(&priv->reset_work); 3768 } 3769 3770 return 0; 3771} 3772 3773static int orinoco_ioctl_setibssport(struct net_device *dev, 3774 struct iw_request_info *info, 3775 void *wrqu, 3776 char *extra) 3777 3778{ 3779 struct orinoco_private *priv = netdev_priv(dev); 3780 int val = *( (int *) extra ); 3781 unsigned long flags; 3782 3783 if (orinoco_lock(priv, &flags) != 0) 3784 return -EBUSY; 3785 3786 priv->ibss_port = val ; 3787 3788 /* Actually update the mode we are using */ 3789 set_port_type(priv); 3790 3791 orinoco_unlock(priv, &flags); 3792 return -EINPROGRESS; /* Call commit handler */ 3793} 3794 3795static int orinoco_ioctl_getibssport(struct net_device *dev, 3796 struct iw_request_info *info, 3797 void *wrqu, 3798 char *extra) 3799{ 3800 struct orinoco_private *priv = netdev_priv(dev); 3801 int *val = (int *) extra; 3802 3803 *val = priv->ibss_port; 3804 return 0; 3805} 3806 3807static int orinoco_ioctl_setport3(struct net_device *dev, 3808 struct iw_request_info *info, 3809 void *wrqu, 3810 char *extra) 3811{ 3812 struct orinoco_private *priv = netdev_priv(dev); 3813 int val = *( (int *) extra ); 3814 int err = 0; 3815 unsigned long flags; 3816 3817 if (orinoco_lock(priv, &flags) != 0) 3818 return -EBUSY; 3819 3820 switch (val) { 3821 case 0: /* Try to do IEEE ad-hoc mode */ 3822 if (! priv->has_ibss) { 3823 err = -EINVAL; 3824 break; 3825 } 3826 priv->prefer_port3 = 0; 3827 3828 break; 3829 3830 case 1: /* Try to do Lucent proprietary ad-hoc mode */ 3831 if (! priv->has_port3) { 3832 err = -EINVAL; 3833 break; 3834 } 3835 priv->prefer_port3 = 1; 3836 break; 3837 3838 default: 3839 err = -EINVAL; 3840 } 3841 3842 if (! err) { 3843 /* Actually update the mode we are using */ 3844 set_port_type(priv); 3845 err = -EINPROGRESS; 3846 } 3847 3848 orinoco_unlock(priv, &flags); 3849 3850 return err; 3851} 3852 3853static int orinoco_ioctl_getport3(struct net_device *dev, 3854 struct iw_request_info *info, 3855 void *wrqu, 3856 char *extra) 3857{ 3858 struct orinoco_private *priv = netdev_priv(dev); 3859 int *val = (int *) extra; 3860 3861 *val = priv->prefer_port3; 3862 return 0; 3863} 3864 3865static int orinoco_ioctl_setpreamble(struct net_device *dev, 3866 struct iw_request_info *info, 3867 void *wrqu, 3868 char *extra) 3869{ 3870 struct orinoco_private *priv = netdev_priv(dev); 3871 unsigned long flags; 3872 int val; 3873 3874 if (! priv->has_preamble) 3875 return -EOPNOTSUPP; 3876 3877 /* 802.11b has recently defined some short preamble. 3878 * Basically, the Phy header has been reduced in size. 3879 * This increase performance, especially at high rates 3880 * (the preamble is transmitted at 1Mb/s), unfortunately 3881 * this give compatibility troubles... - Jean II */ 3882 val = *( (int *) extra ); 3883 3884 if (orinoco_lock(priv, &flags) != 0) 3885 return -EBUSY; 3886 3887 if (val) 3888 priv->preamble = 1; 3889 else 3890 priv->preamble = 0; 3891 3892 orinoco_unlock(priv, &flags); 3893 3894 return -EINPROGRESS; /* Call commit handler */ 3895} 3896 3897static int orinoco_ioctl_getpreamble(struct net_device *dev, 3898 struct iw_request_info *info, 3899 void *wrqu, 3900 char *extra) 3901{ 3902 struct orinoco_private *priv = netdev_priv(dev); 3903 int *val = (int *) extra; 3904 3905 if (! priv->has_preamble) 3906 return -EOPNOTSUPP; 3907 3908 *val = priv->preamble; 3909 return 0; 3910} 3911 3912/* ioctl interface to hermes_read_ltv() 3913 * To use with iwpriv, pass the RID as the token argument, e.g. 3914 * iwpriv get_rid [0xfc00] 3915 * At least Wireless Tools 25 is required to use iwpriv. 3916 * For Wireless Tools 25 and 26 append "dummy" are the end. */ 3917static int orinoco_ioctl_getrid(struct net_device *dev, 3918 struct iw_request_info *info, 3919 struct iw_point *data, 3920 char *extra) 3921{ 3922 struct orinoco_private *priv = netdev_priv(dev); 3923 hermes_t *hw = &priv->hw; 3924 int rid = data->flags; 3925 u16 length; 3926 int err; 3927 unsigned long flags; 3928 3929 /* It's a "get" function, but we don't want users to access the 3930 * WEP key and other raw firmware data */ 3931 if (! capable(CAP_NET_ADMIN)) 3932 return -EPERM; 3933 3934 if (rid < 0xfc00 || rid > 0xffff) 3935 return -EINVAL; 3936 3937 if (orinoco_lock(priv, &flags) != 0) 3938 return -EBUSY; 3939 3940 err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, 3941 extra); 3942 if (err) 3943 goto out; 3944 3945 data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length), 3946 MAX_RID_LEN); 3947 3948 out: 3949 orinoco_unlock(priv, &flags); 3950 return err; 3951} 3952 3953/* Trigger a scan (look for other cells in the vicinity */ 3954static int orinoco_ioctl_setscan(struct net_device *dev, 3955 struct iw_request_info *info, 3956 struct iw_param *srq, 3957 char *extra) 3958{ 3959 struct orinoco_private *priv = netdev_priv(dev); 3960 hermes_t *hw = &priv->hw; 3961 int err = 0; 3962 unsigned long flags; 3963 3964 /* Note : you may have realised that, as this is a SET operation, 3965 * this is privileged and therefore a normal user can't 3966 * perform scanning. 3967 * This is not an error, while the device perform scanning, 3968 * traffic doesn't flow, so it's a perfect DoS... 3969 * Jean II */ 3970 3971 if (orinoco_lock(priv, &flags) != 0) 3972 return -EBUSY; 3973 3974 /* Scanning with port 0 disabled would fail */ 3975 if (!netif_running(dev)) { 3976 err = -ENETDOWN; 3977 goto out; 3978 } 3979 3980 /* In monitor mode, the scan results are always empty. 3981 * Probe responses are passed to the driver as received 3982 * frames and could be processed in software. */ 3983 if (priv->iw_mode == IW_MODE_MONITOR) { 3984 err = -EOPNOTSUPP; 3985 goto out; 3986 } 3987 3988 /* Note : because we don't lock out the irq handler, the way 3989 * we access scan variables in priv is critical. 3990 * o scan_inprogress : not touched by irq handler 3991 * o scan_mode : not touched by irq handler 3992 * o scan_len : synchronised with scan_result 3993 * Before modifying anything on those variables, please think hard ! 3994 * Jean II */ 3995 3996 /* Save flags */ 3997 priv->scan_mode = srq->flags; 3998 3999 /* Always trigger scanning, even if it's in progress. 4000 * This way, if the info frame get lost, we will recover somewhat 4001 * gracefully - Jean II */ 4002 4003 if (priv->has_hostscan) { 4004 switch (priv->firmware_type) { 4005 case FIRMWARE_TYPE_SYMBOL: 4006 err = hermes_write_wordrec(hw, USER_BAP, 4007 HERMES_RID_CNFHOSTSCAN_SYMBOL, 4008 HERMES_HOSTSCAN_SYMBOL_ONCE | 4009 HERMES_HOSTSCAN_SYMBOL_BCAST); 4010 break; 4011 case FIRMWARE_TYPE_INTERSIL: { 4012 __le16 req[3]; 4013 4014 req[0] = cpu_to_le16(0x3fff); /* All channels */ 4015 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */ 4016 req[2] = 0; /* Any ESSID */ 4017 err = HERMES_WRITE_RECORD(hw, USER_BAP, 4018 HERMES_RID_CNFHOSTSCAN, &req); 4019 } 4020 break; 4021 case FIRMWARE_TYPE_AGERE: 4022 err = hermes_write_wordrec(hw, USER_BAP, 4023 HERMES_RID_CNFSCANSSID_AGERE, 4024 0); /* Any ESSID */ 4025 if (err) 4026 break; 4027 4028 err = hermes_inquire(hw, HERMES_INQ_SCAN); 4029 break; 4030 } 4031 } else 4032 err = hermes_inquire(hw, HERMES_INQ_SCAN); 4033 4034 /* One more client */ 4035 if (! err) 4036 priv->scan_inprogress = 1; 4037 4038 out: 4039 orinoco_unlock(priv, &flags); 4040 return err; 4041} 4042 4043#define MAX_CUSTOM_LEN 64 4044 4045/* Translate scan data returned from the card to a card independant 4046 * format that the Wireless Tools will understand - Jean II 4047 * Return message length or -errno for fatal errors */ 4048static inline char *orinoco_translate_scan(struct net_device *dev, 4049 char *current_ev, 4050 char *end_buf, 4051 union hermes_scan_info *bss, 4052 unsigned int last_scanned) 4053{ 4054 struct orinoco_private *priv = netdev_priv(dev); 4055 u16 capabilities; 4056 u16 channel; 4057 struct iw_event iwe; /* Temporary buffer */ 4058 char *p; 4059 char custom[MAX_CUSTOM_LEN]; 4060 4061 /* First entry *MUST* be the AP MAC address */ 4062 iwe.cmd = SIOCGIWAP; 4063 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 4064 memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN); 4065 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 4066 4067 /* Other entries will be displayed in the order we give them */ 4068 4069 /* Add the ESSID */ 4070 iwe.u.data.length = le16_to_cpu(bss->a.essid_len); 4071 if (iwe.u.data.length > 32) 4072 iwe.u.data.length = 32; 4073 iwe.cmd = SIOCGIWESSID; 4074 iwe.u.data.flags = 1; 4075 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); 4076 4077 /* Add mode */ 4078 iwe.cmd = SIOCGIWMODE; 4079 capabilities = le16_to_cpu(bss->a.capabilities); 4080 if (capabilities & 0x3) { 4081 if (capabilities & 0x1) 4082 iwe.u.mode = IW_MODE_MASTER; 4083 else 4084 iwe.u.mode = IW_MODE_ADHOC; 4085 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); 4086 } 4087 4088 channel = bss->s.channel; 4089 if ((channel >= 1) && (channel <= NUM_CHANNELS)) { 4090 /* Add frequency */ 4091 iwe.cmd = SIOCGIWFREQ; 4092 iwe.u.freq.m = channel_frequency[channel-1] * 100000; 4093 iwe.u.freq.e = 1; 4094 current_ev = iwe_stream_add_event(current_ev, end_buf, 4095 &iwe, IW_EV_FREQ_LEN); 4096 } 4097 4098 /* Add quality statistics */ 4099 iwe.cmd = IWEVQUAL; 4100 iwe.u.qual.updated = 0x10; /* no link quality */ 4101 iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95; 4102 iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95; 4103 /* Wireless tools prior to 27.pre22 will show link quality 4104 * anyway, so we provide a reasonable value. */ 4105 if (iwe.u.qual.level > iwe.u.qual.noise) 4106 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; 4107 else 4108 iwe.u.qual.qual = 0; 4109 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 4110 4111 /* Add encryption capability */ 4112 iwe.cmd = SIOCGIWENCODE; 4113 if (capabilities & 0x10) 4114 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 4115 else 4116 iwe.u.data.flags = IW_ENCODE_DISABLED; 4117 iwe.u.data.length = 0; 4118 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); 4119 4120 /* Add EXTRA: Age to display seconds since last beacon/probe response 4121 * for given network. */ 4122 iwe.cmd = IWEVCUSTOM; 4123 p = custom; 4124 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), 4125 " Last beacon: %dms ago", 4126 jiffies_to_msecs(jiffies - last_scanned)); 4127 iwe.u.data.length = p - custom; 4128 if (iwe.u.data.length) 4129 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom); 4130 4131 /* Bit rate is not available in Lucent/Agere firmwares */ 4132 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { 4133 char *current_val = current_ev + IW_EV_LCP_LEN; 4134 int i; 4135 int step; 4136 4137 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) 4138 step = 2; 4139 else 4140 step = 1; 4141 4142 iwe.cmd = SIOCGIWRATE; 4143 /* Those two flags are ignored... */ 4144 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 4145 /* Max 10 values */ 4146 for (i = 0; i < 10; i += step) { 4147 /* NULL terminated */ 4148 if (bss->p.rates[i] == 0x0) 4149 break; 4150 /* Bit rate given in 500 kb/s units (+ 0x80) */ 4151 iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000); 4152 current_val = iwe_stream_add_value(current_ev, current_val, 4153 end_buf, &iwe, 4154 IW_EV_PARAM_LEN); 4155 } 4156 /* Check if we added any event */ 4157 if ((current_val - current_ev) > IW_EV_LCP_LEN) 4158 current_ev = current_val; 4159 } 4160 4161 return current_ev; 4162} 4163 4164/* Return results of a scan */ 4165static int orinoco_ioctl_getscan(struct net_device *dev, 4166 struct iw_request_info *info, 4167 struct iw_point *srq, 4168 char *extra) 4169{ 4170 struct orinoco_private *priv = netdev_priv(dev); 4171 bss_element *bss; 4172 int err = 0; 4173 unsigned long flags; 4174 char *current_ev = extra; 4175 4176 if (orinoco_lock(priv, &flags) != 0) 4177 return -EBUSY; 4178 4179 if (priv->scan_inprogress) { 4180 /* Important note : we don't want to block the caller 4181 * until results are ready for various reasons. 4182 * First, managing wait queues is complex and racy. 4183 * Second, we grab some rtnetlink lock before comming 4184 * here (in dev_ioctl()). 4185 * Third, we generate an Wireless Event, so the 4186 * caller can wait itself on that - Jean II */ 4187 err = -EAGAIN; 4188 goto out; 4189 } 4190 4191 list_for_each_entry(bss, &priv->bss_list, list) { 4192 /* Translate to WE format this entry */ 4193 current_ev = orinoco_translate_scan(dev, current_ev, 4194 extra + srq->length, 4195 &bss->bss, 4196 bss->last_scanned); 4197 4198 /* Check if there is space for one more entry */ 4199 if ((extra + srq->length - current_ev) <= IW_EV_ADDR_LEN) { 4200 /* Ask user space to try again with a bigger buffer */ 4201 err = -E2BIG; 4202 goto out; 4203 } 4204 } 4205 4206 srq->length = (current_ev - extra); 4207 srq->flags = (__u16) priv->scan_mode; 4208 4209out: 4210 orinoco_unlock(priv, &flags); 4211 return err; 4212} 4213 4214/* Commit handler, called after set operations */ 4215static int orinoco_ioctl_commit(struct net_device *dev, 4216 struct iw_request_info *info, 4217 void *wrqu, 4218 char *extra) 4219{ 4220 struct orinoco_private *priv = netdev_priv(dev); 4221 struct hermes *hw = &priv->hw; 4222 unsigned long flags; 4223 int err = 0; 4224 4225 if (!priv->open) 4226 return 0; 4227 4228 if (priv->broken_disableport) { 4229 orinoco_reset(&priv->reset_work); 4230 return 0; 4231 } 4232 4233 if (orinoco_lock(priv, &flags) != 0) 4234 return err; 4235 4236 err = hermes_disable_port(hw, 0); 4237 if (err) { 4238 printk(KERN_WARNING "%s: Unable to disable port " 4239 "while reconfiguring card\n", dev->name); 4240 priv->broken_disableport = 1; 4241 goto out; 4242 } 4243 4244 err = __orinoco_program_rids(dev); 4245 if (err) { 4246 printk(KERN_WARNING "%s: Unable to reconfigure card\n", 4247 dev->name); 4248 goto out; 4249 } 4250 4251 err = hermes_enable_port(hw, 0); 4252 if (err) { 4253 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n", 4254 dev->name); 4255 goto out; 4256 } 4257 4258 out: 4259 if (err) { 4260 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name); 4261 schedule_work(&priv->reset_work); 4262 err = 0; 4263 } 4264 4265 orinoco_unlock(priv, &flags); 4266 return err; 4267} 4268 4269static const struct iw_priv_args orinoco_privtab[] = { 4270 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" }, 4271 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" }, 4272 { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 4273 0, "set_port3" }, 4274 { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 4275 "get_port3" }, 4276 { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 4277 0, "set_preamble" }, 4278 { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 4279 "get_preamble" }, 4280 { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 4281 0, "set_ibssport" }, 4282 { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 4283 "get_ibssport" }, 4284 { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN, 4285 "get_rid" }, 4286}; 4287 4288 4289/* 4290 * Structures to export the Wireless Handlers 4291 */ 4292 4293static const iw_handler orinoco_handler[] = { 4294 [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit, 4295 [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname, 4296 [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq, 4297 [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq, 4298 [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode, 4299 [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode, 4300 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, 4301 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, 4302 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, 4303 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy, 4304 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy, 4305 [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy, 4306 [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy, 4307 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, 4308 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, 4309 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, 4310 [SIOCGIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan, 4311 [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid, 4312 [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid, 4313 [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick, 4314 [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick, 4315 [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate, 4316 [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate, 4317 [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts, 4318 [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts, 4319 [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag, 4320 [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag, 4321 [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry, 4322 [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode, 4323 [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode, 4324 [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower, 4325 [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower, 4326}; 4327 4328 4329/* 4330 Added typecasting since we no longer use iwreq_data -- Moustafa 4331 */ 4332static const iw_handler orinoco_private_handler[] = { 4333 [0] = (iw_handler) orinoco_ioctl_reset, 4334 [1] = (iw_handler) orinoco_ioctl_reset, 4335 [2] = (iw_handler) orinoco_ioctl_setport3, 4336 [3] = (iw_handler) orinoco_ioctl_getport3, 4337 [4] = (iw_handler) orinoco_ioctl_setpreamble, 4338 [5] = (iw_handler) orinoco_ioctl_getpreamble, 4339 [6] = (iw_handler) orinoco_ioctl_setibssport, 4340 [7] = (iw_handler) orinoco_ioctl_getibssport, 4341 [9] = (iw_handler) orinoco_ioctl_getrid, 4342}; 4343 4344static const struct iw_handler_def orinoco_handler_def = { 4345 .num_standard = ARRAY_SIZE(orinoco_handler), 4346 .num_private = ARRAY_SIZE(orinoco_private_handler), 4347 .num_private_args = ARRAY_SIZE(orinoco_privtab), 4348 .standard = orinoco_handler, 4349 .private = orinoco_private_handler, 4350 .private_args = orinoco_privtab, 4351 .get_wireless_stats = orinoco_get_wireless_stats, 4352}; 4353 4354static void orinoco_get_drvinfo(struct net_device *dev, 4355 struct ethtool_drvinfo *info) 4356{ 4357 struct orinoco_private *priv = netdev_priv(dev); 4358 4359 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1); 4360 strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1); 4361 strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1); 4362 if (dev->dev.parent) 4363 strncpy(info->bus_info, dev->dev.parent->bus_id, 4364 sizeof(info->bus_info) - 1); 4365 else 4366 snprintf(info->bus_info, sizeof(info->bus_info) - 1, 4367 "PCMCIA %p", priv->hw.iobase); 4368} 4369 4370static const struct ethtool_ops orinoco_ethtool_ops = { 4371 .get_drvinfo = orinoco_get_drvinfo, 4372 .get_link = ethtool_op_get_link, 4373}; 4374 4375/********************************************************************/ 4376/* Module initialization */ 4377/********************************************************************/ 4378 4379EXPORT_SYMBOL(alloc_orinocodev); 4380EXPORT_SYMBOL(free_orinocodev); 4381 4382EXPORT_SYMBOL(__orinoco_up); 4383EXPORT_SYMBOL(__orinoco_down); 4384EXPORT_SYMBOL(orinoco_reinit_firmware); 4385 4386EXPORT_SYMBOL(orinoco_interrupt); 4387 4388/* Can't be declared "const" or the whole __initdata section will 4389 * become const */ 4390static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION 4391 " (David Gibson <hermes@gibson.dropbear.id.au>, " 4392 "Pavel Roskin <proski@gnu.org>, et al)"; 4393 4394static int __init init_orinoco(void) 4395{ 4396 printk(KERN_DEBUG "%s\n", version); 4397 return 0; 4398} 4399 4400static void __exit exit_orinoco(void) 4401{ 4402} 4403 4404module_init(init_orinoco); 4405module_exit(exit_orinoco);