diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2007-12-19 18:56:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:09:00 -0500 |
commit | 17e70491404c73012a7991a068ba62ec59bebdb2 (patch) | |
tree | fbc490bfee01cc7cb0f3bde3b510fabfdf16c704 /drivers/net/wireless/airo.c | |
parent | b8c06bc1f39a0311cb0f41099be03ee2b202aeae (diff) |
airo: sanitize BSSListRid handling
Stop byteswap-in-place in readBSSListRid(), annotate the sucker.
BTW, that had immediately found a bug - another codepath fetching
the same struct from card did _not_ byteswap, but used ->dBm the
same as everything else - host-endian. Fix in the next patch...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r-- | drivers/net/wireless/airo.c | 69 |
1 files changed, 30 insertions, 39 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index ad91996acc47..a619af6960a7 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -749,39 +749,39 @@ typedef struct { | |||
749 | 749 | ||
750 | /* Only present on firmware >= 5.30.17 */ | 750 | /* Only present on firmware >= 5.30.17 */ |
751 | typedef struct { | 751 | typedef struct { |
752 | u16 unknown[4]; | 752 | __le16 unknown[4]; |
753 | u8 fixed[12]; /* WLAN management frame */ | 753 | u8 fixed[12]; /* WLAN management frame */ |
754 | u8 iep[624]; | 754 | u8 iep[624]; |
755 | } BSSListRidExtra; | 755 | } BSSListRidExtra; |
756 | 756 | ||
757 | typedef struct { | 757 | typedef struct { |
758 | u16 len; | 758 | __le16 len; |
759 | u16 index; /* First is 0 and 0xffff means end of list */ | 759 | __le16 index; /* First is 0 and 0xffff means end of list */ |
760 | #define RADIO_FH 1 /* Frequency hopping radio type */ | 760 | #define RADIO_FH 1 /* Frequency hopping radio type */ |
761 | #define RADIO_DS 2 /* Direct sequence radio type */ | 761 | #define RADIO_DS 2 /* Direct sequence radio type */ |
762 | #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */ | 762 | #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */ |
763 | u16 radioType; | 763 | __le16 radioType; |
764 | u8 bssid[ETH_ALEN]; /* Mac address of the BSS */ | 764 | u8 bssid[ETH_ALEN]; /* Mac address of the BSS */ |
765 | u8 zero; | 765 | u8 zero; |
766 | u8 ssidLen; | 766 | u8 ssidLen; |
767 | u8 ssid[32]; | 767 | u8 ssid[32]; |
768 | u16 dBm; | 768 | __le16 dBm; |
769 | #define CAP_ESS (1<<0) | 769 | #define CAP_ESS cpu_to_le16(1<<0) |
770 | #define CAP_IBSS (1<<1) | 770 | #define CAP_IBSS cpu_to_le16(1<<1) |
771 | #define CAP_PRIVACY (1<<4) | 771 | #define CAP_PRIVACY cpu_to_le16(1<<4) |
772 | #define CAP_SHORTHDR (1<<5) | 772 | #define CAP_SHORTHDR cpu_to_le16(1<<5) |
773 | u16 cap; | 773 | __le16 cap; |
774 | u16 beaconInterval; | 774 | __le16 beaconInterval; |
775 | u8 rates[8]; /* Same as rates for config rid */ | 775 | u8 rates[8]; /* Same as rates for config rid */ |
776 | struct { /* For frequency hopping only */ | 776 | struct { /* For frequency hopping only */ |
777 | u16 dwell; | 777 | __le16 dwell; |
778 | u8 hopSet; | 778 | u8 hopSet; |
779 | u8 hopPattern; | 779 | u8 hopPattern; |
780 | u8 hopIndex; | 780 | u8 hopIndex; |
781 | u8 fill; | 781 | u8 fill; |
782 | } fh; | 782 | } fh; |
783 | u16 dsChannel; | 783 | __le16 dsChannel; |
784 | u16 atimWindow; | 784 | __le16 atimWindow; |
785 | 785 | ||
786 | /* Only present on firmware >= 5.30.17 */ | 786 | /* Only present on firmware >= 5.30.17 */ |
787 | BSSListRidExtra extra; | 787 | BSSListRidExtra extra; |
@@ -1728,8 +1728,8 @@ static void emmh32_final(emmh32_context *context, u8 digest[4]) | |||
1728 | } | 1728 | } |
1729 | 1729 | ||
1730 | static int readBSSListRid(struct airo_info *ai, int first, | 1730 | static int readBSSListRid(struct airo_info *ai, int first, |
1731 | BSSListRid *list) { | 1731 | BSSListRid *list) |
1732 | int rc; | 1732 | { |
1733 | Cmd cmd; | 1733 | Cmd cmd; |
1734 | Resp rsp; | 1734 | Resp rsp; |
1735 | 1735 | ||
@@ -1746,19 +1746,8 @@ static int readBSSListRid(struct airo_info *ai, int first, | |||
1746 | schedule_timeout_uninterruptible(3 * HZ); | 1746 | schedule_timeout_uninterruptible(3 * HZ); |
1747 | ai->list_bss_task = NULL; | 1747 | ai->list_bss_task = NULL; |
1748 | } | 1748 | } |
1749 | rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext, | 1749 | return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext, |
1750 | list, ai->bssListRidLen, 1); | 1750 | list, ai->bssListRidLen, 1); |
1751 | |||
1752 | list->len = le16_to_cpu(list->len); | ||
1753 | list->index = le16_to_cpu(list->index); | ||
1754 | list->radioType = le16_to_cpu(list->radioType); | ||
1755 | list->cap = le16_to_cpu(list->cap); | ||
1756 | list->beaconInterval = le16_to_cpu(list->beaconInterval); | ||
1757 | list->fh.dwell = le16_to_cpu(list->fh.dwell); | ||
1758 | list->dsChannel = le16_to_cpu(list->dsChannel); | ||
1759 | list->atimWindow = le16_to_cpu(list->atimWindow); | ||
1760 | list->dBm = le16_to_cpu(list->dBm); | ||
1761 | return rc; | ||
1762 | } | 1751 | } |
1763 | 1752 | ||
1764 | static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp, int lock) { | 1753 | static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp, int lock) { |
@@ -3028,14 +3017,14 @@ static void airo_process_scan_results (struct airo_info *ai) { | |||
3028 | 3017 | ||
3029 | /* Try to read the first entry of the scan result */ | 3018 | /* Try to read the first entry of the scan result */ |
3030 | rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0); | 3019 | rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0); |
3031 | if((rc) || (bss.index == 0xffff)) { | 3020 | if((rc) || (bss.index == cpu_to_le16(0xffff))) { |
3032 | /* No scan results */ | 3021 | /* No scan results */ |
3033 | goto out; | 3022 | goto out; |
3034 | } | 3023 | } |
3035 | 3024 | ||
3036 | /* Read and parse all entries */ | 3025 | /* Read and parse all entries */ |
3037 | tmp_net = NULL; | 3026 | tmp_net = NULL; |
3038 | while((!rc) && (bss.index != 0xffff)) { | 3027 | while((!rc) && (bss.index != cpu_to_le16(0xffff))) { |
3039 | /* Grab a network off the free list */ | 3028 | /* Grab a network off the free list */ |
3040 | if (!list_empty(&ai->network_free_list)) { | 3029 | if (!list_empty(&ai->network_free_list)) { |
3041 | tmp_net = list_entry(ai->network_free_list.next, | 3030 | tmp_net = list_entry(ai->network_free_list.next, |
@@ -5472,14 +5461,14 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { | |||
5472 | Since it is a rare condition, we'll just live with it, otherwise | 5461 | Since it is a rare condition, we'll just live with it, otherwise |
5473 | we have to add a spin lock... */ | 5462 | we have to add a spin lock... */ |
5474 | rc = readBSSListRid(ai, doLoseSync, &BSSList_rid); | 5463 | rc = readBSSListRid(ai, doLoseSync, &BSSList_rid); |
5475 | while(rc == 0 && BSSList_rid.index != 0xffff) { | 5464 | while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) { |
5476 | ptr += sprintf(ptr, "%s %*s rssi = %d", | 5465 | ptr += sprintf(ptr, "%s %*s rssi = %d", |
5477 | print_mac(mac, BSSList_rid.bssid), | 5466 | print_mac(mac, BSSList_rid.bssid), |
5478 | (int)BSSList_rid.ssidLen, | 5467 | (int)BSSList_rid.ssidLen, |
5479 | BSSList_rid.ssid, | 5468 | BSSList_rid.ssid, |
5480 | (int)BSSList_rid.dBm); | 5469 | le16_to_cpu(BSSList_rid.dBm)); |
5481 | ptr += sprintf(ptr, " channel = %d %s %s %s %s\n", | 5470 | ptr += sprintf(ptr, " channel = %d %s %s %s %s\n", |
5482 | (int)BSSList_rid.dsChannel, | 5471 | le16_to_cpu(BSSList_rid.dsChannel), |
5483 | BSSList_rid.cap & CAP_ESS ? "ESS" : "", | 5472 | BSSList_rid.cap & CAP_ESS ? "ESS" : "", |
5484 | BSSList_rid.cap & CAP_IBSS ? "adhoc" : "", | 5473 | BSSList_rid.cap & CAP_IBSS ? "adhoc" : "", |
5485 | BSSList_rid.cap & CAP_PRIVACY ? "wep" : "", | 5474 | BSSList_rid.cap & CAP_PRIVACY ? "wep" : "", |
@@ -7096,26 +7085,28 @@ static int airo_get_aplist(struct net_device *dev, | |||
7096 | int loseSync = capable(CAP_NET_ADMIN) ? 1: -1; | 7085 | int loseSync = capable(CAP_NET_ADMIN) ? 1: -1; |
7097 | 7086 | ||
7098 | for (i = 0; i < IW_MAX_AP; i++) { | 7087 | for (i = 0; i < IW_MAX_AP; i++) { |
7088 | u16 dBm; | ||
7099 | if (readBSSListRid(local, loseSync, &BSSList)) | 7089 | if (readBSSListRid(local, loseSync, &BSSList)) |
7100 | break; | 7090 | break; |
7101 | loseSync = 0; | 7091 | loseSync = 0; |
7102 | memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN); | 7092 | memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN); |
7103 | address[i].sa_family = ARPHRD_ETHER; | 7093 | address[i].sa_family = ARPHRD_ETHER; |
7094 | dBm = le16_to_cpu(BSSList.dBm); | ||
7104 | if (local->rssi) { | 7095 | if (local->rssi) { |
7105 | qual[i].level = 0x100 - BSSList.dBm; | 7096 | qual[i].level = 0x100 - dBm; |
7106 | qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm ); | 7097 | qual[i].qual = airo_dbm_to_pct(local->rssi, dBm); |
7107 | qual[i].updated = IW_QUAL_QUAL_UPDATED | 7098 | qual[i].updated = IW_QUAL_QUAL_UPDATED |
7108 | | IW_QUAL_LEVEL_UPDATED | 7099 | | IW_QUAL_LEVEL_UPDATED |
7109 | | IW_QUAL_DBM; | 7100 | | IW_QUAL_DBM; |
7110 | } else { | 7101 | } else { |
7111 | qual[i].level = (BSSList.dBm + 321) / 2; | 7102 | qual[i].level = (dBm + 321) / 2; |
7112 | qual[i].qual = 0; | 7103 | qual[i].qual = 0; |
7113 | qual[i].updated = IW_QUAL_QUAL_INVALID | 7104 | qual[i].updated = IW_QUAL_QUAL_INVALID |
7114 | | IW_QUAL_LEVEL_UPDATED | 7105 | | IW_QUAL_LEVEL_UPDATED |
7115 | | IW_QUAL_DBM; | 7106 | | IW_QUAL_DBM; |
7116 | } | 7107 | } |
7117 | qual[i].noise = local->wstats.qual.noise; | 7108 | qual[i].noise = local->wstats.qual.noise; |
7118 | if (BSSList.index == 0xffff) | 7109 | if (BSSList.index == cpu_to_le16(0xffff)) |
7119 | break; | 7110 | break; |
7120 | } | 7111 | } |
7121 | if (!i) { | 7112 | if (!i) { |
@@ -7206,7 +7197,7 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7206 | { | 7197 | { |
7207 | struct airo_info *ai = dev->priv; | 7198 | struct airo_info *ai = dev->priv; |
7208 | struct iw_event iwe; /* Temporary buffer */ | 7199 | struct iw_event iwe; /* Temporary buffer */ |
7209 | u16 capabilities; | 7200 | __le16 capabilities; |
7210 | char * current_val; /* For rates */ | 7201 | char * current_val; /* For rates */ |
7211 | int i; | 7202 | int i; |
7212 | char * buf; | 7203 | char * buf; |
@@ -7230,7 +7221,7 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7230 | 7221 | ||
7231 | /* Add mode */ | 7222 | /* Add mode */ |
7232 | iwe.cmd = SIOCGIWMODE; | 7223 | iwe.cmd = SIOCGIWMODE; |
7233 | capabilities = le16_to_cpu(bss->cap); | 7224 | capabilities = bss->cap; |
7234 | if(capabilities & (CAP_ESS | CAP_IBSS)) { | 7225 | if(capabilities & (CAP_ESS | CAP_IBSS)) { |
7235 | if(capabilities & CAP_ESS) | 7226 | if(capabilities & CAP_ESS) |
7236 | iwe.u.mode = IW_MODE_MASTER; | 7227 | iwe.u.mode = IW_MODE_MASTER; |