aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2007-12-20 22:58:57 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:04 -0500
commit329e2c0067d5a2da88aa844bf57b2aaba9fceb2f (patch)
tree1830ac50a1e9ca708f20ba658de8d5b75606c794 /drivers/net/wireless/airo.c
parenta749716ecc85743f04f7117e3b373266b63edf7e (diff)
airo: sanitize handling of StatusRid
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.c132
1 files changed, 67 insertions, 65 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 306a1d1c1c22..f4a32a323642 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -648,30 +648,30 @@ typedef struct {
648} ConfigRid; 648} ConfigRid;
649 649
650typedef struct { 650typedef struct {
651 u16 len; 651 __le16 len;
652 u8 mac[ETH_ALEN]; 652 u8 mac[ETH_ALEN];
653 u16 mode; 653 __le16 mode;
654 u16 errorCode; 654 __le16 errorCode;
655 u16 sigQuality; 655 __le16 sigQuality;
656 u16 SSIDlen; 656 __le16 SSIDlen;
657 char SSID[32]; 657 char SSID[32];
658 char apName[16]; 658 char apName[16];
659 u8 bssid[4][ETH_ALEN]; 659 u8 bssid[4][ETH_ALEN];
660 u16 beaconPeriod; 660 __le16 beaconPeriod;
661 u16 dimPeriod; 661 __le16 dimPeriod;
662 u16 atimDuration; 662 __le16 atimDuration;
663 u16 hopPeriod; 663 __le16 hopPeriod;
664 u16 channelSet; 664 __le16 channelSet;
665 u16 channel; 665 __le16 channel;
666 u16 hopsToBackbone; 666 __le16 hopsToBackbone;
667 u16 apTotalLoad; 667 __le16 apTotalLoad;
668 u16 generatedLoad; 668 __le16 generatedLoad;
669 u16 accumulatedArl; 669 __le16 accumulatedArl;
670 u16 signalQuality; 670 __le16 signalQuality;
671 u16 currentXmitRate; 671 __le16 currentXmitRate;
672 u16 apDevExtensions; 672 __le16 apDevExtensions;
673 u16 normalizedSignalStrength; 673 __le16 normalizedSignalStrength;
674 u16 shortPreamble; 674 __le16 shortPreamble;
675 u8 apIP[4]; 675 u8 apIP[4];
676 u8 noisePercent; /* Noise percent in last second */ 676 u8 noisePercent; /* Noise percent in last second */
677 u8 noisedBm; /* Noise dBm in last second */ 677 u8 noisedBm; /* Noise dBm in last second */
@@ -679,9 +679,9 @@ typedef struct {
679 u8 noiseAvedBm; /* Noise dBm in last minute */ 679 u8 noiseAvedBm; /* Noise dBm in last minute */
680 u8 noiseMaxPercent; /* Highest noise percent in last minute */ 680 u8 noiseMaxPercent; /* Highest noise percent in last minute */
681 u8 noiseMaxdBm; /* Highest noise dbm in last minute */ 681 u8 noiseMaxdBm; /* Highest noise dbm in last minute */
682 u16 load; 682 __le16 load;
683 u8 carrier[4]; 683 u8 carrier[4];
684 u16 assocStatus; 684 __le16 assocStatus;
685#define STAT_NOPACKETS 0 685#define STAT_NOPACKETS 0
686#define STAT_NOCARRIERSET 10 686#define STAT_NOCARRIERSET 10
687#define STAT_GOTCARRIERSET 11 687#define STAT_GOTCARRIERSET 11
@@ -1853,18 +1853,10 @@ static int writeConfigRid(struct airo_info*ai, int lock) {
1853 1853
1854 return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock); 1854 return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1855} 1855}
1856static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) {
1857 int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1858 u16 *s;
1859
1860 statr->len = le16_to_cpu(statr->len);
1861 for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
1862 1856
1863 for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++) 1857static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
1864 *s = le16_to_cpu(*s); 1858{
1865 statr->load = le16_to_cpu(statr->load); 1859 return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1866 statr->assocStatus = le16_to_cpu(statr->assocStatus);
1867 return rc;
1868} 1860}
1869 1861
1870static int readAPListRid(struct airo_info *ai, APListRid *aplr) 1862static int readAPListRid(struct airo_info *ai, APListRid *aplr)
@@ -4656,13 +4648,15 @@ static ssize_t proc_write( struct file *file,
4656 return len; 4648 return len;
4657} 4649}
4658 4650
4659static int proc_status_open( struct inode *inode, struct file *file ) { 4651static int proc_status_open(struct inode *inode, struct file *file)
4652{
4660 struct proc_data *data; 4653 struct proc_data *data;
4661 struct proc_dir_entry *dp = PDE(inode); 4654 struct proc_dir_entry *dp = PDE(inode);
4662 struct net_device *dev = dp->data; 4655 struct net_device *dev = dp->data;
4663 struct airo_info *apriv = dev->priv; 4656 struct airo_info *apriv = dev->priv;
4664 CapabilityRid cap_rid; 4657 CapabilityRid cap_rid;
4665 StatusRid status_rid; 4658 StatusRid status_rid;
4659 u16 mode;
4666 int i; 4660 int i;
4667 4661
4668 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4662 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
@@ -4676,16 +4670,18 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4676 readStatusRid(apriv, &status_rid, 1); 4670 readStatusRid(apriv, &status_rid, 1);
4677 readCapabilityRid(apriv, &cap_rid, 1); 4671 readCapabilityRid(apriv, &cap_rid, 1);
4678 4672
4673 mode = le16_to_cpu(status_rid.mode);
4674
4679 i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n", 4675 i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4680 status_rid.mode & 1 ? "CFG ": "", 4676 mode & 1 ? "CFG ": "",
4681 status_rid.mode & 2 ? "ACT ": "", 4677 mode & 2 ? "ACT ": "",
4682 status_rid.mode & 0x10 ? "SYN ": "", 4678 mode & 0x10 ? "SYN ": "",
4683 status_rid.mode & 0x20 ? "LNK ": "", 4679 mode & 0x20 ? "LNK ": "",
4684 status_rid.mode & 0x40 ? "LEAP ": "", 4680 mode & 0x40 ? "LEAP ": "",
4685 status_rid.mode & 0x80 ? "PRIV ": "", 4681 mode & 0x80 ? "PRIV ": "",
4686 status_rid.mode & 0x100 ? "KEY ": "", 4682 mode & 0x100 ? "KEY ": "",
4687 status_rid.mode & 0x200 ? "WEP ": "", 4683 mode & 0x200 ? "WEP ": "",
4688 status_rid.mode & 0x8000 ? "ERR ": ""); 4684 mode & 0x8000 ? "ERR ": "");
4689 sprintf( data->rbuffer+i, "Mode: %x\n" 4685 sprintf( data->rbuffer+i, "Mode: %x\n"
4690 "Signal Strength: %d\n" 4686 "Signal Strength: %d\n"
4691 "Signal Quality: %d\n" 4687 "Signal Quality: %d\n"
@@ -4698,14 +4694,14 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4698 "Radio type: %x\nCountry: %x\nHardware Version: %x\n" 4694 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4699 "Software Version: %x\nSoftware Subversion: %x\n" 4695 "Software Version: %x\nSoftware Subversion: %x\n"
4700 "Boot block version: %x\n", 4696 "Boot block version: %x\n",
4701 (int)status_rid.mode, 4697 le16_to_cpu(status_rid.mode),
4702 (int)status_rid.normalizedSignalStrength, 4698 le16_to_cpu(status_rid.normalizedSignalStrength),
4703 (int)status_rid.signalQuality, 4699 le16_to_cpu(status_rid.signalQuality),
4704 (int)status_rid.SSIDlen, 4700 le16_to_cpu(status_rid.SSIDlen),
4705 status_rid.SSID, 4701 status_rid.SSID,
4706 status_rid.apName, 4702 status_rid.apName,
4707 (int)status_rid.channel, 4703 le16_to_cpu(status_rid.channel),
4708 (int)status_rid.currentXmitRate/2, 4704 le16_to_cpu(status_rid.currentXmitRate) / 2,
4709 version, 4705 version,
4710 cap_rid.prodName, 4706 cap_rid.prodName,
4711 cap_rid.manName, 4707 cap_rid.manName,
@@ -5726,25 +5722,27 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5726static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid) 5722static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5727{ 5723{
5728 int quality = 0; 5724 int quality = 0;
5725 u16 sq;
5729 5726
5730 if ((status_rid->mode & 0x3f) != 0x3f) 5727 if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5731 return 0; 5728 return 0;
5732 5729
5733 if (!(cap_rid->hardCap & cpu_to_le16(8))) 5730 if (!(cap_rid->hardCap & cpu_to_le16(8)))
5734 return 0; 5731 return 0;
5735 5732
5733 sq = le16_to_cpu(status_rid->signalQuality);
5736 if (memcmp(cap_rid->prodName, "350", 3)) 5734 if (memcmp(cap_rid->prodName, "350", 3))
5737 if (status_rid->signalQuality > 0x20) 5735 if (sq > 0x20)
5738 quality = 0; 5736 quality = 0;
5739 else 5737 else
5740 quality = 0x20 - status_rid->signalQuality; 5738 quality = 0x20 - sq;
5741 else 5739 else
5742 if (status_rid->signalQuality > 0xb0) 5740 if (sq > 0xb0)
5743 quality = 0; 5741 quality = 0;
5744 else if (status_rid->signalQuality < 0x10) 5742 else if (sq < 0x10)
5745 quality = 0xa0; 5743 quality = 0xa0;
5746 else 5744 else
5747 quality = 0xb0 - status_rid->signalQuality; 5745 quality = 0xb0 - sq;
5748 return quality; 5746 return quality;
5749} 5747}
5750 5748
@@ -5824,11 +5822,11 @@ static int airo_get_freq(struct net_device *dev,
5824 5822
5825 readConfigRid(local, 1); 5823 readConfigRid(local, 1);
5826 if ((local->config.opmode & 0xFF) == MODE_STA_ESS) 5824 if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
5827 status_rid.channel = local->config.channelSet; 5825 status_rid.channel = cpu_to_le16(local->config.channelSet);
5828 else 5826 else
5829 readStatusRid(local, &status_rid, 1); 5827 readStatusRid(local, &status_rid, 1);
5830 5828
5831 ch = (int)status_rid.channel; 5829 ch = le16_to_cpu(status_rid.channel);
5832 if((ch > 0) && (ch < 15)) { 5830 if((ch > 0) && (ch < 15)) {
5833 fwrq->m = frequency_list[ch - 1] * 100000; 5831 fwrq->m = frequency_list[ch - 1] * 100000;
5834 fwrq->e = 1; 5832 fwrq->e = 1;
@@ -5904,11 +5902,11 @@ static int airo_get_essid(struct net_device *dev,
5904 * get the relevant SSID from the SSID list... */ 5902 * get the relevant SSID from the SSID list... */
5905 5903
5906 /* Get the current SSID */ 5904 /* Get the current SSID */
5907 memcpy(extra, status_rid.SSID, status_rid.SSIDlen); 5905 memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5908 /* If none, we may want to get the one that was set */ 5906 /* If none, we may want to get the one that was set */
5909 5907
5910 /* Push it out ! */ 5908 /* Push it out ! */
5911 dwrq->length = status_rid.SSIDlen; 5909 dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5912 dwrq->flags = 1; /* active */ 5910 dwrq->flags = 1; /* active */
5913 5911
5914 return 0; 5912 return 0;
@@ -6098,7 +6096,7 @@ static int airo_get_rate(struct net_device *dev,
6098 6096
6099 readStatusRid(local, &status_rid, 1); 6097 readStatusRid(local, &status_rid, 1);
6100 6098
6101 vwrq->value = status_rid.currentXmitRate * 500000; 6099 vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6102 /* If more than one rate, set auto */ 6100 /* If more than one rate, set auto */
6103 readConfigRid(local, 1); 6101 readConfigRid(local, 1);
6104 vwrq->fixed = (local->config.rates[1] == 0); 6102 vwrq->fixed = (local->config.rates[1] == 0);
@@ -7646,18 +7644,22 @@ static void airo_read_wireless_stats(struct airo_info *local)
7646 up(&local->sem); 7644 up(&local->sem);
7647 7645
7648 /* The status */ 7646 /* The status */
7649 local->wstats.status = status_rid.mode; 7647 local->wstats.status = le16_to_cpu(status_rid.mode);
7650 7648
7651 /* Signal quality and co */ 7649 /* Signal quality and co */
7652 if (local->rssi) { 7650 if (local->rssi) {
7653 local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality ); 7651 local->wstats.qual.level =
7652 airo_rssi_to_dbm(local->rssi,
7653 le16_to_cpu(status_rid.sigQuality));
7654 /* normalizedSignalStrength appears to be a percentage */ 7654 /* normalizedSignalStrength appears to be a percentage */
7655 local->wstats.qual.qual = status_rid.normalizedSignalStrength; 7655 local->wstats.qual.qual =
7656 le16_to_cpu(status_rid.normalizedSignalStrength);
7656 } else { 7657 } else {
7657 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; 7658 local->wstats.qual.level =
7659 (le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7658 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); 7660 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7659 } 7661 }
7660 if (status_rid.len >= 124) { 7662 if (le16_to_cpu(status_rid.len) >= 124) {
7661 local->wstats.qual.noise = 0x100 - status_rid.noisedBm; 7663 local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7662 local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; 7664 local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7663 } else { 7665 } else {