aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2007-12-19 18:56:37 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:00 -0500
commit17e70491404c73012a7991a068ba62ec59bebdb2 (patch)
treefbc490bfee01cc7cb0f3bde3b510fabfdf16c704 /drivers/net/wireless/airo.c
parentb8c06bc1f39a0311cb0f41099be03ee2b202aeae (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.c69
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 */
751typedef struct { 751typedef 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
757typedef struct { 757typedef 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
1730static int readBSSListRid(struct airo_info *ai, int first, 1730static 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
1764static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp, int lock) { 1753static 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;