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