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

Configure Feed

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

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