diff options
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r-- | drivers/net/wireless/orinoco.c | 182 |
1 files changed, 102 insertions, 80 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index aabcdc2be05..8de49fe5723 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -94,6 +94,8 @@ #include <net/iw_handler.h> #include <net/ieee80211.h> +#include <net/ieee80211.h> + #include <asm/uaccess.h> #include <asm/io.h> #include <asm/system.h> @@ -101,7 +103,6 @@ #include "hermes.h" #include "hermes_rid.h" #include "orinoco.h" -#include "ieee802_11.h" /********************************************************************/ /* Module information */ @@ -150,7 +151,7 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; #define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2) #define ORINOCO_MIN_MTU 256 -#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD) +#define ORINOCO_MAX_MTU (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD) #define SYMBOL_MAX_VER_LEN (14) #define USER_BAP 0 @@ -442,7 +443,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu) if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) return -EINVAL; - if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) > + if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) > (priv->nicbuf_size - ETH_HLEN) ) return -EINVAL; @@ -918,7 +919,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) data. */ return; } - if (length > IEEE802_11_DATA_LEN) { + if (length > IEEE80211_DATA_LEN) { printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", dev->name, length); stats->rx_length_errors++; @@ -1052,8 +1053,9 @@ static void orinoco_join_ap(struct net_device *dev) u16 channel; } __attribute__ ((packed)) req; const int atom_len = offsetof(struct prism2_scan_apinfo, atim); - struct prism2_scan_apinfo *atom; + struct prism2_scan_apinfo *atom = NULL; int offset = 4; + int found = 0; u8 *buf; u16 len; @@ -1088,15 +1090,18 @@ static void orinoco_join_ap(struct net_device *dev) * we were requested to join */ for (; offset + atom_len <= len; offset += atom_len) { atom = (struct prism2_scan_apinfo *) (buf + offset); - if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) - goto found; + if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) { + found = 1; + break; + } } - DEBUG(1, "%s: Requested AP not found in scan results\n", - dev->name); - goto out; + if (! found) { + DEBUG(1, "%s: Requested AP not found in scan results\n", + dev->name); + goto out; + } - found: memcpy(req.bssid, priv->desired_bssid, ETH_ALEN); req.channel = atom->channel; /* both are little-endian */ err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST, @@ -1283,8 +1288,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) /* Read scan data */ err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, infofid, sizeof(info)); - if (err) + if (err) { + kfree(buf); break; + } #ifdef ORINOCO_DEBUG { @@ -2272,7 +2279,7 @@ static int orinoco_init(struct net_device *dev) /* No need to lock, the hw_unavailable flag is already set in * alloc_orinocodev() */ - priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; + priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN; /* Initialize the firmware */ err = orinoco_reinit_firmware(dev); @@ -4020,7 +4027,8 @@ static int orinoco_ioctl_setscan(struct net_device *dev, } /* Translate scan data returned from the card to a card independant - * format that the Wireless Tools will understand - Jean II */ + * format that the Wireless Tools will understand - Jean II + * Return message length or -errno for fatal errors */ static inline int orinoco_translate_scan(struct net_device *dev, char *buffer, char *scan, @@ -4060,13 +4068,19 @@ static inline int orinoco_translate_scan(struct net_device *dev, break; case FIRMWARE_TYPE_INTERSIL: offset = 4; - if (priv->has_hostscan) - atom_len = scan[0] + (scan[1] << 8); - else + if (priv->has_hostscan) { + atom_len = le16_to_cpup((u16 *)scan); + /* Sanity check for atom_len */ + if (atom_len < sizeof(struct prism2_scan_apinfo)) { + printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n", + dev->name, atom_len); + return -EIO; + } + } else atom_len = offsetof(struct prism2_scan_apinfo, atim); break; default: - return 0; + return -EOPNOTSUPP; } /* Check that we got an whole number of atoms */ @@ -4074,7 +4088,7 @@ static inline int orinoco_translate_scan(struct net_device *dev, printk(KERN_ERR "%s: Unexpected scan data length %d, " "atom_len %d, offset %d\n", dev->name, scan_len, atom_len, offset); - return 0; + return -EIO; } /* Read the entries one by one */ @@ -4209,33 +4223,41 @@ static int orinoco_ioctl_getscan(struct net_device *dev, /* We have some results to push back to user space */ /* Translate to WE format */ - srq->length = orinoco_translate_scan(dev, extra, - priv->scan_result, - priv->scan_len); - - /* Return flags */ - srq->flags = (__u16) priv->scan_mode; + int ret = orinoco_translate_scan(dev, extra, + priv->scan_result, + priv->scan_len); + + if (ret < 0) { + err = ret; + kfree(priv->scan_result); + priv->scan_result = NULL; + } else { + srq->length = ret; - /* Results are here, so scan no longer in progress */ - priv->scan_inprogress = 0; + /* Return flags */ + srq->flags = (__u16) priv->scan_mode; - /* In any case, Scan results will be cleaned up in the - * reset function and when exiting the driver. - * The person triggering the scanning may never come to - * pick the results, so we need to do it in those places. - * Jean II */ + /* In any case, Scan results will be cleaned up in the + * reset function and when exiting the driver. + * The person triggering the scanning may never come to + * pick the results, so we need to do it in those places. + * Jean II */ #ifdef SCAN_SINGLE_READ - /* If you enable this option, only one client (the first - * one) will be able to read the result (and only one - * time). If there is multiple concurent clients that - * want to read scan results, this behavior is not - * advisable - Jean II */ - kfree(priv->scan_result); - priv->scan_result = NULL; + /* If you enable this option, only one client (the first + * one) will be able to read the result (and only one + * time). If there is multiple concurent clients that + * want to read scan results, this behavior is not + * advisable - Jean II */ + kfree(priv->scan_result); + priv->scan_result = NULL; #endif /* SCAN_SINGLE_READ */ - /* Here, if too much time has elapsed since last scan, - * we may want to clean up scan results... - Jean II */ + /* Here, if too much time has elapsed since last scan, + * we may want to clean up scan results... - Jean II */ + } + + /* Scan is no longer in progress */ + priv->scan_inprogress = 0; } orinoco_unlock(priv, &flags); @@ -4322,36 +4344,36 @@ static const struct iw_priv_args orinoco_privtab[] = { */ static const iw_handler orinoco_handler[] = { - [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit, - [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname, - [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq, - [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq, - [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode, - [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode, - [SIOCSIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens, - [SIOCGIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens, - [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange, - [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy, - [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getspy, - [SIOCSIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setwap, - [SIOCGIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getwap, - [SIOCSIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setscan, - [SIOCGIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getscan, - [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setessid, - [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getessid, - [SIOCSIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setnick, - [SIOCGIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getnick, - [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrate, - [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrate, - [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrts, - [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrts, - [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfrag, - [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfrag, - [SIOCGIWRETRY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getretry, - [SIOCSIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_setiwencode, - [SIOCGIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwencode, - [SIOCSIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setpower, - [SIOCGIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getpower, + [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit, + [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname, + [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq, + [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq, + [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode, + [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode, + [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, + [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, + [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, + [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, + [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy, + [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, + [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, + [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, + [SIOCGIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan, + [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid, + [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid, + [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick, + [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick, + [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate, + [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate, + [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts, + [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts, + [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag, + [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag, + [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry, + [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode, + [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode, + [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower, + [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower, }; @@ -4359,15 +4381,15 @@ static const iw_handler orinoco_handler[] = { Added typecasting since we no longer use iwreq_data -- Moustafa */ static const iw_handler orinoco_private_handler[] = { - [0] (iw_handler) orinoco_ioctl_reset, - [1] (iw_handler) orinoco_ioctl_reset, - [2] (iw_handler) orinoco_ioctl_setport3, - [3] (iw_handler) orinoco_ioctl_getport3, - [4] (iw_handler) orinoco_ioctl_setpreamble, - [5] (iw_handler) orinoco_ioctl_getpreamble, - [6] (iw_handler) orinoco_ioctl_setibssport, - [7] (iw_handler) orinoco_ioctl_getibssport, - [9] (iw_handler) orinoco_ioctl_getrid, + [0] = (iw_handler) orinoco_ioctl_reset, + [1] = (iw_handler) orinoco_ioctl_reset, + [2] = (iw_handler) orinoco_ioctl_setport3, + [3] = (iw_handler) orinoco_ioctl_getport3, + [4] = (iw_handler) orinoco_ioctl_setpreamble, + [5] = (iw_handler) orinoco_ioctl_getpreamble, + [6] = (iw_handler) orinoco_ioctl_setibssport, + [7] = (iw_handler) orinoco_ioctl_getibssport, + [9] = (iw_handler) orinoco_ioctl_getrid, }; static const struct iw_handler_def orinoco_handler_def = { |