aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
author <jgarzik@pretzel.yyz.us>2005-05-27 22:08:07 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-05-27 22:08:07 -0400
commit51a730d758ae4052e10ca7e06336f10af598c4fc (patch)
treeb76a004c00cd7139659be515ee03398e47067290 /drivers/net/wireless/airo.c
parent6cd15a9daf826115356f9403494c76e5aafa7793 (diff)
parentff0e0ea2f5d36fa90fc2c57fd019102b0a0cfabf (diff)
Automatic merge of /spare/repo/netdev-2.6 branch we18-ieee80211
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r--drivers/net/wireless/airo.c150
1 files changed, 104 insertions, 46 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index e3168a13b786..4314df28d60d 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -754,7 +754,7 @@ typedef struct {
754 u8 zero; 754 u8 zero;
755 u8 ssidLen; 755 u8 ssidLen;
756 u8 ssid[32]; 756 u8 ssid[32];
757 u16 rssi; 757 u16 dBm;
758#define CAP_ESS (1<<0) 758#define CAP_ESS (1<<0)
759#define CAP_IBSS (1<<1) 759#define CAP_IBSS (1<<1)
760#define CAP_PRIVACY (1<<4) 760#define CAP_PRIVACY (1<<4)
@@ -1125,6 +1125,9 @@ static int micsetup(struct airo_info *ai);
1125static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); 1125static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
1126static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); 1126static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1127 1127
1128static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
1129static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
1130
1128#include <linux/crypto.h> 1131#include <linux/crypto.h>
1129#endif 1132#endif
1130 1133
@@ -1720,6 +1723,7 @@ static int readBSSListRid(struct airo_info *ai, int first,
1720 list->fh.dwell = le16_to_cpu(list->fh.dwell); 1723 list->fh.dwell = le16_to_cpu(list->fh.dwell);
1721 list->dsChannel = le16_to_cpu(list->dsChannel); 1724 list->dsChannel = le16_to_cpu(list->dsChannel);
1722 list->atimWindow = le16_to_cpu(list->atimWindow); 1725 list->atimWindow = le16_to_cpu(list->atimWindow);
1726 list->dBm = le16_to_cpu(list->dBm);
1723 return rc; 1727 return rc;
1724} 1728}
1725 1729
@@ -3252,7 +3256,10 @@ badrx:
3252 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; 3256 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
3253 else 3257 else
3254 wstats.level = (hdr.rssi[1] + 321) / 2; 3258 wstats.level = (hdr.rssi[1] + 321) / 2;
3255 wstats.updated = 3; 3259 wstats.noise = apriv->wstats.qual.noise;
3260 wstats.updated = IW_QUAL_LEVEL_UPDATED
3261 | IW_QUAL_QUAL_UPDATED
3262 | IW_QUAL_NOISE_UPDATED;
3256 /* Update spy records */ 3263 /* Update spy records */
3257 wireless_spy_update(dev, sa, &wstats); 3264 wireless_spy_update(dev, sa, &wstats);
3258 } 3265 }
@@ -3595,7 +3602,10 @@ void mpi_receive_802_11 (struct airo_info *ai)
3595 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm; 3602 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3596 else 3603 else
3597 wstats.level = (hdr.rssi[1] + 321) / 2; 3604 wstats.level = (hdr.rssi[1] + 321) / 2;
3598 wstats.updated = 3; 3605 wstats.noise = ai->wstats.qual.noise;
3606 wstats.updated = IW_QUAL_QUAL_UPDATED
3607 | IW_QUAL_LEVEL_UPDATED
3608 | IW_QUAL_NOISE_UPDATED;
3599 /* Update spy records */ 3609 /* Update spy records */
3600 wireless_spy_update(ai->dev, sa, &wstats); 3610 wireless_spy_update(ai->dev, sa, &wstats);
3601 } 3611 }
@@ -3686,7 +3696,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3686 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock); 3696 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3687 if ( status == SUCCESS ) { 3697 if ( status == SUCCESS ) {
3688 if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL) 3698 if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3689 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); 3699 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3690 } 3700 }
3691 else { 3701 else {
3692 if (ai->rssi) { 3702 if (ai->rssi) {
@@ -5355,7 +5365,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5355 (int)BSSList_rid.bssid[5], 5365 (int)BSSList_rid.bssid[5],
5356 (int)BSSList_rid.ssidLen, 5366 (int)BSSList_rid.ssidLen,
5357 BSSList_rid.ssid, 5367 BSSList_rid.ssid,
5358 (int)BSSList_rid.rssi); 5368 (int)BSSList_rid.dBm);
5359 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n", 5369 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5360 (int)BSSList_rid.dsChannel, 5370 (int)BSSList_rid.dsChannel,
5361 BSSList_rid.cap & CAP_ESS ? "ESS" : "", 5371 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
@@ -5600,6 +5610,29 @@ static void __exit airo_cleanup_module( void )
5600 * would not work at all... - Jean II 5610 * would not work at all... - Jean II
5601 */ 5611 */
5602 5612
5613static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5614{
5615 if( !rssi_rid )
5616 return 0;
5617
5618 return (0x100 - rssi_rid[rssi].rssidBm);
5619}
5620
5621static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5622{
5623 int i;
5624
5625 if( !rssi_rid )
5626 return 0;
5627
5628 for( i = 0; i < 256; i++ )
5629 if (rssi_rid[i].rssidBm == dbm)
5630 return rssi_rid[i].rssipct;
5631
5632 return 0;
5633}
5634
5635
5603static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid) 5636static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5604{ 5637{
5605 int quality = 0; 5638 int quality = 0;
@@ -6450,11 +6483,29 @@ static int airo_get_range(struct net_device *dev,
6450 } 6483 }
6451 range->num_frequency = k; 6484 range->num_frequency = k;
6452 6485
6486 range->sensitivity = 65535;
6487
6453 /* Hum... Should put the right values there */ 6488 /* Hum... Should put the right values there */
6454 range->max_qual.qual = airo_get_max_quality(&cap_rid); 6489 if (local->rssi)
6455 range->max_qual.level = 0x100 - 120; /* -120 dBm */ 6490 range->max_qual.qual = 100; /* % */
6491 else
6492 range->max_qual.qual = airo_get_max_quality(&cap_rid);
6493 range->max_qual.level = 0; /* 0 means we use dBm */
6456 range->max_qual.noise = 0; 6494 range->max_qual.noise = 0;
6457 range->sensitivity = 65535; 6495 range->max_qual.updated = 0;
6496
6497 /* Experimental measurements - boundary 11/5.5 Mb/s */
6498 /* Note : with or without the (local->rssi), results
6499 * are somewhat different. - Jean II */
6500 if (local->rssi) {
6501 range->avg_qual.qual = 50; /* % */
6502 range->avg_qual.level = 186; /* -70 dBm */
6503 } else {
6504 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6505 range->avg_qual.level = 176; /* -80 dBm */
6506 }
6507 range->avg_qual.noise = 0;
6508 range->avg_qual.updated = 0;
6458 6509
6459 for(i = 0 ; i < 8 ; i++) { 6510 for(i = 0 ; i < 8 ; i++) {
6460 range->bitrate[i] = cap_rid.supportedRates[i] * 500000; 6511 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
@@ -6515,15 +6566,6 @@ static int airo_get_range(struct net_device *dev,
6515 range->max_retry = 65535; 6566 range->max_retry = 65535;
6516 range->min_r_time = 1024; 6567 range->min_r_time = 1024;
6517 range->max_r_time = 65535 * 1024; 6568 range->max_r_time = 65535 * 1024;
6518 /* Experimental measurements - boundary 11/5.5 Mb/s */
6519 /* Note : with or without the (local->rssi), results
6520 * are somewhat different. - Jean II */
6521 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6522 if (local->rssi)
6523 range->avg_qual.level = 186; /* -70 dBm */
6524 else
6525 range->avg_qual.level = 176; /* -80 dBm */
6526 range->avg_qual.noise = 0;
6527 6569
6528 /* Event capability (kernel + driver) */ 6570 /* Event capability (kernel + driver) */
6529 range->event_capa[0] = (IW_EVENT_CAPA_K_0 | 6571 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
@@ -6683,12 +6725,18 @@ static int airo_get_aplist(struct net_device *dev,
6683 loseSync = 0; 6725 loseSync = 0;
6684 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN); 6726 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
6685 address[i].sa_family = ARPHRD_ETHER; 6727 address[i].sa_family = ARPHRD_ETHER;
6686 if (local->rssi) 6728 if (local->rssi) {
6687 qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm; 6729 qual[i].level = 0x100 - BSSList.dBm;
6688 else 6730 qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm );
6689 qual[i].level = (BSSList.rssi + 321) / 2; 6731 qual[i].updated = IW_QUAL_QUAL_UPDATED;
6690 qual[i].qual = qual[i].noise = 0; 6732 } else {
6691 qual[i].updated = 2; 6733 qual[i].level = (BSSList.dBm + 321) / 2;
6734 qual[i].qual = 0;
6735 qual[i].updated = IW_QUAL_QUAL_INVALID;
6736 }
6737 qual[i].noise = local->wstats.qual.noise;
6738 qual[i].updated = IW_QUAL_LEVEL_UPDATED
6739 | IW_QUAL_NOISE_UPDATED;
6692 if (BSSList.index == 0xffff) 6740 if (BSSList.index == 0xffff)
6693 break; 6741 break;
6694 } 6742 }
@@ -6767,7 +6815,7 @@ static int airo_set_scan(struct net_device *dev,
6767static inline char *airo_translate_scan(struct net_device *dev, 6815static inline char *airo_translate_scan(struct net_device *dev,
6768 char *current_ev, 6816 char *current_ev,
6769 char *end_buf, 6817 char *end_buf,
6770 BSSListRid *list) 6818 BSSListRid *bss)
6771{ 6819{
6772 struct airo_info *ai = dev->priv; 6820 struct airo_info *ai = dev->priv;
6773 struct iw_event iwe; /* Temporary buffer */ 6821 struct iw_event iwe; /* Temporary buffer */
@@ -6778,22 +6826,22 @@ static inline char *airo_translate_scan(struct net_device *dev,
6778 /* First entry *MUST* be the AP MAC address */ 6826 /* First entry *MUST* be the AP MAC address */
6779 iwe.cmd = SIOCGIWAP; 6827 iwe.cmd = SIOCGIWAP;
6780 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 6828 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
6781 memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN); 6829 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
6782 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 6830 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
6783 6831
6784 /* Other entries will be displayed in the order we give them */ 6832 /* Other entries will be displayed in the order we give them */
6785 6833
6786 /* Add the ESSID */ 6834 /* Add the ESSID */
6787 iwe.u.data.length = list->ssidLen; 6835 iwe.u.data.length = bss->ssidLen;
6788 if(iwe.u.data.length > 32) 6836 if(iwe.u.data.length > 32)
6789 iwe.u.data.length = 32; 6837 iwe.u.data.length = 32;
6790 iwe.cmd = SIOCGIWESSID; 6838 iwe.cmd = SIOCGIWESSID;
6791 iwe.u.data.flags = 1; 6839 iwe.u.data.flags = 1;
6792 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid); 6840 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
6793 6841
6794 /* Add mode */ 6842 /* Add mode */
6795 iwe.cmd = SIOCGIWMODE; 6843 iwe.cmd = SIOCGIWMODE;
6796 capabilities = le16_to_cpu(list->cap); 6844 capabilities = le16_to_cpu(bss->cap);
6797 if(capabilities & (CAP_ESS | CAP_IBSS)) { 6845 if(capabilities & (CAP_ESS | CAP_IBSS)) {
6798 if(capabilities & CAP_ESS) 6846 if(capabilities & CAP_ESS)
6799 iwe.u.mode = IW_MODE_MASTER; 6847 iwe.u.mode = IW_MODE_MASTER;
@@ -6804,19 +6852,25 @@ static inline char *airo_translate_scan(struct net_device *dev,
6804 6852
6805 /* Add frequency */ 6853 /* Add frequency */
6806 iwe.cmd = SIOCGIWFREQ; 6854 iwe.cmd = SIOCGIWFREQ;
6807 iwe.u.freq.m = le16_to_cpu(list->dsChannel); 6855 iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
6808 iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000; 6856 iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
6809 iwe.u.freq.e = 1; 6857 iwe.u.freq.e = 1;
6810 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); 6858 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
6811 6859
6812 /* Add quality statistics */ 6860 /* Add quality statistics */
6813 iwe.cmd = IWEVQUAL; 6861 iwe.cmd = IWEVQUAL;
6814 if (ai->rssi) 6862 if (ai->rssi) {
6815 iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm; 6863 iwe.u.qual.level = 0x100 - bss->dBm;
6816 else 6864 iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm );
6817 iwe.u.qual.level = (list->rssi + 321) / 2; 6865 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED;
6818 iwe.u.qual.noise = 0; 6866 } else {
6819 iwe.u.qual.qual = 0; 6867 iwe.u.qual.level = (bss->dBm + 321) / 2;
6868 iwe.u.qual.qual = 0;
6869 iwe.u.qual.updated = IW_QUAL_QUAL_INVALID;
6870 }
6871 iwe.u.qual.noise = ai->wstats.qual.noise;
6872 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
6873 | IW_QUAL_NOISE_UPDATED;
6820 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 6874 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
6821 6875
6822 /* Add encryption capability */ 6876 /* Add encryption capability */
@@ -6826,7 +6880,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
6826 else 6880 else
6827 iwe.u.data.flags = IW_ENCODE_DISABLED; 6881 iwe.u.data.flags = IW_ENCODE_DISABLED;
6828 iwe.u.data.length = 0; 6882 iwe.u.data.length = 0;
6829 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid); 6883 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
6830 6884
6831 /* Rate : stuffing multiple values in a single event require a bit 6885 /* Rate : stuffing multiple values in a single event require a bit
6832 * more of magic - Jean II */ 6886 * more of magic - Jean II */
@@ -6838,10 +6892,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
6838 /* Max 8 values */ 6892 /* Max 8 values */
6839 for(i = 0 ; i < 8 ; i++) { 6893 for(i = 0 ; i < 8 ; i++) {
6840 /* NULL terminated */ 6894 /* NULL terminated */
6841 if(list->rates[i] == 0) 6895 if(bss->rates[i] == 0)
6842 break; 6896 break;
6843 /* Bit rate given in 500 kb/s units (+ 0x80) */ 6897 /* Bit rate given in 500 kb/s units (+ 0x80) */
6844 iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000); 6898 iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
6845 /* Add new value to event */ 6899 /* Add new value to event */
6846 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); 6900 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
6847 } 6901 }
@@ -7160,18 +7214,22 @@ static void airo_read_wireless_stats(struct airo_info *local)
7160 /* The status */ 7214 /* The status */
7161 local->wstats.status = status_rid.mode; 7215 local->wstats.status = status_rid.mode;
7162 7216
7163 /* Signal quality and co. But where is the noise level ??? */ 7217 /* Signal quality and co */
7164 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); 7218 if (local->rssi) {
7165 if (local->rssi) 7219 local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality );
7166 local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm; 7220 /* normalizedSignalStrength appears to be a percentage */
7167 else 7221 local->wstats.qual.qual = status_rid.normalizedSignalStrength;
7222 } else {
7168 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; 7223 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
7224 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7225 }
7226 local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED;
7169 if (status_rid.len >= 124) { 7227 if (status_rid.len >= 124) {
7170 local->wstats.qual.noise = 256 - status_rid.noisedBm; 7228 local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7171 local->wstats.qual.updated = 7; 7229 local->wstats.qual.updated |= IW_QUAL_NOISE_UPDATED;
7172 } else { 7230 } else {
7173 local->wstats.qual.noise = 0; 7231 local->wstats.qual.noise = 0;
7174 local->wstats.qual.updated = 3; 7232 local->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
7175 } 7233 }
7176 7234
7177 /* Packets discarded in the wireless adapter due to wireless 7235 /* Packets discarded in the wireless adapter due to wireless