aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pretzel.yyz.us>2005-06-26 23:38:58 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-26 23:38:58 -0400
commit5696c1944a33b4434a9a1ebb6383b906afd43a10 (patch)
tree16fbe6ba431bcf949ee8645510b0c2fd39b5810f /drivers/net/wireless/orinoco.c
parent66b04a80eea60cabf9d89fd34deb3234a740052f (diff)
parent020f46a39eb7b99a575b9f4d105fce2b142acdf1 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r--drivers/net/wireless/orinoco.c332
1 files changed, 69 insertions, 263 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index b47684c3217e..a57187391f81 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -493,6 +493,9 @@ EXPORT_SYMBOL(orinoco_debug);
493static int suppress_linkstatus; /* = 0 */ 493static int suppress_linkstatus; /* = 0 */
494module_param(suppress_linkstatus, bool, 0644); 494module_param(suppress_linkstatus, bool, 0644);
495MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); 495MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
496static int ignore_disconnect; /* = 0 */
497module_param(ignore_disconnect, int, 0644);
498MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
496 499
497/********************************************************************/ 500/********************************************************************/
498/* Compile time configuration and compatibility stuff */ 501/* Compile time configuration and compatibility stuff */
@@ -605,7 +608,6 @@ struct hermes_rx_descriptor {
605static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 608static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
606static int __orinoco_program_rids(struct net_device *dev); 609static int __orinoco_program_rids(struct net_device *dev);
607static void __orinoco_set_multicast_list(struct net_device *dev); 610static void __orinoco_set_multicast_list(struct net_device *dev);
608static int orinoco_debug_dump_recs(struct net_device *dev);
609 611
610/********************************************************************/ 612/********************************************************************/
611/* Internal helper functions */ 613/* Internal helper functions */
@@ -656,7 +658,7 @@ static int orinoco_open(struct net_device *dev)
656 return err; 658 return err;
657} 659}
658 660
659int orinoco_stop(struct net_device *dev) 661static int orinoco_stop(struct net_device *dev)
660{ 662{
661 struct orinoco_private *priv = netdev_priv(dev); 663 struct orinoco_private *priv = netdev_priv(dev);
662 int err = 0; 664 int err = 0;
@@ -687,7 +689,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
687 struct orinoco_private *priv = netdev_priv(dev); 689 struct orinoco_private *priv = netdev_priv(dev);
688 hermes_t *hw = &priv->hw; 690 hermes_t *hw = &priv->hw;
689 struct iw_statistics *wstats = &priv->wstats; 691 struct iw_statistics *wstats = &priv->wstats;
690 int err = 0; 692 int err;
691 unsigned long flags; 693 unsigned long flags;
692 694
693 if (! netif_device_present(dev)) { 695 if (! netif_device_present(dev)) {
@@ -696,9 +698,21 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
696 return NULL; /* FIXME: Can we do better than this? */ 698 return NULL; /* FIXME: Can we do better than this? */
697 } 699 }
698 700
701 /* If busy, return the old stats. Returning NULL may cause
702 * the interface to disappear from /proc/net/wireless */
699 if (orinoco_lock(priv, &flags) != 0) 703 if (orinoco_lock(priv, &flags) != 0)
700 return NULL; /* FIXME: Erg, we've been signalled, how 704 return wstats;
701 * do we propagate this back up? */ 705
706 /* We can't really wait for the tallies inquiry command to
707 * complete, so we just use the previous results and trigger
708 * a new tallies inquiry command for next time - Jean II */
709 /* FIXME: Really we should wait for the inquiry to come back -
710 * as it is the stats we give don't make a whole lot of sense.
711 * Unfortunately, it's not clear how to do that within the
712 * wireless extensions framework: I think we're in user
713 * context, but a lock seems to be held by the time we get in
714 * here so we're not safe to sleep here. */
715 hermes_inquire(hw, HERMES_INQ_TALLIES);
702 716
703 if (priv->iw_mode == IW_MODE_ADHOC) { 717 if (priv->iw_mode == IW_MODE_ADHOC) {
704 memset(&wstats->qual, 0, sizeof(wstats->qual)); 718 memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -717,25 +731,16 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
717 731
718 err = HERMES_READ_RECORD(hw, USER_BAP, 732 err = HERMES_READ_RECORD(hw, USER_BAP,
719 HERMES_RID_COMMSQUALITY, &cq); 733 HERMES_RID_COMMSQUALITY, &cq);
720 734
721 wstats->qual.qual = (int)le16_to_cpu(cq.qual); 735 if (!err) {
722 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; 736 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
723 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; 737 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
724 wstats->qual.updated = 7; 738 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
739 wstats->qual.updated = 7;
740 }
725 } 741 }
726 742
727 /* We can't really wait for the tallies inquiry command to
728 * complete, so we just use the previous results and trigger
729 * a new tallies inquiry command for next time - Jean II */
730 /* FIXME: We're in user context (I think?), so we should just
731 wait for the tallies to come through */
732 err = hermes_inquire(hw, HERMES_INQ_TALLIES);
733
734 orinoco_unlock(priv, &flags); 743 orinoco_unlock(priv, &flags);
735
736 if (err)
737 return NULL;
738
739 return wstats; 744 return wstats;
740} 745}
741 746
@@ -1276,9 +1281,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1276 len = sizeof(tallies); 1281 len = sizeof(tallies);
1277 } 1282 }
1278 1283
1279 /* Read directly the data (no seek) */ 1284 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
1280 hermes_read_words(hw, HERMES_DATA1, (void *) &tallies, 1285 infofid, sizeof(info));
1281 len / 2); /* FIXME: blech! */ 1286 if (err)
1287 break;
1282 1288
1283 /* Increment our various counters */ 1289 /* Increment our various counters */
1284 /* wstats->discard.nwid - no wrong BSSID stuff */ 1290 /* wstats->discard.nwid - no wrong BSSID stuff */
@@ -1308,8 +1314,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1308 break; 1314 break;
1309 } 1315 }
1310 1316
1311 hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus, 1317 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
1312 len / 2); 1318 infofid, sizeof(info));
1319 if (err)
1320 break;
1313 newstatus = le16_to_cpu(linkstatus.linkstatus); 1321 newstatus = le16_to_cpu(linkstatus.linkstatus);
1314 1322
1315 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) 1323 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
@@ -1318,7 +1326,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1318 1326
1319 if (connected) 1327 if (connected)
1320 netif_carrier_on(dev); 1328 netif_carrier_on(dev);
1321 else 1329 else if (!ignore_disconnect)
1322 netif_carrier_off(dev); 1330 netif_carrier_off(dev);
1323 1331
1324 if (newstatus != priv->last_linkstatus) 1332 if (newstatus != priv->last_linkstatus)
@@ -1351,6 +1359,8 @@ int __orinoco_up(struct net_device *dev)
1351 struct hermes *hw = &priv->hw; 1359 struct hermes *hw = &priv->hw;
1352 int err; 1360 int err;
1353 1361
1362 netif_carrier_off(dev); /* just to make sure */
1363
1354 err = __orinoco_program_rids(dev); 1364 err = __orinoco_program_rids(dev);
1355 if (err) { 1365 if (err) {
1356 printk(KERN_ERR "%s: Error %d configuring card\n", 1366 printk(KERN_ERR "%s: Error %d configuring card\n",
@@ -1414,7 +1424,7 @@ int orinoco_reinit_firmware(struct net_device *dev)
1414 return err; 1424 return err;
1415 1425
1416 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 1426 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1417 if (err == -EIO) { 1427 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
1418 /* Try workaround for old Symbol firmware bug */ 1428 /* Try workaround for old Symbol firmware bug */
1419 printk(KERN_WARNING "%s: firmware ALLOC bug detected " 1429 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1420 "(old Symbol firmware?). Trying to work around... ", 1430 "(old Symbol firmware?). Trying to work around... ",
@@ -1611,17 +1621,15 @@ static int __orinoco_program_rids(struct net_device *dev)
1611 return err; 1621 return err;
1612 } 1622 }
1613 /* Set the channel/frequency */ 1623 /* Set the channel/frequency */
1614 if (priv->channel == 0) { 1624 if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
1615 printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name); 1625 err = hermes_write_wordrec(hw, USER_BAP,
1616 if (priv->createibss) 1626 HERMES_RID_CNFOWNCHANNEL,
1617 priv->channel = 10; 1627 priv->channel);
1618 } 1628 if (err) {
1619 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL, 1629 printk(KERN_ERR "%s: Error %d setting channel %d\n",
1620 priv->channel); 1630 dev->name, err, priv->channel);
1621 if (err) { 1631 return err;
1622 printk(KERN_ERR "%s: Error %d setting channel\n", 1632 }
1623 dev->name, err);
1624 return err;
1625 } 1633 }
1626 1634
1627 if (priv->has_ibss) { 1635 if (priv->has_ibss) {
@@ -1917,7 +1925,7 @@ static void orinoco_reset(struct net_device *dev)
1917{ 1925{
1918 struct orinoco_private *priv = netdev_priv(dev); 1926 struct orinoco_private *priv = netdev_priv(dev);
1919 struct hermes *hw = &priv->hw; 1927 struct hermes *hw = &priv->hw;
1920 int err = 0; 1928 int err;
1921 unsigned long flags; 1929 unsigned long flags;
1922 1930
1923 if (orinoco_lock(priv, &flags) != 0) 1931 if (orinoco_lock(priv, &flags) != 0)
@@ -1939,20 +1947,20 @@ static void orinoco_reset(struct net_device *dev)
1939 1947
1940 orinoco_unlock(priv, &flags); 1948 orinoco_unlock(priv, &flags);
1941 1949
1942 if (priv->hard_reset) 1950 if (priv->hard_reset) {
1943 err = (*priv->hard_reset)(priv); 1951 err = (*priv->hard_reset)(priv);
1944 if (err) { 1952 if (err) {
1945 printk(KERN_ERR "%s: orinoco_reset: Error %d " 1953 printk(KERN_ERR "%s: orinoco_reset: Error %d "
1946 "performing hard reset\n", dev->name, err); 1954 "performing hard reset\n", dev->name, err);
1947 /* FIXME: shutdown of some sort */ 1955 goto disable;
1948 return; 1956 }
1949 } 1957 }
1950 1958
1951 err = orinoco_reinit_firmware(dev); 1959 err = orinoco_reinit_firmware(dev);
1952 if (err) { 1960 if (err) {
1953 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", 1961 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
1954 dev->name, err); 1962 dev->name, err);
1955 return; 1963 goto disable;
1956 } 1964 }
1957 1965
1958 spin_lock_irq(&priv->lock); /* This has to be called from user context */ 1966 spin_lock_irq(&priv->lock); /* This has to be called from user context */
@@ -1973,6 +1981,10 @@ static void orinoco_reset(struct net_device *dev)
1973 spin_unlock_irq(&priv->lock); 1981 spin_unlock_irq(&priv->lock);
1974 1982
1975 return; 1983 return;
1984 disable:
1985 hermes_set_irqmask(hw, 0);
1986 netif_device_detach(dev);
1987 printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
1976} 1988}
1977 1989
1978/********************************************************************/ 1990/********************************************************************/
@@ -2057,7 +2069,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2057 if (events & HERMES_EV_ALLOC) 2069 if (events & HERMES_EV_ALLOC)
2058 __orinoco_ev_alloc(dev, hw); 2070 __orinoco_ev_alloc(dev, hw);
2059 2071
2060 hermes_write_regn(hw, EVACK, events); 2072 hermes_write_regn(hw, EVACK, evstat);
2061 2073
2062 evstat = hermes_read_regn(hw, EVSTAT); 2074 evstat = hermes_read_regn(hw, EVSTAT);
2063 events = evstat & hw->inten; 2075 events = evstat & hw->inten;
@@ -2216,6 +2228,8 @@ static int determine_firmware(struct net_device *dev)
2216 firmver >= 0x31000; 2228 firmver >= 0x31000;
2217 priv->has_preamble = (firmver >= 0x20000); 2229 priv->has_preamble = (firmver >= 0x20000);
2218 priv->ibss_port = 4; 2230 priv->ibss_port = 4;
2231 priv->broken_disableport = (firmver == 0x25013) ||
2232 (firmver >= 0x30000 && firmver <= 0x31000);
2219 /* Tested with Intel firmware : 0x20015 => Jean II */ 2233 /* Tested with Intel firmware : 0x20015 => Jean II */
2220 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ 2234 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2221 break; 2235 break;
@@ -2268,7 +2282,7 @@ static int orinoco_init(struct net_device *dev)
2268 priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN; 2282 priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
2269 2283
2270 /* Initialize the firmware */ 2284 /* Initialize the firmware */
2271 err = hermes_init(hw); 2285 err = orinoco_reinit_firmware(dev);
2272 if (err != 0) { 2286 if (err != 0) {
2273 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", 2287 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2274 dev->name, err); 2288 dev->name, err);
@@ -2401,31 +2415,12 @@ static int orinoco_init(struct net_device *dev)
2401 /* By default use IEEE/IBSS ad-hoc mode if we have it */ 2415 /* By default use IEEE/IBSS ad-hoc mode if we have it */
2402 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); 2416 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
2403 set_port_type(priv); 2417 set_port_type(priv);
2404 priv->channel = 10; /* default channel, more-or-less arbitrary */ 2418 priv->channel = 0; /* use firmware default */
2405 2419
2406 priv->promiscuous = 0; 2420 priv->promiscuous = 0;
2407 priv->wep_on = 0; 2421 priv->wep_on = 0;
2408 priv->tx_key = 0; 2422 priv->tx_key = 0;
2409 2423
2410 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2411 if (err == -EIO) {
2412 /* Try workaround for old Symbol firmware bug */
2413 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
2414 "(old Symbol firmware?). Trying to work around... ",
2415 dev->name);
2416
2417 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
2418 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2419 if (err)
2420 printk("failed!\n");
2421 else
2422 printk("ok.\n");
2423 }
2424 if (err) {
2425 printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
2426 goto out;
2427 }
2428
2429 /* Make the hardware available, as long as it hasn't been 2424 /* Make the hardware available, as long as it hasn't been
2430 * removed elsewhere (e.g. by PCMCIA hot unplug) */ 2425 * removed elsewhere (e.g. by PCMCIA hot unplug) */
2431 spin_lock_irq(&priv->lock); 2426 spin_lock_irq(&priv->lock);
@@ -2451,7 +2446,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2451 priv = netdev_priv(dev); 2446 priv = netdev_priv(dev);
2452 priv->ndev = dev; 2447 priv->ndev = dev;
2453 if (sizeof_card) 2448 if (sizeof_card)
2454 priv->card = (void *)((unsigned long)netdev_priv(dev) 2449 priv->card = (void *)((unsigned long)priv
2455 + sizeof(struct orinoco_private)); 2450 + sizeof(struct orinoco_private));
2456 else 2451 else
2457 priv->card = NULL; 2452 priv->card = NULL;
@@ -2556,6 +2551,7 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
2556 } 2551 }
2557 2552
2558 len = le16_to_cpu(essidbuf.len); 2553 len = le16_to_cpu(essidbuf.len);
2554 BUG_ON(len > IW_ESSID_MAX_SIZE);
2559 2555
2560 memset(buf, 0, IW_ESSID_MAX_SIZE+1); 2556 memset(buf, 0, IW_ESSID_MAX_SIZE+1);
2561 memcpy(buf, p, len); 2557 memcpy(buf, p, len);
@@ -2924,13 +2920,14 @@ static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
2924 memset(&essidbuf, 0, sizeof(essidbuf)); 2920 memset(&essidbuf, 0, sizeof(essidbuf));
2925 2921
2926 if (erq->flags) { 2922 if (erq->flags) {
2927 if (erq->length > IW_ESSID_MAX_SIZE) 2923 /* iwconfig includes the NUL in the specified length */
2924 if (erq->length > IW_ESSID_MAX_SIZE+1)
2928 return -E2BIG; 2925 return -E2BIG;
2929 2926
2930 if (copy_from_user(&essidbuf, erq->pointer, erq->length)) 2927 if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2931 return -EFAULT; 2928 return -EFAULT;
2932 2929
2933 essidbuf[erq->length] = '\0'; 2930 essidbuf[IW_ESSID_MAX_SIZE] = '\0';
2934 } 2931 }
2935 2932
2936 if (orinoco_lock(priv, &flags) != 0) 2933 if (orinoco_lock(priv, &flags) != 0)
@@ -3856,7 +3853,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3856 { SIOCIWFIRSTPRIV + 0x7, 0, 3853 { SIOCIWFIRSTPRIV + 0x7, 0,
3857 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 3854 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3858 "get_ibssport" }, 3855 "get_ibssport" },
3859 { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
3860 }; 3856 };
3861 3857
3862 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]); 3858 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
@@ -3944,14 +3940,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3944 err = orinoco_ioctl_getibssport(dev, wrq); 3940 err = orinoco_ioctl_getibssport(dev, wrq);
3945 break; 3941 break;
3946 3942
3947 case SIOCIWLASTPRIV:
3948 err = orinoco_debug_dump_recs(dev);
3949 if (err)
3950 printk(KERN_ERR "%s: Unable to dump records (%d)\n",
3951 dev->name, err);
3952 break;
3953
3954
3955 default: 3943 default:
3956 err = -EOPNOTSUPP; 3944 err = -EOPNOTSUPP;
3957 } 3945 }
@@ -3965,187 +3953,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3965 return err; 3953 return err;
3966} 3954}
3967 3955
3968struct {
3969 u16 rid;
3970 char *name;
3971 int displaytype;
3972#define DISPLAY_WORDS 0
3973#define DISPLAY_BYTES 1
3974#define DISPLAY_STRING 2
3975#define DISPLAY_XSTRING 3
3976} record_table[] = {
3977#define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
3978 DEBUG_REC(CNFPORTTYPE,WORDS),
3979 DEBUG_REC(CNFOWNMACADDR,BYTES),
3980 DEBUG_REC(CNFDESIREDSSID,STRING),
3981 DEBUG_REC(CNFOWNCHANNEL,WORDS),
3982 DEBUG_REC(CNFOWNSSID,STRING),
3983 DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
3984 DEBUG_REC(CNFSYSTEMSCALE,WORDS),
3985 DEBUG_REC(CNFMAXDATALEN,WORDS),
3986 DEBUG_REC(CNFPMENABLED,WORDS),
3987 DEBUG_REC(CNFPMEPS,WORDS),
3988 DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
3989 DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
3990 DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
3991 DEBUG_REC(CNFOWNNAME,STRING),
3992 DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
3993 DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
3994 DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
3995 DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
3996 DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
3997 DEBUG_REC(CNFDEFAULTKEY0,BYTES),
3998 DEBUG_REC(CNFDEFAULTKEY1,BYTES),
3999 DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
4000 DEBUG_REC(CNFDEFAULTKEY2,BYTES),
4001 DEBUG_REC(CNFDEFAULTKEY3,BYTES),
4002 DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
4003 DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
4004 DEBUG_REC(CNFAUTHENTICATION,WORDS),
4005 DEBUG_REC(CNFMAXASSOCSTA,WORDS),
4006 DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
4007 DEBUG_REC(CNFTXCONTROL,WORDS),
4008 DEBUG_REC(CNFROAMINGMODE,WORDS),
4009 DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
4010 DEBUG_REC(CNFRCVCRCERROR,WORDS),
4011 DEBUG_REC(CNFMMLIFE,WORDS),
4012 DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
4013 DEBUG_REC(CNFBEACONINT,WORDS),
4014 DEBUG_REC(CNFAPPCFINFO,WORDS),
4015 DEBUG_REC(CNFSTAPCFINFO,WORDS),
4016 DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
4017 DEBUG_REC(CNFTIMCTRL,WORDS),
4018 DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
4019 DEBUG_REC(CNFENHSECURITY,WORDS),
4020 DEBUG_REC(CNFGROUPADDRESSES,BYTES),
4021 DEBUG_REC(CNFCREATEIBSS,WORDS),
4022 DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
4023 DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
4024 DEBUG_REC(CNFTXRATECONTROL,WORDS),
4025 DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
4026 DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
4027 DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
4028 DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
4029 DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
4030 DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
4031 DEBUG_REC(CNFTXKEY_AGERE,WORDS),
4032 DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
4033 DEBUG_REC(CNFBASICRATES,WORDS),
4034 DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
4035 DEBUG_REC(CNFTICKTIME,WORDS),
4036 DEBUG_REC(CNFSCANREQUEST,WORDS),
4037 DEBUG_REC(CNFJOINREQUEST,WORDS),
4038 DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
4039 DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
4040 DEBUG_REC(MAXLOADTIME,WORDS),
4041 DEBUG_REC(DOWNLOADBUFFER,WORDS),
4042 DEBUG_REC(PRIID,WORDS),
4043 DEBUG_REC(PRISUPRANGE,WORDS),
4044 DEBUG_REC(CFIACTRANGES,WORDS),
4045 DEBUG_REC(NICSERNUM,XSTRING),
4046 DEBUG_REC(NICID,WORDS),
4047 DEBUG_REC(MFISUPRANGE,WORDS),
4048 DEBUG_REC(CFISUPRANGE,WORDS),
4049 DEBUG_REC(CHANNELLIST,WORDS),
4050 DEBUG_REC(REGULATORYDOMAINS,WORDS),
4051 DEBUG_REC(TEMPTYPE,WORDS),
4052/* DEBUG_REC(CIS,BYTES), */
4053 DEBUG_REC(STAID,WORDS),
4054 DEBUG_REC(CURRENTSSID,STRING),
4055 DEBUG_REC(CURRENTBSSID,BYTES),
4056 DEBUG_REC(COMMSQUALITY,WORDS),
4057 DEBUG_REC(CURRENTTXRATE,WORDS),
4058 DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
4059 DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
4060 DEBUG_REC(PROTOCOLRSPTIME,WORDS),
4061 DEBUG_REC(SHORTRETRYLIMIT,WORDS),
4062 DEBUG_REC(LONGRETRYLIMIT,WORDS),
4063 DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
4064 DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
4065 DEBUG_REC(CFPOLLABLE,WORDS),
4066 DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
4067 DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
4068 DEBUG_REC(OWNMACADDR,BYTES),
4069 DEBUG_REC(SCANRESULTSTABLE,WORDS),
4070 DEBUG_REC(PHYTYPE,WORDS),
4071 DEBUG_REC(CURRENTCHANNEL,WORDS),
4072 DEBUG_REC(CURRENTPOWERSTATE,WORDS),
4073 DEBUG_REC(CCAMODE,WORDS),
4074 DEBUG_REC(SUPPORTEDDATARATES,WORDS),
4075 DEBUG_REC(BUILDSEQ,BYTES),
4076 DEBUG_REC(FWID,XSTRING)
4077#undef DEBUG_REC
4078};
4079
4080#define DEBUG_LTV_SIZE 128
4081
4082static int orinoco_debug_dump_recs(struct net_device *dev)
4083{
4084 struct orinoco_private *priv = netdev_priv(dev);
4085 hermes_t *hw = &priv->hw;
4086 u8 *val8;
4087 u16 *val16;
4088 int i,j;
4089 u16 length;
4090 int err;
4091
4092 /* I'm not sure: we might have a lock here, so we'd better go
4093 atomic, just in case. */
4094 val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
4095 if (! val8)
4096 return -ENOMEM;
4097 val16 = (u16 *)val8;
4098
4099 for (i = 0; i < ARRAY_SIZE(record_table); i++) {
4100 u16 rid = record_table[i].rid;
4101 int len;
4102
4103 memset(val8, 0, DEBUG_LTV_SIZE + 2);
4104
4105 err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
4106 &length, val8);
4107 if (err) {
4108 DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
4109 continue;
4110 }
4111 val16 = (u16 *)val8;
4112 if (length == 0)
4113 continue;
4114
4115 printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
4116 record_table[i].name,
4117 rid, length, (length-1)*2);
4118 len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
4119
4120 switch (record_table[i].displaytype) {
4121 case DISPLAY_WORDS:
4122 for (j = 0; j < len / 2; j++)
4123 printk("%04X-", le16_to_cpu(val16[j]));
4124 break;
4125
4126 case DISPLAY_BYTES:
4127 default:
4128 for (j = 0; j < len; j++)
4129 printk("%02X:", val8[j]);
4130 break;
4131
4132 case DISPLAY_STRING:
4133 len = min(len, le16_to_cpu(val16[0])+2);
4134 val8[len] = '\0';
4135 printk("\"%s\"", (char *)&val16[1]);
4136 break;
4137
4138 case DISPLAY_XSTRING:
4139 printk("'%s'", (char *)val8);
4140 }
4141
4142 printk("\n");
4143 }
4144
4145 kfree(val8);
4146
4147 return 0;
4148}
4149 3956
4150/********************************************************************/ 3957/********************************************************************/
4151/* Debugging */ 3958/* Debugging */
@@ -4219,7 +4026,6 @@ EXPORT_SYMBOL(free_orinocodev);
4219 4026
4220EXPORT_SYMBOL(__orinoco_up); 4027EXPORT_SYMBOL(__orinoco_up);
4221EXPORT_SYMBOL(__orinoco_down); 4028EXPORT_SYMBOL(__orinoco_down);
4222EXPORT_SYMBOL(orinoco_stop);
4223EXPORT_SYMBOL(orinoco_reinit_firmware); 4029EXPORT_SYMBOL(orinoco_reinit_firmware);
4224 4030
4225EXPORT_SYMBOL(orinoco_interrupt); 4031EXPORT_SYMBOL(orinoco_interrupt);