0001
0002
0003
0004
0005 #include <linux/slab.h>
0006 #include <linux/kernel.h>
0007 #include <linux/if_arp.h>
0008 #include <linux/wireless.h>
0009 #include <linux/ieee80211.h>
0010 #include <linux/etherdevice.h>
0011 #include <net/iw_handler.h>
0012 #include <net/cfg80211.h>
0013 #include <net/cfg80211-wext.h>
0014
0015 #include "hermes.h"
0016 #include "hermes_rid.h"
0017 #include "orinoco.h"
0018
0019 #include "hw.h"
0020 #include "mic.h"
0021 #include "scan.h"
0022 #include "main.h"
0023
0024 #include "wext.h"
0025
0026 #define MAX_RID_LEN 1024
0027
0028
0029
0030 static int orinoco_set_key(struct orinoco_private *priv, int index,
0031 enum orinoco_alg alg, const u8 *key, int key_len,
0032 const u8 *seq, int seq_len)
0033 {
0034 kfree_sensitive(priv->keys[index].key);
0035 kfree_sensitive(priv->keys[index].seq);
0036
0037 if (key_len) {
0038 priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC);
0039 if (!priv->keys[index].key)
0040 goto nomem;
0041 } else
0042 priv->keys[index].key = NULL;
0043
0044 if (seq_len) {
0045 priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC);
0046 if (!priv->keys[index].seq)
0047 goto free_key;
0048 } else
0049 priv->keys[index].seq = NULL;
0050
0051 priv->keys[index].key_len = key_len;
0052 priv->keys[index].seq_len = seq_len;
0053
0054 if (key_len)
0055 memcpy((void *)priv->keys[index].key, key, key_len);
0056 if (seq_len)
0057 memcpy((void *)priv->keys[index].seq, seq, seq_len);
0058
0059 switch (alg) {
0060 case ORINOCO_ALG_TKIP:
0061 priv->keys[index].cipher = WLAN_CIPHER_SUITE_TKIP;
0062 break;
0063
0064 case ORINOCO_ALG_WEP:
0065 priv->keys[index].cipher = (key_len > SMALL_KEY_SIZE) ?
0066 WLAN_CIPHER_SUITE_WEP104 : WLAN_CIPHER_SUITE_WEP40;
0067 break;
0068
0069 case ORINOCO_ALG_NONE:
0070 default:
0071 priv->keys[index].cipher = 0;
0072 break;
0073 }
0074
0075 return 0;
0076
0077 free_key:
0078 kfree(priv->keys[index].key);
0079 priv->keys[index].key = NULL;
0080
0081 nomem:
0082 priv->keys[index].key_len = 0;
0083 priv->keys[index].seq_len = 0;
0084 priv->keys[index].cipher = 0;
0085
0086 return -ENOMEM;
0087 }
0088
0089 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
0090 {
0091 struct orinoco_private *priv = ndev_priv(dev);
0092 struct hermes *hw = &priv->hw;
0093 struct iw_statistics *wstats = &priv->wstats;
0094 int err;
0095 unsigned long flags;
0096
0097 if (!netif_device_present(dev)) {
0098 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
0099 dev->name);
0100 return NULL;
0101 }
0102
0103
0104
0105 if (orinoco_lock(priv, &flags) != 0)
0106 return wstats;
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 hermes_inquire(hw, HERMES_INQ_TALLIES);
0118
0119 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
0120 memset(&wstats->qual, 0, sizeof(wstats->qual));
0121
0122
0123 if (SPY_NUMBER(priv)) {
0124 wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
0125 wstats->qual.level = priv->spy_data.spy_stat[0].level;
0126 wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
0127 wstats->qual.updated =
0128 priv->spy_data.spy_stat[0].updated;
0129 }
0130 } else {
0131 struct {
0132 __le16 qual, signal, noise, unused;
0133 } __packed cq;
0134
0135 err = HERMES_READ_RECORD(hw, USER_BAP,
0136 HERMES_RID_COMMSQUALITY, &cq);
0137
0138 if (!err) {
0139 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
0140 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
0141 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
0142 wstats->qual.updated =
0143 IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
0144 }
0145 }
0146
0147 orinoco_unlock(priv, &flags);
0148 return wstats;
0149 }
0150
0151
0152
0153
0154
0155 static int orinoco_ioctl_setwap(struct net_device *dev,
0156 struct iw_request_info *info,
0157 struct sockaddr *ap_addr,
0158 char *extra)
0159 {
0160 struct orinoco_private *priv = ndev_priv(dev);
0161 int err = -EINPROGRESS;
0162 unsigned long flags;
0163
0164 if (orinoco_lock(priv, &flags) != 0)
0165 return -EBUSY;
0166
0167
0168 if (is_zero_ether_addr(ap_addr->sa_data) ||
0169 is_broadcast_ether_addr(ap_addr->sa_data)) {
0170 priv->bssid_fixed = 0;
0171 eth_zero_addr(priv->desired_bssid);
0172
0173
0174 if (ap_addr->sa_data[0] == 0) {
0175 __orinoco_hw_set_wap(priv);
0176 err = 0;
0177 }
0178 goto out;
0179 }
0180
0181 if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
0182 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
0183 "support manual roaming\n",
0184 dev->name);
0185 err = -EOPNOTSUPP;
0186 goto out;
0187 }
0188
0189 if (priv->iw_mode != NL80211_IFTYPE_STATION) {
0190 printk(KERN_WARNING "%s: Manual roaming supported only in "
0191 "managed mode\n", dev->name);
0192 err = -EOPNOTSUPP;
0193 goto out;
0194 }
0195
0196
0197 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
0198 strlen(priv->desired_essid) == 0) {
0199 printk(KERN_WARNING "%s: Desired ESSID must be set for "
0200 "manual roaming\n", dev->name);
0201 err = -EOPNOTSUPP;
0202 goto out;
0203 }
0204
0205
0206 priv->bssid_fixed = 1;
0207 memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
0208
0209 out:
0210 orinoco_unlock(priv, &flags);
0211 return err;
0212 }
0213
0214 static int orinoco_ioctl_getwap(struct net_device *dev,
0215 struct iw_request_info *info,
0216 struct sockaddr *ap_addr,
0217 char *extra)
0218 {
0219 struct orinoco_private *priv = ndev_priv(dev);
0220
0221 int err = 0;
0222 unsigned long flags;
0223
0224 if (orinoco_lock(priv, &flags) != 0)
0225 return -EBUSY;
0226
0227 ap_addr->sa_family = ARPHRD_ETHER;
0228 err = orinoco_hw_get_current_bssid(priv, ap_addr->sa_data);
0229
0230 orinoco_unlock(priv, &flags);
0231
0232 return err;
0233 }
0234
0235 static int orinoco_ioctl_setiwencode(struct net_device *dev,
0236 struct iw_request_info *info,
0237 struct iw_point *erq,
0238 char *keybuf)
0239 {
0240 struct orinoco_private *priv = ndev_priv(dev);
0241 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
0242 int setindex = priv->tx_key;
0243 enum orinoco_alg encode_alg = priv->encode_alg;
0244 int restricted = priv->wep_restrict;
0245 int err = -EINPROGRESS;
0246 unsigned long flags;
0247
0248 if (!priv->has_wep)
0249 return -EOPNOTSUPP;
0250
0251 if (erq->pointer) {
0252
0253 if (erq->length > LARGE_KEY_SIZE)
0254 return -E2BIG;
0255
0256 if ((erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep)
0257 return -E2BIG;
0258 }
0259
0260 if (orinoco_lock(priv, &flags) != 0)
0261 return -EBUSY;
0262
0263
0264 if ((priv->has_wpa) && (priv->encode_alg == ORINOCO_ALG_TKIP))
0265 (void) orinoco_clear_tkip_key(priv, setindex);
0266
0267 if (erq->length > 0) {
0268 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
0269 index = priv->tx_key;
0270
0271
0272 if (encode_alg != ORINOCO_ALG_WEP) {
0273 setindex = index;
0274 encode_alg = ORINOCO_ALG_WEP;
0275 }
0276 } else {
0277
0278
0279
0280 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
0281 if ((index != -1) || (erq->flags == 0)) {
0282 err = -EINVAL;
0283 goto out;
0284 }
0285 } else {
0286
0287 if (priv->keys[index].key_len == 0) {
0288 err = -EINVAL;
0289 goto out;
0290 }
0291 setindex = index;
0292 }
0293 }
0294
0295 if (erq->flags & IW_ENCODE_DISABLED)
0296 encode_alg = ORINOCO_ALG_NONE;
0297 if (erq->flags & IW_ENCODE_OPEN)
0298 restricted = 0;
0299 if (erq->flags & IW_ENCODE_RESTRICTED)
0300 restricted = 1;
0301
0302 if (erq->pointer && erq->length > 0) {
0303 err = orinoco_set_key(priv, index, ORINOCO_ALG_WEP, keybuf,
0304 erq->length, NULL, 0);
0305 }
0306 priv->tx_key = setindex;
0307
0308
0309 if ((priv->encode_alg == encode_alg) &&
0310 (priv->wep_restrict == restricted) &&
0311 netif_carrier_ok(dev)) {
0312 err = __orinoco_hw_setup_wepkeys(priv);
0313
0314 goto out;
0315 }
0316
0317 priv->encode_alg = encode_alg;
0318 priv->wep_restrict = restricted;
0319
0320 out:
0321 orinoco_unlock(priv, &flags);
0322
0323 return err;
0324 }
0325
0326 static int orinoco_ioctl_getiwencode(struct net_device *dev,
0327 struct iw_request_info *info,
0328 struct iw_point *erq,
0329 char *keybuf)
0330 {
0331 struct orinoco_private *priv = ndev_priv(dev);
0332 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
0333 unsigned long flags;
0334
0335 if (!priv->has_wep)
0336 return -EOPNOTSUPP;
0337
0338 if (orinoco_lock(priv, &flags) != 0)
0339 return -EBUSY;
0340
0341 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
0342 index = priv->tx_key;
0343
0344 erq->flags = 0;
0345 if (!priv->encode_alg)
0346 erq->flags |= IW_ENCODE_DISABLED;
0347 erq->flags |= index + 1;
0348
0349 if (priv->wep_restrict)
0350 erq->flags |= IW_ENCODE_RESTRICTED;
0351 else
0352 erq->flags |= IW_ENCODE_OPEN;
0353
0354 erq->length = priv->keys[index].key_len;
0355
0356 memcpy(keybuf, priv->keys[index].key, erq->length);
0357
0358 orinoco_unlock(priv, &flags);
0359 return 0;
0360 }
0361
0362 static int orinoco_ioctl_setessid(struct net_device *dev,
0363 struct iw_request_info *info,
0364 struct iw_point *erq,
0365 char *essidbuf)
0366 {
0367 struct orinoco_private *priv = ndev_priv(dev);
0368 unsigned long flags;
0369
0370
0371
0372
0373
0374
0375 if (erq->length > IW_ESSID_MAX_SIZE)
0376 return -E2BIG;
0377
0378 if (orinoco_lock(priv, &flags) != 0)
0379 return -EBUSY;
0380
0381
0382 memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
0383
0384
0385 if (erq->flags)
0386 memcpy(priv->desired_essid, essidbuf, erq->length);
0387
0388 orinoco_unlock(priv, &flags);
0389
0390 return -EINPROGRESS;
0391 }
0392
0393 static int orinoco_ioctl_getessid(struct net_device *dev,
0394 struct iw_request_info *info,
0395 struct iw_point *erq,
0396 char *essidbuf)
0397 {
0398 struct orinoco_private *priv = ndev_priv(dev);
0399 int active;
0400 int err = 0;
0401 unsigned long flags;
0402
0403 if (netif_running(dev)) {
0404 err = orinoco_hw_get_essid(priv, &active, essidbuf);
0405 if (err < 0)
0406 return err;
0407 erq->length = err;
0408 } else {
0409 if (orinoco_lock(priv, &flags) != 0)
0410 return -EBUSY;
0411 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
0412 erq->length = strlen(priv->desired_essid);
0413 orinoco_unlock(priv, &flags);
0414 }
0415
0416 erq->flags = 1;
0417
0418 return 0;
0419 }
0420
0421 static int orinoco_ioctl_setfreq(struct net_device *dev,
0422 struct iw_request_info *info,
0423 struct iw_freq *frq,
0424 char *extra)
0425 {
0426 struct orinoco_private *priv = ndev_priv(dev);
0427 int chan = -1;
0428 unsigned long flags;
0429 int err = -EINPROGRESS;
0430
0431
0432 if (priv->iw_mode == NL80211_IFTYPE_STATION)
0433 return -EBUSY;
0434
0435 if ((frq->e == 0) && (frq->m <= 1000)) {
0436
0437 chan = frq->m;
0438 } else {
0439
0440 int denom = 1;
0441 int i;
0442
0443
0444 for (i = 0; i < (6 - frq->e); i++)
0445 denom *= 10;
0446
0447 chan = ieee80211_frequency_to_channel(frq->m / denom);
0448 }
0449
0450 if ((chan < 1) || (chan > NUM_CHANNELS) ||
0451 !(priv->channel_mask & (1 << (chan - 1))))
0452 return -EINVAL;
0453
0454 if (orinoco_lock(priv, &flags) != 0)
0455 return -EBUSY;
0456
0457 priv->channel = chan;
0458 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
0459
0460 struct hermes *hw = &priv->hw;
0461 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
0462 HERMES_TEST_SET_CHANNEL,
0463 chan, NULL);
0464 }
0465 orinoco_unlock(priv, &flags);
0466
0467 return err;
0468 }
0469
0470 static int orinoco_ioctl_getfreq(struct net_device *dev,
0471 struct iw_request_info *info,
0472 struct iw_freq *frq,
0473 char *extra)
0474 {
0475 struct orinoco_private *priv = ndev_priv(dev);
0476 int tmp;
0477
0478
0479 tmp = orinoco_hw_get_freq(priv);
0480 if (tmp < 0)
0481 return tmp;
0482
0483 frq->m = tmp * 100000;
0484 frq->e = 1;
0485
0486 return 0;
0487 }
0488
0489 static int orinoco_ioctl_getsens(struct net_device *dev,
0490 struct iw_request_info *info,
0491 struct iw_param *srq,
0492 char *extra)
0493 {
0494 struct orinoco_private *priv = ndev_priv(dev);
0495 struct hermes *hw = &priv->hw;
0496 u16 val;
0497 int err;
0498 unsigned long flags;
0499
0500 if (!priv->has_sensitivity)
0501 return -EOPNOTSUPP;
0502
0503 if (orinoco_lock(priv, &flags) != 0)
0504 return -EBUSY;
0505 err = hermes_read_wordrec(hw, USER_BAP,
0506 HERMES_RID_CNFSYSTEMSCALE, &val);
0507 orinoco_unlock(priv, &flags);
0508
0509 if (err)
0510 return err;
0511
0512 srq->value = val;
0513 srq->fixed = 0;
0514
0515 return 0;
0516 }
0517
0518 static int orinoco_ioctl_setsens(struct net_device *dev,
0519 struct iw_request_info *info,
0520 struct iw_param *srq,
0521 char *extra)
0522 {
0523 struct orinoco_private *priv = ndev_priv(dev);
0524 int val = srq->value;
0525 unsigned long flags;
0526
0527 if (!priv->has_sensitivity)
0528 return -EOPNOTSUPP;
0529
0530 if ((val < 1) || (val > 3))
0531 return -EINVAL;
0532
0533 if (orinoco_lock(priv, &flags) != 0)
0534 return -EBUSY;
0535 priv->ap_density = val;
0536 orinoco_unlock(priv, &flags);
0537
0538 return -EINPROGRESS;
0539 }
0540
0541 static int orinoco_ioctl_setrate(struct net_device *dev,
0542 struct iw_request_info *info,
0543 struct iw_param *rrq,
0544 char *extra)
0545 {
0546 struct orinoco_private *priv = ndev_priv(dev);
0547 int ratemode;
0548 int bitrate;
0549 unsigned long flags;
0550
0551
0552
0553
0554 if (rrq->value == -1)
0555 bitrate = 110;
0556 else {
0557 if (rrq->value % 100000)
0558 return -EINVAL;
0559 bitrate = rrq->value / 100000;
0560 }
0561
0562 ratemode = orinoco_get_bitratemode(bitrate, !rrq->fixed);
0563
0564 if (ratemode == -1)
0565 return -EINVAL;
0566
0567 if (orinoco_lock(priv, &flags) != 0)
0568 return -EBUSY;
0569 priv->bitratemode = ratemode;
0570 orinoco_unlock(priv, &flags);
0571
0572 return -EINPROGRESS;
0573 }
0574
0575 static int orinoco_ioctl_getrate(struct net_device *dev,
0576 struct iw_request_info *info,
0577 struct iw_param *rrq,
0578 char *extra)
0579 {
0580 struct orinoco_private *priv = ndev_priv(dev);
0581 int err = 0;
0582 int bitrate, automatic;
0583 unsigned long flags;
0584
0585 if (orinoco_lock(priv, &flags) != 0)
0586 return -EBUSY;
0587
0588 orinoco_get_ratemode_cfg(priv->bitratemode, &bitrate, &automatic);
0589
0590
0591
0592 if (netif_running(dev)) {
0593 int act_bitrate;
0594 int lerr;
0595
0596
0597 lerr = orinoco_hw_get_act_bitrate(priv, &act_bitrate);
0598 if (!lerr)
0599 bitrate = act_bitrate;
0600 }
0601
0602 orinoco_unlock(priv, &flags);
0603
0604 rrq->value = bitrate;
0605 rrq->fixed = !automatic;
0606 rrq->disabled = 0;
0607
0608 return err;
0609 }
0610
0611 static int orinoco_ioctl_setpower(struct net_device *dev,
0612 struct iw_request_info *info,
0613 struct iw_param *prq,
0614 char *extra)
0615 {
0616 struct orinoco_private *priv = ndev_priv(dev);
0617 int err = -EINPROGRESS;
0618 unsigned long flags;
0619
0620 if (orinoco_lock(priv, &flags) != 0)
0621 return -EBUSY;
0622
0623 if (prq->disabled) {
0624 priv->pm_on = 0;
0625 } else {
0626 switch (prq->flags & IW_POWER_MODE) {
0627 case IW_POWER_UNICAST_R:
0628 priv->pm_mcast = 0;
0629 priv->pm_on = 1;
0630 break;
0631 case IW_POWER_ALL_R:
0632 priv->pm_mcast = 1;
0633 priv->pm_on = 1;
0634 break;
0635 case IW_POWER_ON:
0636
0637 break;
0638 default:
0639 err = -EINVAL;
0640 goto out;
0641 }
0642
0643 if (prq->flags & IW_POWER_TIMEOUT) {
0644 priv->pm_on = 1;
0645 priv->pm_timeout = prq->value / 1000;
0646 }
0647 if (prq->flags & IW_POWER_PERIOD) {
0648 priv->pm_on = 1;
0649 priv->pm_period = prq->value / 1000;
0650 }
0651
0652
0653 if (!priv->pm_on) {
0654 err = -EINVAL;
0655 goto out;
0656 }
0657 }
0658
0659 out:
0660 orinoco_unlock(priv, &flags);
0661
0662 return err;
0663 }
0664
0665 static int orinoco_ioctl_getpower(struct net_device *dev,
0666 struct iw_request_info *info,
0667 struct iw_param *prq,
0668 char *extra)
0669 {
0670 struct orinoco_private *priv = ndev_priv(dev);
0671 struct hermes *hw = &priv->hw;
0672 int err = 0;
0673 u16 enable, period, timeout, mcast;
0674 unsigned long flags;
0675
0676 if (orinoco_lock(priv, &flags) != 0)
0677 return -EBUSY;
0678
0679 err = hermes_read_wordrec(hw, USER_BAP,
0680 HERMES_RID_CNFPMENABLED, &enable);
0681 if (err)
0682 goto out;
0683
0684 err = hermes_read_wordrec(hw, USER_BAP,
0685 HERMES_RID_CNFMAXSLEEPDURATION, &period);
0686 if (err)
0687 goto out;
0688
0689 err = hermes_read_wordrec(hw, USER_BAP,
0690 HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
0691 if (err)
0692 goto out;
0693
0694 err = hermes_read_wordrec(hw, USER_BAP,
0695 HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
0696 if (err)
0697 goto out;
0698
0699 prq->disabled = !enable;
0700
0701 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
0702 prq->flags = IW_POWER_TIMEOUT;
0703 prq->value = timeout * 1000;
0704 } else {
0705 prq->flags = IW_POWER_PERIOD;
0706 prq->value = period * 1000;
0707 }
0708 if (mcast)
0709 prq->flags |= IW_POWER_ALL_R;
0710 else
0711 prq->flags |= IW_POWER_UNICAST_R;
0712
0713 out:
0714 orinoco_unlock(priv, &flags);
0715
0716 return err;
0717 }
0718
0719 static int orinoco_ioctl_set_encodeext(struct net_device *dev,
0720 struct iw_request_info *info,
0721 union iwreq_data *wrqu,
0722 char *extra)
0723 {
0724 struct orinoco_private *priv = ndev_priv(dev);
0725 struct iw_point *encoding = &wrqu->encoding;
0726 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
0727 int idx, alg = ext->alg, set_key = 1;
0728 unsigned long flags;
0729 int err = -EINVAL;
0730
0731 if (orinoco_lock(priv, &flags) != 0)
0732 return -EBUSY;
0733
0734
0735 idx = encoding->flags & IW_ENCODE_INDEX;
0736 if (idx) {
0737 if ((idx < 1) || (idx > 4))
0738 goto out;
0739 idx--;
0740 } else
0741 idx = priv->tx_key;
0742
0743 if (encoding->flags & IW_ENCODE_DISABLED)
0744 alg = IW_ENCODE_ALG_NONE;
0745
0746 if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
0747
0748 (void) orinoco_clear_tkip_key(priv, priv->tx_key);
0749 }
0750
0751 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
0752 priv->tx_key = idx;
0753 set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
0754 (ext->key_len > 0)) ? 1 : 0;
0755 }
0756
0757 if (set_key) {
0758
0759 switch (alg) {
0760 case IW_ENCODE_ALG_NONE:
0761 priv->encode_alg = ORINOCO_ALG_NONE;
0762 err = orinoco_set_key(priv, idx, ORINOCO_ALG_NONE,
0763 NULL, 0, NULL, 0);
0764 break;
0765
0766 case IW_ENCODE_ALG_WEP:
0767 if (ext->key_len <= 0)
0768 goto out;
0769
0770 priv->encode_alg = ORINOCO_ALG_WEP;
0771 err = orinoco_set_key(priv, idx, ORINOCO_ALG_WEP,
0772 ext->key, ext->key_len, NULL, 0);
0773 break;
0774
0775 case IW_ENCODE_ALG_TKIP:
0776 {
0777 u8 *tkip_iv = NULL;
0778
0779 if (!priv->has_wpa ||
0780 (ext->key_len > sizeof(struct orinoco_tkip_key)))
0781 goto out;
0782
0783 priv->encode_alg = ORINOCO_ALG_TKIP;
0784
0785 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
0786 tkip_iv = &ext->rx_seq[0];
0787
0788 err = orinoco_set_key(priv, idx, ORINOCO_ALG_TKIP,
0789 ext->key, ext->key_len, tkip_iv,
0790 ORINOCO_SEQ_LEN);
0791
0792 err = __orinoco_hw_set_tkip_key(priv, idx,
0793 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
0794 priv->keys[idx].key, priv->keys[idx].key_len,
0795 tkip_iv, ORINOCO_SEQ_LEN, NULL, 0);
0796 if (err)
0797 printk(KERN_ERR "%s: Error %d setting TKIP key"
0798 "\n", dev->name, err);
0799
0800 goto out;
0801 }
0802 default:
0803 goto out;
0804 }
0805 }
0806 err = -EINPROGRESS;
0807 out:
0808 orinoco_unlock(priv, &flags);
0809
0810 return err;
0811 }
0812
0813 static int orinoco_ioctl_get_encodeext(struct net_device *dev,
0814 struct iw_request_info *info,
0815 union iwreq_data *wrqu,
0816 char *extra)
0817 {
0818 struct orinoco_private *priv = ndev_priv(dev);
0819 struct iw_point *encoding = &wrqu->encoding;
0820 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
0821 int idx, max_key_len;
0822 unsigned long flags;
0823 int err;
0824
0825 if (orinoco_lock(priv, &flags) != 0)
0826 return -EBUSY;
0827
0828 err = -EINVAL;
0829 max_key_len = encoding->length - sizeof(*ext);
0830 if (max_key_len < 0)
0831 goto out;
0832
0833 idx = encoding->flags & IW_ENCODE_INDEX;
0834 if (idx) {
0835 if ((idx < 1) || (idx > 4))
0836 goto out;
0837 idx--;
0838 } else
0839 idx = priv->tx_key;
0840
0841 encoding->flags = idx + 1;
0842 memset(ext, 0, sizeof(*ext));
0843
0844 switch (priv->encode_alg) {
0845 case ORINOCO_ALG_NONE:
0846 ext->alg = IW_ENCODE_ALG_NONE;
0847 ext->key_len = 0;
0848 encoding->flags |= IW_ENCODE_DISABLED;
0849 break;
0850 case ORINOCO_ALG_WEP:
0851 ext->alg = IW_ENCODE_ALG_WEP;
0852 ext->key_len = min(priv->keys[idx].key_len, max_key_len);
0853 memcpy(ext->key, priv->keys[idx].key, ext->key_len);
0854 encoding->flags |= IW_ENCODE_ENABLED;
0855 break;
0856 case ORINOCO_ALG_TKIP:
0857 ext->alg = IW_ENCODE_ALG_TKIP;
0858 ext->key_len = min(priv->keys[idx].key_len, max_key_len);
0859 memcpy(ext->key, priv->keys[idx].key, ext->key_len);
0860 encoding->flags |= IW_ENCODE_ENABLED;
0861 break;
0862 }
0863
0864 err = 0;
0865 out:
0866 orinoco_unlock(priv, &flags);
0867
0868 return err;
0869 }
0870
0871 static int orinoco_ioctl_set_auth(struct net_device *dev,
0872 struct iw_request_info *info,
0873 union iwreq_data *wrqu, char *extra)
0874 {
0875 struct orinoco_private *priv = ndev_priv(dev);
0876 struct hermes *hw = &priv->hw;
0877 struct iw_param *param = &wrqu->param;
0878 unsigned long flags;
0879 int ret = -EINPROGRESS;
0880
0881 if (orinoco_lock(priv, &flags) != 0)
0882 return -EBUSY;
0883
0884 switch (param->flags & IW_AUTH_INDEX) {
0885 case IW_AUTH_WPA_VERSION:
0886 case IW_AUTH_CIPHER_PAIRWISE:
0887 case IW_AUTH_CIPHER_GROUP:
0888 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
0889 case IW_AUTH_PRIVACY_INVOKED:
0890 case IW_AUTH_DROP_UNENCRYPTED:
0891
0892
0893
0894 break;
0895
0896 case IW_AUTH_MFP:
0897
0898
0899
0900 if (param->value == IW_AUTH_MFP_REQUIRED)
0901 ret = -EINVAL;
0902 break;
0903
0904 case IW_AUTH_KEY_MGMT:
0905
0906
0907
0908
0909 priv->key_mgmt = param->value;
0910 break;
0911
0912 case IW_AUTH_TKIP_COUNTERMEASURES:
0913
0914
0915
0916
0917
0918
0919
0920 if (param->value) {
0921 priv->tkip_cm_active = 1;
0922 ret = hermes_disable_port(hw, 0);
0923 } else {
0924 priv->tkip_cm_active = 0;
0925 ret = hermes_enable_port(hw, 0);
0926 }
0927 break;
0928
0929 case IW_AUTH_80211_AUTH_ALG:
0930 if (param->value & IW_AUTH_ALG_SHARED_KEY)
0931 priv->wep_restrict = 1;
0932 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
0933 priv->wep_restrict = 0;
0934 else
0935 ret = -EINVAL;
0936 break;
0937
0938 case IW_AUTH_WPA_ENABLED:
0939 if (priv->has_wpa) {
0940 priv->wpa_enabled = param->value ? 1 : 0;
0941 } else {
0942 if (param->value)
0943 ret = -EOPNOTSUPP;
0944
0945 priv->wpa_enabled = 0;
0946 }
0947 break;
0948
0949 default:
0950 ret = -EOPNOTSUPP;
0951 }
0952
0953 orinoco_unlock(priv, &flags);
0954 return ret;
0955 }
0956
0957 static int orinoco_ioctl_get_auth(struct net_device *dev,
0958 struct iw_request_info *info,
0959 union iwreq_data *wrqu, char *extra)
0960 {
0961 struct orinoco_private *priv = ndev_priv(dev);
0962 struct iw_param *param = &wrqu->param;
0963 unsigned long flags;
0964 int ret = 0;
0965
0966 if (orinoco_lock(priv, &flags) != 0)
0967 return -EBUSY;
0968
0969 switch (param->flags & IW_AUTH_INDEX) {
0970 case IW_AUTH_KEY_MGMT:
0971 param->value = priv->key_mgmt;
0972 break;
0973
0974 case IW_AUTH_TKIP_COUNTERMEASURES:
0975 param->value = priv->tkip_cm_active;
0976 break;
0977
0978 case IW_AUTH_80211_AUTH_ALG:
0979 if (priv->wep_restrict)
0980 param->value = IW_AUTH_ALG_SHARED_KEY;
0981 else
0982 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
0983 break;
0984
0985 case IW_AUTH_WPA_ENABLED:
0986 param->value = priv->wpa_enabled;
0987 break;
0988
0989 default:
0990 ret = -EOPNOTSUPP;
0991 }
0992
0993 orinoco_unlock(priv, &flags);
0994 return ret;
0995 }
0996
0997 static int orinoco_ioctl_set_genie(struct net_device *dev,
0998 struct iw_request_info *info,
0999 union iwreq_data *wrqu, char *extra)
1000 {
1001 struct orinoco_private *priv = ndev_priv(dev);
1002 u8 *buf;
1003 unsigned long flags;
1004
1005
1006 if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
1007 (wrqu->data.length && (extra == NULL)))
1008 return -EINVAL;
1009
1010 if (wrqu->data.length) {
1011 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
1012 if (buf == NULL)
1013 return -ENOMEM;
1014 } else
1015 buf = NULL;
1016
1017 if (orinoco_lock(priv, &flags) != 0) {
1018 kfree(buf);
1019 return -EBUSY;
1020 }
1021
1022 kfree(priv->wpa_ie);
1023 priv->wpa_ie = buf;
1024 priv->wpa_ie_len = wrqu->data.length;
1025
1026 if (priv->wpa_ie) {
1027
1028
1029
1030
1031
1032 }
1033
1034 orinoco_unlock(priv, &flags);
1035 return 0;
1036 }
1037
1038 static int orinoco_ioctl_get_genie(struct net_device *dev,
1039 struct iw_request_info *info,
1040 union iwreq_data *wrqu, char *extra)
1041 {
1042 struct orinoco_private *priv = ndev_priv(dev);
1043 unsigned long flags;
1044 int err = 0;
1045
1046 if (orinoco_lock(priv, &flags) != 0)
1047 return -EBUSY;
1048
1049 if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
1050 wrqu->data.length = 0;
1051 goto out;
1052 }
1053
1054 if (wrqu->data.length < priv->wpa_ie_len) {
1055 err = -E2BIG;
1056 goto out;
1057 }
1058
1059 wrqu->data.length = priv->wpa_ie_len;
1060 memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
1061
1062 out:
1063 orinoco_unlock(priv, &flags);
1064 return err;
1065 }
1066
1067 static int orinoco_ioctl_set_mlme(struct net_device *dev,
1068 struct iw_request_info *info,
1069 union iwreq_data *wrqu, char *extra)
1070 {
1071 struct orinoco_private *priv = ndev_priv(dev);
1072 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1073 unsigned long flags;
1074 int ret = 0;
1075
1076 if (orinoco_lock(priv, &flags) != 0)
1077 return -EBUSY;
1078
1079 switch (mlme->cmd) {
1080 case IW_MLME_DEAUTH:
1081
1082 break;
1083
1084 case IW_MLME_DISASSOC:
1085
1086 ret = orinoco_hw_disassociate(priv, mlme->addr.sa_data,
1087 mlme->reason_code);
1088 break;
1089
1090 default:
1091 ret = -EOPNOTSUPP;
1092 }
1093
1094 orinoco_unlock(priv, &flags);
1095 return ret;
1096 }
1097
1098 static int orinoco_ioctl_reset(struct net_device *dev,
1099 struct iw_request_info *info,
1100 void *wrqu,
1101 char *extra)
1102 {
1103 struct orinoco_private *priv = ndev_priv(dev);
1104
1105 if (!capable(CAP_NET_ADMIN))
1106 return -EPERM;
1107
1108 if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
1109 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
1110
1111
1112 orinoco_reset(&priv->reset_work);
1113 } else {
1114 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
1115
1116 schedule_work(&priv->reset_work);
1117 }
1118
1119 return 0;
1120 }
1121
1122 static int orinoco_ioctl_setibssport(struct net_device *dev,
1123 struct iw_request_info *info,
1124 void *wrqu,
1125 char *extra)
1126
1127 {
1128 struct orinoco_private *priv = ndev_priv(dev);
1129 int val = *((int *) extra);
1130 unsigned long flags;
1131
1132 if (orinoco_lock(priv, &flags) != 0)
1133 return -EBUSY;
1134
1135 priv->ibss_port = val;
1136
1137
1138 set_port_type(priv);
1139
1140 orinoco_unlock(priv, &flags);
1141 return -EINPROGRESS;
1142 }
1143
1144 static int orinoco_ioctl_getibssport(struct net_device *dev,
1145 struct iw_request_info *info,
1146 void *wrqu,
1147 char *extra)
1148 {
1149 struct orinoco_private *priv = ndev_priv(dev);
1150 int *val = (int *) extra;
1151
1152 *val = priv->ibss_port;
1153 return 0;
1154 }
1155
1156 static int orinoco_ioctl_setport3(struct net_device *dev,
1157 struct iw_request_info *info,
1158 void *wrqu,
1159 char *extra)
1160 {
1161 struct orinoco_private *priv = ndev_priv(dev);
1162 int val = *((int *) extra);
1163 int err = 0;
1164 unsigned long flags;
1165
1166 if (orinoco_lock(priv, &flags) != 0)
1167 return -EBUSY;
1168
1169 switch (val) {
1170 case 0:
1171 if (!priv->has_ibss) {
1172 err = -EINVAL;
1173 break;
1174 }
1175 priv->prefer_port3 = 0;
1176
1177 break;
1178
1179 case 1:
1180 if (!priv->has_port3) {
1181 err = -EINVAL;
1182 break;
1183 }
1184 priv->prefer_port3 = 1;
1185 break;
1186
1187 default:
1188 err = -EINVAL;
1189 }
1190
1191 if (!err) {
1192
1193 set_port_type(priv);
1194 err = -EINPROGRESS;
1195 }
1196
1197 orinoco_unlock(priv, &flags);
1198
1199 return err;
1200 }
1201
1202 static int orinoco_ioctl_getport3(struct net_device *dev,
1203 struct iw_request_info *info,
1204 void *wrqu,
1205 char *extra)
1206 {
1207 struct orinoco_private *priv = ndev_priv(dev);
1208 int *val = (int *) extra;
1209
1210 *val = priv->prefer_port3;
1211 return 0;
1212 }
1213
1214 static int orinoco_ioctl_setpreamble(struct net_device *dev,
1215 struct iw_request_info *info,
1216 void *wrqu,
1217 char *extra)
1218 {
1219 struct orinoco_private *priv = ndev_priv(dev);
1220 unsigned long flags;
1221 int val;
1222
1223 if (!priv->has_preamble)
1224 return -EOPNOTSUPP;
1225
1226
1227
1228
1229
1230
1231 val = *((int *) extra);
1232
1233 if (orinoco_lock(priv, &flags) != 0)
1234 return -EBUSY;
1235
1236 if (val)
1237 priv->preamble = 1;
1238 else
1239 priv->preamble = 0;
1240
1241 orinoco_unlock(priv, &flags);
1242
1243 return -EINPROGRESS;
1244 }
1245
1246 static int orinoco_ioctl_getpreamble(struct net_device *dev,
1247 struct iw_request_info *info,
1248 void *wrqu,
1249 char *extra)
1250 {
1251 struct orinoco_private *priv = ndev_priv(dev);
1252 int *val = (int *) extra;
1253
1254 if (!priv->has_preamble)
1255 return -EOPNOTSUPP;
1256
1257 *val = priv->preamble;
1258 return 0;
1259 }
1260
1261
1262
1263
1264
1265
1266 static int orinoco_ioctl_getrid(struct net_device *dev,
1267 struct iw_request_info *info,
1268 struct iw_point *data,
1269 char *extra)
1270 {
1271 struct orinoco_private *priv = ndev_priv(dev);
1272 struct hermes *hw = &priv->hw;
1273 int rid = data->flags;
1274 u16 length;
1275 int err;
1276 unsigned long flags;
1277
1278
1279
1280 if (!capable(CAP_NET_ADMIN))
1281 return -EPERM;
1282
1283 if (rid < 0xfc00 || rid > 0xffff)
1284 return -EINVAL;
1285
1286 if (orinoco_lock(priv, &flags) != 0)
1287 return -EBUSY;
1288
1289 err = hw->ops->read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
1290 extra);
1291 if (err)
1292 goto out;
1293
1294 data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
1295 MAX_RID_LEN);
1296
1297 out:
1298 orinoco_unlock(priv, &flags);
1299 return err;
1300 }
1301
1302
1303
1304 static int orinoco_ioctl_commit(struct net_device *dev,
1305 struct iw_request_info *info,
1306 void *wrqu,
1307 char *extra)
1308 {
1309 struct orinoco_private *priv = ndev_priv(dev);
1310 unsigned long flags;
1311 int err = 0;
1312
1313 if (!priv->open)
1314 return 0;
1315
1316 if (orinoco_lock(priv, &flags) != 0)
1317 return err;
1318
1319 err = orinoco_commit(priv);
1320
1321 orinoco_unlock(priv, &flags);
1322 return err;
1323 }
1324
1325 static const struct iw_priv_args orinoco_privtab[] = {
1326 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
1327 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
1328 { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1329 0, "set_port3" },
1330 { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1331 "get_port3" },
1332 { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1333 0, "set_preamble" },
1334 { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1335 "get_preamble" },
1336 { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1337 0, "set_ibssport" },
1338 { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1339 "get_ibssport" },
1340 { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
1341 "get_rid" },
1342 };
1343
1344
1345
1346
1347
1348
1349 static const iw_handler orinoco_handler[] = {
1350 IW_HANDLER(SIOCSIWCOMMIT, (iw_handler)orinoco_ioctl_commit),
1351 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
1352 IW_HANDLER(SIOCSIWFREQ, (iw_handler)orinoco_ioctl_setfreq),
1353 IW_HANDLER(SIOCGIWFREQ, (iw_handler)orinoco_ioctl_getfreq),
1354 IW_HANDLER(SIOCSIWMODE, (iw_handler)cfg80211_wext_siwmode),
1355 IW_HANDLER(SIOCGIWMODE, (iw_handler)cfg80211_wext_giwmode),
1356 IW_HANDLER(SIOCSIWSENS, (iw_handler)orinoco_ioctl_setsens),
1357 IW_HANDLER(SIOCGIWSENS, (iw_handler)orinoco_ioctl_getsens),
1358 IW_HANDLER(SIOCGIWRANGE, (iw_handler)cfg80211_wext_giwrange),
1359 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1360 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1361 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1362 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1363 IW_HANDLER(SIOCSIWAP, (iw_handler)orinoco_ioctl_setwap),
1364 IW_HANDLER(SIOCGIWAP, (iw_handler)orinoco_ioctl_getwap),
1365 IW_HANDLER(SIOCSIWSCAN, (iw_handler)cfg80211_wext_siwscan),
1366 IW_HANDLER(SIOCGIWSCAN, (iw_handler)cfg80211_wext_giwscan),
1367 IW_HANDLER(SIOCSIWESSID, (iw_handler)orinoco_ioctl_setessid),
1368 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid),
1369 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate),
1370 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate),
1371 IW_HANDLER(SIOCSIWRTS, (iw_handler)cfg80211_wext_siwrts),
1372 IW_HANDLER(SIOCGIWRTS, (iw_handler)cfg80211_wext_giwrts),
1373 IW_HANDLER(SIOCSIWFRAG, (iw_handler)cfg80211_wext_siwfrag),
1374 IW_HANDLER(SIOCGIWFRAG, (iw_handler)cfg80211_wext_giwfrag),
1375 IW_HANDLER(SIOCGIWRETRY, (iw_handler)cfg80211_wext_giwretry),
1376 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode),
1377 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode),
1378 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower),
1379 IW_HANDLER(SIOCGIWPOWER, (iw_handler)orinoco_ioctl_getpower),
1380 IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
1381 IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
1382 IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
1383 IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
1384 IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
1385 IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
1386 IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
1387 };
1388
1389
1390
1391
1392
1393 static const iw_handler orinoco_private_handler[] = {
1394 [0] = (iw_handler)orinoco_ioctl_reset,
1395 [1] = (iw_handler)orinoco_ioctl_reset,
1396 [2] = (iw_handler)orinoco_ioctl_setport3,
1397 [3] = (iw_handler)orinoco_ioctl_getport3,
1398 [4] = (iw_handler)orinoco_ioctl_setpreamble,
1399 [5] = (iw_handler)orinoco_ioctl_getpreamble,
1400 [6] = (iw_handler)orinoco_ioctl_setibssport,
1401 [7] = (iw_handler)orinoco_ioctl_getibssport,
1402 [9] = (iw_handler)orinoco_ioctl_getrid,
1403 };
1404
1405 const struct iw_handler_def orinoco_handler_def = {
1406 .num_standard = ARRAY_SIZE(orinoco_handler),
1407 .num_private = ARRAY_SIZE(orinoco_private_handler),
1408 .num_private_args = ARRAY_SIZE(orinoco_privtab),
1409 .standard = orinoco_handler,
1410 .private = orinoco_private_handler,
1411 .private_args = orinoco_privtab,
1412 .get_wireless_stats = orinoco_get_wireless_stats,
1413 };