wext.c revision 0a54917c3fc295cb61f3fb52373c173fd3b69f48
1cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/* Wireless extensions support. 2cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * 3cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * See copyright notice in main.c 4cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 55a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 6cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include <linux/kernel.h> 7cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include <linux/if_arp.h> 8cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include <linux/wireless.h> 9cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include <linux/ieee80211.h> 10cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include <net/iw_handler.h> 11ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy#include <net/cfg80211.h> 12cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 13cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "hermes.h" 14cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "hermes_rid.h" 15cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "orinoco.h" 16cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 17cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "hw.h" 18cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "mic.h" 19cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "scan.h" 20cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "main.h" 21cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 22cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#include "wext.h" 23cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 24cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy#define MAX_RID_LEN 1024 25cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 264af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy/* Helper routine to record keys 275b0691508aa99d309101a49b4b084dc16b3d7019Andrey Borzenkov * It is called under orinoco_lock so it may not sleep */ 284af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroystatic int orinoco_set_key(struct orinoco_private *priv, int index, 294af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy enum orinoco_alg alg, const u8 *key, int key_len, 304af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy const u8 *seq, int seq_len) 314af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy{ 324af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy kzfree(priv->keys[index].key); 334af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy kzfree(priv->keys[index].seq); 344af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 354af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (key_len) { 365b0691508aa99d309101a49b4b084dc16b3d7019Andrey Borzenkov priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC); 374af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (!priv->keys[index].key) 384af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy goto nomem; 394af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy } else 404af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].key = NULL; 414af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 424af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (seq_len) { 435b0691508aa99d309101a49b4b084dc16b3d7019Andrey Borzenkov priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC); 444af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (!priv->keys[index].seq) 454af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy goto free_key; 464af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy } else 474af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].seq = NULL; 484af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 494af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].key_len = key_len; 504af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].seq_len = seq_len; 514af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 524af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (key_len) 534af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy memcpy(priv->keys[index].key, key, key_len); 544af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (seq_len) 554af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy memcpy(priv->keys[index].seq, seq, seq_len); 564af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 574af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy switch (alg) { 584af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy case ORINOCO_ALG_TKIP: 594af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].cipher = WLAN_CIPHER_SUITE_TKIP; 604af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy break; 614af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 624af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy case ORINOCO_ALG_WEP: 634af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].cipher = (key_len > SMALL_KEY_SIZE) ? 644af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy WLAN_CIPHER_SUITE_WEP104 : WLAN_CIPHER_SUITE_WEP40; 654af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy break; 664af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 674af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy case ORINOCO_ALG_NONE: 684af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy default: 694af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].cipher = 0; 704af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy break; 714af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy } 724af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 734af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy return 0; 744af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 754af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroyfree_key: 764af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy kfree(priv->keys[index].key); 774af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].key = NULL; 784af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 794af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroynomem: 804af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].key_len = 0; 814af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].seq_len = 0; 824af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[index].cipher = 0; 834af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 844af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy return -ENOMEM; 854af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy} 864af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 87cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) 88cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 89ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 90cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_t *hw = &priv->hw; 91cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_statistics *wstats = &priv->wstats; 92cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err; 93cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 94cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 95cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!netif_device_present(dev)) { 96cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n", 97cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy dev->name); 98cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return NULL; /* FIXME: Can we do better than this? */ 99cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 100cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 101cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* If busy, return the old stats. Returning NULL may cause 102cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * the interface to disappear from /proc/net/wireless */ 103cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 104cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return wstats; 105cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 106cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* We can't really wait for the tallies inquiry command to 107cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * complete, so we just use the previous results and trigger 108cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * a new tallies inquiry command for next time - Jean II */ 109cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* FIXME: Really we should wait for the inquiry to come back - 110cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * as it is the stats we give don't make a whole lot of sense. 111cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * Unfortunately, it's not clear how to do that within the 112cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * wireless extensions framework: I think we're in user 113cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * context, but a lock seems to be held by the time we get in 114cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * here so we're not safe to sleep here. */ 115cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_inquire(hw, HERMES_INQ_TALLIES); 116cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1175217c571c898371c540e49671600d54346b2e123David Kilroy if (priv->iw_mode == NL80211_IFTYPE_ADHOC) { 118cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memset(&wstats->qual, 0, sizeof(wstats->qual)); 119cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* If a spy address is defined, we report stats of the 120cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * first spy address - Jean II */ 121cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (SPY_NUMBER(priv)) { 122cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.qual = priv->spy_data.spy_stat[0].qual; 123cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.level = priv->spy_data.spy_stat[0].level; 124cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.noise = priv->spy_data.spy_stat[0].noise; 125cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.updated = 126cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->spy_data.spy_stat[0].updated; 127cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 128cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 129cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct { 130cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy __le16 qual, signal, noise, unused; 131ba2d3587912f82d1ab4367975b1df460db60fb1eEric Dumazet } __packed cq; 132cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 133cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = HERMES_READ_RECORD(hw, USER_BAP, 134cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_RID_COMMSQUALITY, &cq); 135cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 136cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!err) { 137cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.qual = (int)le16_to_cpu(cq.qual); 138cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; 139cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; 140cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wstats->qual.updated = 141cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 142cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 143cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 144cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 145cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 146cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return wstats; 147cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 148cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 149cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/********************************************************************/ 150cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/* Wireless extensions */ 151cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/********************************************************************/ 152cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 153cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setwap(struct net_device *dev, 154cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 155cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct sockaddr *ap_addr, 156cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 157cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 158ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 159cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = -EINPROGRESS; /* Call commit handler */ 160cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 161cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 162cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 163cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 164cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 165cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 166cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 167cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Enable automatic roaming - no sanity checks are needed */ 168cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 || 169cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) { 170cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->bssid_fixed = 0; 171cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memset(priv->desired_bssid, 0, ETH_ALEN); 172cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 173cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* "off" means keep existing connection */ 174cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (ap_addr->sa_data[0] == 0) { 175cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy __orinoco_hw_set_wap(priv); 176cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = 0; 177cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 178cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 179cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 180cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 181cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->firmware_type == FIRMWARE_TYPE_AGERE) { 182cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't " 183cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "support manual roaming\n", 184cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy dev->name); 185cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EOPNOTSUPP; 186cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 187cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 188cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1895217c571c898371c540e49671600d54346b2e123David Kilroy if (priv->iw_mode != NL80211_IFTYPE_STATION) { 190cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_WARNING "%s: Manual roaming supported only in " 191cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "managed mode\n", dev->name); 192cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EOPNOTSUPP; 193cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 194cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 195cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 196cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Intersil firmware hangs without Desired ESSID */ 197cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL && 198cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy strlen(priv->desired_essid) == 0) { 199cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_WARNING "%s: Desired ESSID must be set for " 200cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "manual roaming\n", dev->name); 201cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EOPNOTSUPP; 202cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 203cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 204cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 205cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Finally, enable manual roaming */ 206cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->bssid_fixed = 1; 207cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN); 208cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 209cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 210cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 211cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 212cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 213cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 214cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getwap(struct net_device *dev, 215cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 216cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct sockaddr *ap_addr, 217cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 218cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 219ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 220cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 221cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 222cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 223cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 224cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 225cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 226cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 227cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ap_addr->sa_family = ARPHRD_ETHER; 2282b2603515e26466685895e93cae59bc061389f11David Kilroy err = orinoco_hw_get_current_bssid(priv, ap_addr->sa_data); 229cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 230cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 231cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 232cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 233cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 234cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 235cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setiwencode(struct net_device *dev, 236cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 237cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *erq, 238cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *keybuf) 239cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 240ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 241cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int index = (erq->flags & IW_ENCODE_INDEX) - 1; 242cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int setindex = priv->tx_key; 2435c9f41e285ad60013f0962746192769f899757beDavid Kilroy enum orinoco_alg encode_alg = priv->encode_alg; 244cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int restricted = priv->wep_restrict; 245cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = -EINPROGRESS; /* Call commit handler */ 246cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 247cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 248cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_wep) 249cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EOPNOTSUPP; 250cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 251cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->pointer) { 252cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* We actually have a key to set - check its length */ 253cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->length > LARGE_KEY_SIZE) 254cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -E2BIG; 255cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 256cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep) 257cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -E2BIG; 258cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 259cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 260cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 261cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 262cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 263cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Clear any TKIP key we have */ 2645c9f41e285ad60013f0962746192769f899757beDavid Kilroy if ((priv->has_wpa) && (priv->encode_alg == ORINOCO_ALG_TKIP)) 265cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy (void) orinoco_clear_tkip_key(priv, setindex); 266cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 267cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->length > 0) { 268cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 269cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy index = priv->tx_key; 270cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 271cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Switch on WEP if off */ 2725c9f41e285ad60013f0962746192769f899757beDavid Kilroy if (encode_alg != ORINOCO_ALG_WEP) { 273cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy setindex = index; 2745c9f41e285ad60013f0962746192769f899757beDavid Kilroy encode_alg = ORINOCO_ALG_WEP; 275cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 276cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 277cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Important note : if the user do "iwconfig eth0 enc off", 278cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * we will arrive there with an index of -1. This is valid 279cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * but need to be taken care off... Jean II */ 280cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) { 281cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((index != -1) || (erq->flags == 0)) { 282cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 283cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 284cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 285cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 286cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Set the index : Check that the key is valid */ 2874af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (priv->keys[index].key_len == 0) { 288cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 289cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 290cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 291cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy setindex = index; 292cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 293cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 294cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 295cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->flags & IW_ENCODE_DISABLED) 2965c9f41e285ad60013f0962746192769f899757beDavid Kilroy encode_alg = ORINOCO_ALG_NONE; 297cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->flags & IW_ENCODE_OPEN) 298cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy restricted = 0; 299cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->flags & IW_ENCODE_RESTRICTED) 300cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy restricted = 1; 301cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 302cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->pointer && erq->length > 0) { 3034af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy err = orinoco_set_key(priv, index, ORINOCO_ALG_WEP, keybuf, 3044af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy erq->length, NULL, 0); 305cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 306cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->tx_key = setindex; 307cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 308cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Try fast key change if connected and only keys are changed */ 309cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((priv->encode_alg == encode_alg) && 310cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy (priv->wep_restrict == restricted) && 311cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy netif_carrier_ok(dev)) { 312cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = __orinoco_hw_setup_wepkeys(priv); 313cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* No need to commit if successful */ 314cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 315cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 316cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 317cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->encode_alg = encode_alg; 318cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wep_restrict = restricted; 319cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 320cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 321cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 322cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 323cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 324cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 325cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 326cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getiwencode(struct net_device *dev, 327cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 328cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *erq, 329cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *keybuf) 330cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 331ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 332cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int index = (erq->flags & IW_ENCODE_INDEX) - 1; 333cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 334cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 335cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_wep) 336cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EOPNOTSUPP; 337cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 338cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 339cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 340cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 341cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) 342cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy index = priv->tx_key; 343cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 344cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->flags = 0; 345cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->encode_alg) 346cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->flags |= IW_ENCODE_DISABLED; 347cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->flags |= index + 1; 348cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 349cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->wep_restrict) 350cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->flags |= IW_ENCODE_RESTRICTED; 351cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else 352cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->flags |= IW_ENCODE_OPEN; 353cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 3544af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy erq->length = priv->keys[index].key_len; 355cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 3564af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy memcpy(keybuf, priv->keys[index].key, erq->length); 357cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 358cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 359cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 360cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 361cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 362cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setessid(struct net_device *dev, 363cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 364cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *erq, 365cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *essidbuf) 366cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 367ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 368cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 369cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 370cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it 371cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * anyway... - Jean II */ 372cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 373cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Hum... Should not use Wireless Extension constant (may change), 374cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * should use our own... - Jean II */ 375cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->length > IW_ESSID_MAX_SIZE) 376cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -E2BIG; 377cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 378cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 379cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 380cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 381cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */ 382cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memset(priv->desired_essid, 0, sizeof(priv->desired_essid)); 383cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 384cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* If not ANY, get the new ESSID */ 385cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (erq->flags) 386cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memcpy(priv->desired_essid, essidbuf, erq->length); 387cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 388cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 389cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 390cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINPROGRESS; /* Call commit handler */ 391cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 392cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 393cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getessid(struct net_device *dev, 394cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 395cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *erq, 396cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *essidbuf) 397cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 398ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 399cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int active; 400cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 401cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 402cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 403cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (netif_running(dev)) { 404cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = orinoco_hw_get_essid(priv, &active, essidbuf); 405cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err < 0) 406cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 407cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->length = err; 408cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 409cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 410cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 411cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE); 412cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->length = strlen(priv->desired_essid); 413cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 414cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 415cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 416cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy erq->flags = 1; 417cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 418cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 419cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 420cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 421cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setfreq(struct net_device *dev, 422cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 423cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_freq *frq, 424cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 425cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 426ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 427cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int chan = -1; 428cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 429cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = -EINPROGRESS; /* Call commit handler */ 430cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 431cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* In infrastructure mode the AP sets the channel */ 4325217c571c898371c540e49671600d54346b2e123David Kilroy if (priv->iw_mode == NL80211_IFTYPE_STATION) 433cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 434cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 435cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((frq->e == 0) && (frq->m <= 1000)) { 436cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Setting by channel number */ 437cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy chan = frq->m; 438cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 439cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Setting by frequency */ 440cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int denom = 1; 441cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int i; 442cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 443cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Calculate denominator to rescale to MHz */ 444cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy for (i = 0; i < (6 - frq->e); i++) 445cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy denom *= 10; 446cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 447cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy chan = ieee80211_freq_to_dsss_chan(frq->m / denom); 448cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 449cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 450cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((chan < 1) || (chan > NUM_CHANNELS) || 451cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy !(priv->channel_mask & (1 << (chan-1)))) 452cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINVAL; 453cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 454cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 455cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 456cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 457cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->channel = chan; 4585217c571c898371c540e49671600d54346b2e123David Kilroy if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 459cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Fast channel change - no commit if successful */ 460cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_t *hw = &priv->hw; 461b42f2074dedef559ecf72dce61a6501f9f9b273aDavid Kilroy err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | 462cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_TEST_SET_CHANNEL, 463cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy chan, NULL); 464cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 465cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 466cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 467cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 468cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 469cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 470cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getfreq(struct net_device *dev, 471cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 472cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_freq *frq, 473cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 474cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 475ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 476cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int tmp; 477cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 478cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Locking done in there */ 479cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy tmp = orinoco_hw_get_freq(priv); 480cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (tmp < 0) 481cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return tmp; 482cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 483cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy frq->m = tmp * 100000; 484cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy frq->e = 1; 485cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 486cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 487cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 488cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 489cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getsens(struct net_device *dev, 490cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 491cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *srq, 492cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 493cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 494ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 495cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_t *hw = &priv->hw; 496cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy u16 val; 497cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err; 498cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 499cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 500cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_sensitivity) 501cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EOPNOTSUPP; 502cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 503cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 504cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 505cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = hermes_read_wordrec(hw, USER_BAP, 506cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_RID_CNFSYSTEMSCALE, &val); 507cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 508cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 509cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 510cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 511cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 512cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy srq->value = val; 513cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy srq->fixed = 0; /* auto */ 514cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 515cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 516cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 517cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 518cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setsens(struct net_device *dev, 519cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 520cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *srq, 521cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 522cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 523ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 524cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int val = srq->value; 525cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 526cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 527cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_sensitivity) 528cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EOPNOTSUPP; 529cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 530cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((val < 1) || (val > 3)) 531cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINVAL; 532cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 533cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 534cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 535cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->ap_density = val; 536cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 537cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 538cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINPROGRESS; /* Call commit handler */ 539cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 540cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 541cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setrate(struct net_device *dev, 542cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 543cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *rrq, 544cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 545cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 546ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 547cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int ratemode; 548cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int bitrate; /* 100s of kilobits */ 549cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 550cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 551cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* As the user space doesn't know our highest rate, it uses -1 552cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * to ask us to set the highest rate. Test it using "iwconfig 553cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * ethX rate auto" - Jean II */ 554cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (rrq->value == -1) 555cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy bitrate = 110; 556cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else { 557cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (rrq->value % 100000) 558cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINVAL; 559cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy bitrate = rrq->value / 100000; 560cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 561cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 562cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ratemode = orinoco_get_bitratemode(bitrate, !rrq->fixed); 563cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 564cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (ratemode == -1) 565cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINVAL; 566cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 567cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 568cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 569cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->bitratemode = ratemode; 570cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 571cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 572cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINPROGRESS; 573cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 574cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 575cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getrate(struct net_device *dev, 576cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 577cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *rrq, 578cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 579cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 580ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 581cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 582cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int bitrate, automatic; 583cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 584cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 585cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 586cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 587cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 588cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_get_ratemode_cfg(priv->bitratemode, &bitrate, &automatic); 589cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 590cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* If the interface is running we try to find more about the 591cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy current mode */ 5929736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy if (netif_running(dev)) { 5939736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy int act_bitrate; 5949736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy int lerr; 5959736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy 5969736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy /* Ignore errors if we can't get the actual bitrate */ 5979736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy lerr = orinoco_hw_get_act_bitrate(priv, &act_bitrate); 5989736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy if (!lerr) 5999736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy bitrate = act_bitrate; 6009736ebfe39687f2edde9e97fc188f013a31048f6David Kilroy } 601cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 602cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 603cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 604cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy rrq->value = bitrate; 605cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy rrq->fixed = !automatic; 606cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy rrq->disabled = 0; 607cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 608cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 609cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 610cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 611cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setpower(struct net_device *dev, 612cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 613cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *prq, 614cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 615cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 616ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 617cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = -EINPROGRESS; /* Call commit handler */ 618cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 619cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 620cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 621cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 622cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 623cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (prq->disabled) { 624cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_on = 0; 625cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 626cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (prq->flags & IW_POWER_MODE) { 627cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_POWER_UNICAST_R: 628cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_mcast = 0; 629cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_on = 1; 630cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 631cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_POWER_ALL_R: 632cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_mcast = 1; 633cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_on = 1; 634cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 635cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_POWER_ON: 636cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* No flags : but we may have a value - Jean II */ 637cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 638cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy default: 639cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 640cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 641cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 642cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 643cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (prq->flags & IW_POWER_TIMEOUT) { 644cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_on = 1; 645cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_timeout = prq->value / 1000; 646cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 647cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (prq->flags & IW_POWER_PERIOD) { 648cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_on = 1; 649cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->pm_period = prq->value / 1000; 650cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 651cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* It's valid to not have a value if we are just toggling 652cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * the flags... Jean II */ 653cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->pm_on) { 654cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 655cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 656cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 657cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 658cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 659cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 660cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 661cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 662cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 663cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 664cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 665cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getpower(struct net_device *dev, 666cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 667cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *prq, 668cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 669cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 670ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 671cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_t *hw = &priv->hw; 672cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 673cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy u16 enable, period, timeout, mcast; 674cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 675cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 676cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 677cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 678cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 679cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = hermes_read_wordrec(hw, USER_BAP, 680cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_RID_CNFPMENABLED, &enable); 681cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 682cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 683cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 684cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = hermes_read_wordrec(hw, USER_BAP, 685cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_RID_CNFMAXSLEEPDURATION, &period); 686cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 687cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 688cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 689cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = hermes_read_wordrec(hw, USER_BAP, 690cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_RID_CNFPMHOLDOVERDURATION, &timeout); 691cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 692cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 693cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 694cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = hermes_read_wordrec(hw, USER_BAP, 695cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy HERMES_RID_CNFMULTICASTRECEIVE, &mcast); 696cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 697cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 698cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 699cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->disabled = !enable; 700cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Note : by default, display the period */ 701cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 702cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->flags = IW_POWER_TIMEOUT; 703cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->value = timeout * 1000; 704cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 705cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->flags = IW_POWER_PERIOD; 706cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->value = period * 1000; 707cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 708cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (mcast) 709cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->flags |= IW_POWER_ALL_R; 710cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else 711cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy prq->flags |= IW_POWER_UNICAST_R; 712cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 713cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 714cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 715cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 716cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 717cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 718cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 719cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_set_encodeext(struct net_device *dev, 720cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 721cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, 722cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 723cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 724ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 725cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *encoding = &wrqu->encoding; 726cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 727cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int idx, alg = ext->alg, set_key = 1; 728cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 729cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = -EINVAL; 730cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 731cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 732cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 733cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 734cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Determine and validate the key index */ 735cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy idx = encoding->flags & IW_ENCODE_INDEX; 736cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (idx) { 737cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((idx < 1) || (idx > 4)) 738cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 739cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy idx--; 740cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else 741cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy idx = priv->tx_key; 742cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 743cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (encoding->flags & IW_ENCODE_DISABLED) 744cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy alg = IW_ENCODE_ALG_NONE; 745cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 746cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) { 747cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Clear any TKIP TX key we had */ 748cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy (void) orinoco_clear_tkip_key(priv, priv->tx_key); 749cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 750cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 751cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 752cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->tx_key = idx; 753cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy set_key = ((alg == IW_ENCODE_ALG_TKIP) || 754cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy (ext->key_len > 0)) ? 1 : 0; 755cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 756cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 757cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (set_key) { 758cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Set the requested key first */ 759cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (alg) { 760cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_ENCODE_ALG_NONE: 7615c9f41e285ad60013f0962746192769f899757beDavid Kilroy priv->encode_alg = ORINOCO_ALG_NONE; 7624af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy err = orinoco_set_key(priv, idx, ORINOCO_ALG_NONE, 7634af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy NULL, 0, NULL, 0); 764cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 765cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 766cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_ENCODE_ALG_WEP: 7674af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy if (ext->key_len <= 0) 768cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 769cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 7705c9f41e285ad60013f0962746192769f899757beDavid Kilroy priv->encode_alg = ORINOCO_ALG_WEP; 7714af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy err = orinoco_set_key(priv, idx, ORINOCO_ALG_WEP, 7724af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy ext->key, ext->key_len, NULL, 0); 773cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 774cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 775cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_ENCODE_ALG_TKIP: 776cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { 777cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy u8 *tkip_iv = NULL; 778cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 779cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_wpa || 7804af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy (ext->key_len > sizeof(struct orinoco_tkip_key))) 781cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 782cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 7835c9f41e285ad60013f0962746192769f899757beDavid Kilroy priv->encode_alg = ORINOCO_ALG_TKIP; 784cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 785cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 786cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy tkip_iv = &ext->rx_seq[0]; 787cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 7884af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy err = orinoco_set_key(priv, idx, ORINOCO_ALG_TKIP, 7894af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy ext->key, ext->key_len, tkip_iv, 7904af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy ORINOCO_SEQ_LEN); 7914af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy 79298e5f404485d5d11b15e8351535a0e064a37647cDavid Kilroy err = __orinoco_hw_set_tkip_key(priv, idx, 793cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 7944af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy priv->keys[idx].key, 79516e158480d542f3909b5aca8b125af986ae128c1David Kilroy tkip_iv, ORINOCO_SEQ_LEN, NULL, 0); 796cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 797cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_ERR "%s: Error %d setting TKIP key" 798cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "\n", dev->name, err); 799cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 800cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 801cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 802cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy default: 803cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 804cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 805cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 806cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINPROGRESS; 807cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 808cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 809cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 810cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 811cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 812cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 813cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_get_encodeext(struct net_device *dev, 814cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 815cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, 816cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 817cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 818ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 819cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *encoding = &wrqu->encoding; 820cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 821cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int idx, max_key_len; 822cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 823cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err; 824cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 825cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 826cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 827cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 828cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 829cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy max_key_len = encoding->length - sizeof(*ext); 830cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (max_key_len < 0) 831cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 832cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 833cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy idx = encoding->flags & IW_ENCODE_INDEX; 834cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (idx) { 835cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((idx < 1) || (idx > 4)) 836cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 837cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy idx--; 838cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else 839cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy idx = priv->tx_key; 840cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 841cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy encoding->flags = idx + 1; 842cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memset(ext, 0, sizeof(*ext)); 843cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 844cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (priv->encode_alg) { 8455c9f41e285ad60013f0962746192769f899757beDavid Kilroy case ORINOCO_ALG_NONE: 8465c9f41e285ad60013f0962746192769f899757beDavid Kilroy ext->alg = IW_ENCODE_ALG_NONE; 847cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ext->key_len = 0; 848cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy encoding->flags |= IW_ENCODE_DISABLED; 849cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 8505c9f41e285ad60013f0962746192769f899757beDavid Kilroy case ORINOCO_ALG_WEP: 8515c9f41e285ad60013f0962746192769f899757beDavid Kilroy ext->alg = IW_ENCODE_ALG_WEP; 8524af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy ext->key_len = min(priv->keys[idx].key_len, max_key_len); 8534af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy memcpy(ext->key, priv->keys[idx].key, ext->key_len); 854cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy encoding->flags |= IW_ENCODE_ENABLED; 855cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 8565c9f41e285ad60013f0962746192769f899757beDavid Kilroy case ORINOCO_ALG_TKIP: 8575c9f41e285ad60013f0962746192769f899757beDavid Kilroy ext->alg = IW_ENCODE_ALG_TKIP; 8584af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy ext->key_len = min(priv->keys[idx].key_len, max_key_len); 8594af198fb7a99b07980b1bd52df550ba3f24688dfDavid Kilroy memcpy(ext->key, priv->keys[idx].key, ext->key_len); 860cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy encoding->flags |= IW_ENCODE_ENABLED; 861cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 862cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 863cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 864cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = 0; 865cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 866cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 867cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 868cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 869cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 870cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 871cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_set_auth(struct net_device *dev, 872cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 873cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, char *extra) 874cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 875ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 876cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_t *hw = &priv->hw; 877cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *param = &wrqu->param; 878cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 879cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int ret = -EINPROGRESS; 880cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 881cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 882cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 883cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 884cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (param->flags & IW_AUTH_INDEX) { 885cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_WPA_VERSION: 886cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_CIPHER_PAIRWISE: 887cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_CIPHER_GROUP: 888cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_RX_UNENCRYPTED_EAPOL: 889cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_PRIVACY_INVOKED: 890cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_DROP_UNENCRYPTED: 891cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* 892cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * orinoco does not use these parameters 893cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 894cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 895cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 896cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_KEY_MGMT: 897cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* wl_lkm implies value 2 == PSK for Hermes I 898cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * which ties in with WEXT 899cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * no other hints tho :( 900cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 901cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->key_mgmt = param->value; 902cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 903cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 904cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_TKIP_COUNTERMEASURES: 905cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* When countermeasures are enabled, shut down the 906cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * card; when disabled, re-enable the card. This must 907cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * take effect immediately. 908cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * 909cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * TODO: Make sure that the EAPOL message is getting 910cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * out before card disabled 911cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 912cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (param->value) { 913cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->tkip_cm_active = 1; 9140a54917c3fc295cb61f3fb52373c173fd3b69f48David Kilroy ret = hermes_disable_port(hw, 0); 915cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 916cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->tkip_cm_active = 0; 9170a54917c3fc295cb61f3fb52373c173fd3b69f48David Kilroy ret = hermes_enable_port(hw, 0); 918cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 919cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 920cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 921cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_80211_AUTH_ALG: 922cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (param->value & IW_AUTH_ALG_SHARED_KEY) 923cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wep_restrict = 1; 924cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) 925cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wep_restrict = 0; 926cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else 927cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ret = -EINVAL; 928cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 929cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 930cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_WPA_ENABLED: 931cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->has_wpa) { 932cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wpa_enabled = param->value ? 1 : 0; 933cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 934cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (param->value) 935cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ret = -EOPNOTSUPP; 936cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* else silently accept disable of WPA */ 937cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wpa_enabled = 0; 938cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 939cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 940cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 941cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy default: 942cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ret = -EOPNOTSUPP; 943cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 944cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 945cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 946cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return ret; 947cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 948cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 949cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_get_auth(struct net_device *dev, 950cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 951cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, char *extra) 952cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 953ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 954cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_param *param = &wrqu->param; 955cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 956cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int ret = 0; 957cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 958cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 959cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 960cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 961cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (param->flags & IW_AUTH_INDEX) { 962cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_KEY_MGMT: 963cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy param->value = priv->key_mgmt; 964cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 965cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 966cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_TKIP_COUNTERMEASURES: 967cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy param->value = priv->tkip_cm_active; 968cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 969cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 970cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_80211_AUTH_ALG: 971cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->wep_restrict) 972cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy param->value = IW_AUTH_ALG_SHARED_KEY; 973cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else 974cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy param->value = IW_AUTH_ALG_OPEN_SYSTEM; 975cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 976cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 977cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_AUTH_WPA_ENABLED: 978cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy param->value = priv->wpa_enabled; 979cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 980cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 981cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy default: 982cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ret = -EOPNOTSUPP; 983cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 984cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 985cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 986cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return ret; 987cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 988cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 989cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_set_genie(struct net_device *dev, 990cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 991cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, char *extra) 992cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 993ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 994cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy u8 *buf; 995cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 996cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 997cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* cut off at IEEE80211_MAX_DATA_LEN */ 998cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) || 999cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy (wrqu->data.length && (extra == NULL))) 1000cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINVAL; 1001cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1002cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (wrqu->data.length) { 10031d66fa777d674da3a5172dcdd930f8928b1904c6Julia Lawall buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL); 1004cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (buf == NULL) 1005cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -ENOMEM; 1006cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else 1007cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy buf = NULL; 1008cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1009cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) { 1010cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy kfree(buf); 1011cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1012cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1013cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1014cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy kfree(priv->wpa_ie); 1015cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wpa_ie = buf; 1016cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->wpa_ie_len = wrqu->data.length; 1017cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1018cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (priv->wpa_ie) { 1019cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Looks like wl_lkm wants to check the auth alg, and 1020cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * somehow pass it to the firmware. 1021cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * Instead it just calls the key mgmt rid 1022cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * - we do this in set auth. 1023cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 1024cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1025cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1026cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1027cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 1028cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1029cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1030cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_get_genie(struct net_device *dev, 1031cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1032cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, char *extra) 1033cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1034ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1035cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1036cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 1037cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1038cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1039cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1040cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1041cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) { 1042cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wrqu->data.length = 0; 1043cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 1044cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1045cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1046cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (wrqu->data.length < priv->wpa_ie_len) { 1047cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -E2BIG; 1048cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 1049cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1050cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1051cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy wrqu->data.length = priv->wpa_ie_len; 1052cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy memcpy(extra, priv->wpa_ie, priv->wpa_ie_len); 1053cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1054cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroyout: 1055cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1056cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 1057cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1058cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1059cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_set_mlme(struct net_device *dev, 1060cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1061cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy union iwreq_data *wrqu, char *extra) 1062cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1063ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1064cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_mlme *mlme = (struct iw_mlme *)extra; 1065cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1066cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int ret = 0; 1067cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1068cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1069cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1070cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1071cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (mlme->cmd) { 1072cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_MLME_DEAUTH: 1073cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* silently ignore */ 1074cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 1075cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1076cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case IW_MLME_DISASSOC: 107707542d08ee573b6d8281f38430117b52fccaf50aDavid Kilroy 107807542d08ee573b6d8281f38430117b52fccaf50aDavid Kilroy ret = orinoco_hw_disassociate(priv, mlme->addr.sa_data, 107907542d08ee573b6d8281f38430117b52fccaf50aDavid Kilroy mlme->reason_code); 1080cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 108107542d08ee573b6d8281f38430117b52fccaf50aDavid Kilroy 1082cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy default: 1083cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy ret = -EOPNOTSUPP; 1084cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1085cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1086cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1087cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return ret; 1088cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1089cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1090cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_reset(struct net_device *dev, 1091cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1092cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1093cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1094cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1095ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1096cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1097cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!capable(CAP_NET_ADMIN)) 1098cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EPERM; 1099cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1100cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) { 1101cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name); 1102cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1103cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Firmware reset */ 1104cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_reset(&priv->reset_work); 1105cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } else { 1106cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name); 1107cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1108cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy schedule_work(&priv->reset_work); 1109cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1110cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1111cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 1112cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1113cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1114cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setibssport(struct net_device *dev, 1115cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1116cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1117cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1118cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1119cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1120ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1121cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int val = *((int *) extra); 1122cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1123cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1124cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1125cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1126cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 112730fab9e0aecf15ca79bb194bb603203f5e1fde66David Kilroy priv->ibss_port = val; 1128cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1129cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Actually update the mode we are using */ 1130cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy set_port_type(priv); 1131cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1132cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1133cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINPROGRESS; /* Call commit handler */ 1134cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1135cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1136cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getibssport(struct net_device *dev, 1137cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1138cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1139cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1140cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1141ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1142cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int *val = (int *) extra; 1143cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1144cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy *val = priv->ibss_port; 1145cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 1146cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1147cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1148cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setport3(struct net_device *dev, 1149cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1150cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1151cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1152cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1153ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1154cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int val = *((int *) extra); 1155cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 1156cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1157cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1158cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1159cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1160cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1161cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy switch (val) { 1162cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case 0: /* Try to do IEEE ad-hoc mode */ 1163cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_ibss) { 1164cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 1165cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 1166cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1167cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->prefer_port3 = 0; 1168cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1169cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 1170cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1171cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy case 1: /* Try to do Lucent proprietary ad-hoc mode */ 1172cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_port3) { 1173cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 1174cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 1175cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1176cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->prefer_port3 = 1; 1177cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy break; 1178cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1179cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy default: 1180cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINVAL; 1181cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1182cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1183cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!err) { 1184cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* Actually update the mode we are using */ 1185cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy set_port_type(priv); 1186cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy err = -EINPROGRESS; 1187cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy } 1188cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1189cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1190cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1191cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 1192cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1193cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1194cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getport3(struct net_device *dev, 1195cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1196cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1197cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1198cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1199ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1200cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int *val = (int *) extra; 1201cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1202cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy *val = priv->prefer_port3; 1203cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 1204cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1205cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1206cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_setpreamble(struct net_device *dev, 1207cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1208cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1209cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1210cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1211ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1212cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1213cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int val; 1214cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1215cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_preamble) 1216cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EOPNOTSUPP; 1217cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1218cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* 802.11b has recently defined some short preamble. 1219cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * Basically, the Phy header has been reduced in size. 1220cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * This increase performance, especially at high rates 1221cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * (the preamble is transmitted at 1Mb/s), unfortunately 1222cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * this give compatibility troubles... - Jean II */ 1223cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy val = *((int *) extra); 1224cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1225cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1226cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1227cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1228cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (val) 1229cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->preamble = 1; 1230cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy else 1231cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy priv->preamble = 0; 1232cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1233cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1234cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1235cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINPROGRESS; /* Call commit handler */ 1236cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1237cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1238cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getpreamble(struct net_device *dev, 1239cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1240cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1241cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1242cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1243ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1244cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int *val = (int *) extra; 1245cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1246cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->has_preamble) 1247cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EOPNOTSUPP; 1248cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1249cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy *val = priv->preamble; 1250cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 1251cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1252cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1253cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/* ioctl interface to hermes_read_ltv() 1254cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * To use with iwpriv, pass the RID as the token argument, e.g. 1255cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * iwpriv get_rid [0xfc00] 1256cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * At least Wireless Tools 25 is required to use iwpriv. 1257cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * For Wireless Tools 25 and 26 append "dummy" are the end. */ 1258cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_getrid(struct net_device *dev, 1259cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1260cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_point *data, 1261cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1262cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1263ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1264cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy hermes_t *hw = &priv->hw; 1265cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int rid = data->flags; 1266cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy u16 length; 1267cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err; 1268cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1269cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1270cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy /* It's a "get" function, but we don't want users to access the 1271cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * WEP key and other raw firmware data */ 1272cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!capable(CAP_NET_ADMIN)) 1273cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EPERM; 1274cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1275cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (rid < 0xfc00 || rid > 0xffff) 1276cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EINVAL; 1277cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1278cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1279cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return -EBUSY; 1280cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1281b42f2074dedef559ecf72dce61a6501f9f9b273aDavid Kilroy err = hw->ops->read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, 1282b42f2074dedef559ecf72dce61a6501f9f9b273aDavid Kilroy extra); 1283cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (err) 1284cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy goto out; 1285cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1286cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length), 1287cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy MAX_RID_LEN); 1288cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1289cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy out: 1290cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1291cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 1292cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1293cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1294cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1295cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/* Commit handler, called after set operations */ 1296cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic int orinoco_ioctl_commit(struct net_device *dev, 1297cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy struct iw_request_info *info, 1298cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy void *wrqu, 1299cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy char *extra) 1300cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy{ 1301ea60a6aaf55984a13a7150568cc103d006e86ab2David Kilroy struct orinoco_private *priv = ndev_priv(dev); 1302cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy unsigned long flags; 1303cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy int err = 0; 1304cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1305cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (!priv->open) 1306cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return 0; 1307cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1308cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy if (orinoco_lock(priv, &flags) != 0) 1309cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 1310cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1311721aa2f75b00399074eb443fdf16d797b4504a36David Kilroy err = orinoco_commit(priv); 1312cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1313cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy orinoco_unlock(priv, &flags); 1314cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy return err; 1315cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy} 1316cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1317cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic const struct iw_priv_args orinoco_privtab[] = { 1318cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" }, 1319cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" }, 1320cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 1321cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 0, "set_port3" }, 1322cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 1323cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "get_port3" }, 1324cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 1325cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 0, "set_preamble" }, 1326cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 1327cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "get_preamble" }, 1328cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 1329cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 0, "set_ibssport" }, 1330cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 1331cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "get_ibssport" }, 1332cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN, 1333cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy "get_rid" }, 1334cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy}; 1335cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1336cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1337cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/* 1338cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy * Structures to export the Wireless Handlers 1339cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 1340cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1341cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic const iw_handler orinoco_handler[] = { 1342adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWCOMMIT, (iw_handler)orinoco_ioctl_commit), 1343adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname), 1344adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWFREQ, (iw_handler)orinoco_ioctl_setfreq), 1345adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWFREQ, (iw_handler)orinoco_ioctl_getfreq), 1346adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWMODE, (iw_handler)cfg80211_wext_siwmode), 1347adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWMODE, (iw_handler)cfg80211_wext_giwmode), 1348adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWSENS, (iw_handler)orinoco_ioctl_setsens), 1349adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWSENS, (iw_handler)orinoco_ioctl_getsens), 1350adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWRANGE, (iw_handler)cfg80211_wext_giwrange), 1351adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy), 1352adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy), 1353adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy), 1354adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy), 1355adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWAP, (iw_handler)orinoco_ioctl_setwap), 1356adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWAP, (iw_handler)orinoco_ioctl_getwap), 1357adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWSCAN, (iw_handler)cfg80211_wext_siwscan), 1358adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWSCAN, (iw_handler)cfg80211_wext_giwscan), 1359adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWESSID, (iw_handler)orinoco_ioctl_setessid), 1360adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid), 1361adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate), 1362adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate), 1363c3d415030c1a00cc21935c38f8761db46ef1d7ffDavid Kilroy IW_HANDLER(SIOCSIWRTS, (iw_handler)cfg80211_wext_siwrts), 1364c3d415030c1a00cc21935c38f8761db46ef1d7ffDavid Kilroy IW_HANDLER(SIOCGIWRTS, (iw_handler)cfg80211_wext_giwrts), 1365c3d415030c1a00cc21935c38f8761db46ef1d7ffDavid Kilroy IW_HANDLER(SIOCSIWFRAG, (iw_handler)cfg80211_wext_siwfrag), 1366c3d415030c1a00cc21935c38f8761db46ef1d7ffDavid Kilroy IW_HANDLER(SIOCGIWFRAG, (iw_handler)cfg80211_wext_giwfrag), 1367c3d415030c1a00cc21935c38f8761db46ef1d7ffDavid Kilroy IW_HANDLER(SIOCGIWRETRY, (iw_handler)cfg80211_wext_giwretry), 1368adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode), 1369adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode), 1370adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower), 1371adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWPOWER, (iw_handler)orinoco_ioctl_getpower), 1372adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie), 1373adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie), 1374adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme), 1375adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth), 1376adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth), 1377adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext), 1378adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext), 1379cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy}; 1380cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1381cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1382cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy/* 1383cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy Added typecasting since we no longer use iwreq_data -- Moustafa 1384cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy */ 1385cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroystatic const iw_handler orinoco_private_handler[] = { 1386adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [0] = (iw_handler)orinoco_ioctl_reset, 1387adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [1] = (iw_handler)orinoco_ioctl_reset, 1388adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [2] = (iw_handler)orinoco_ioctl_setport3, 1389adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [3] = (iw_handler)orinoco_ioctl_getport3, 1390adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [4] = (iw_handler)orinoco_ioctl_setpreamble, 1391adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [5] = (iw_handler)orinoco_ioctl_getpreamble, 1392adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [6] = (iw_handler)orinoco_ioctl_setibssport, 1393adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [7] = (iw_handler)orinoco_ioctl_getibssport, 1394adc009e2e76b222006beb7f9df6d0aee051509d2Joe Perches [9] = (iw_handler)orinoco_ioctl_getrid, 1395cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy}; 1396cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy 1397cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroyconst struct iw_handler_def orinoco_handler_def = { 1398cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .num_standard = ARRAY_SIZE(orinoco_handler), 1399cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .num_private = ARRAY_SIZE(orinoco_private_handler), 1400cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .num_private_args = ARRAY_SIZE(orinoco_privtab), 1401cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .standard = orinoco_handler, 1402cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .private = orinoco_private_handler, 1403cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .private_args = orinoco_privtab, 1404cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy .get_wireless_stats = orinoco_get_wireless_stats, 1405cb1576a829826d56fab59e22aa3af8c5a7db9936David Kilroy}; 1406