aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-12-14 08:45:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-19 15:23:17 -0500
commit69ba3e5d74a467a64248cd90ccafb524b1fddcb5 (patch)
tree81d1dcf8216a132cce176321612cab6b6d36e601 /drivers
parentda9f57eade0a743450a201645db7fc5ac0809900 (diff)
p54: more accurate rssi to dBm conversion
This patch replaces the static rssi auto calibration data with more precise values out of the device's eeprom. Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/p54/p54.h8
-rw-r--r--drivers/net/wireless/p54/p54common.c69
-rw-r--r--drivers/net/wireless/p54/p54common.h17
3 files changed, 68 insertions, 26 deletions
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 23b80ef4d015..e0a68815a471 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -61,6 +61,13 @@ struct p54_edcf_queue_param {
61 __le16 txop; 61 __le16 txop;
62} __attribute__ ((packed)); 62} __attribute__ ((packed));
63 63
64struct p54_rssi_linear_approximation {
65 s16 mul;
66 s16 add;
67 s16 longbow_unkn;
68 s16 longbow_unk2;
69};
70
64#define EEPROM_READBACK_LEN 0x3fc 71#define EEPROM_READBACK_LEN 0x3fc
65 72
66#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 73#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -91,6 +98,7 @@ struct p54_common {
91 struct pda_channel_output_limit *output_limit; 98 struct pda_channel_output_limit *output_limit;
92 unsigned int output_limit_len; 99 unsigned int output_limit_len;
93 struct pda_pa_curve_data *curve_data; 100 struct pda_pa_curve_data *curve_data;
101 struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
94 unsigned int filter_flags; 102 unsigned int filter_flags;
95 bool use_short_slot; 103 bool use_short_slot;
96 u16 rxhw; 104 u16 rxhw;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index ddb858608a50..05eb677aa3e1 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -335,6 +335,36 @@ static const char *p54_rf_chips[] = { "NULL", "Duette3", "Duette2",
335 "Frisbee", "Xbow", "Longbow", "NULL", "NULL" }; 335 "Frisbee", "Xbow", "Longbow", "NULL", "NULL" };
336static int p54_init_xbow_synth(struct ieee80211_hw *dev); 336static int p54_init_xbow_synth(struct ieee80211_hw *dev);
337 337
338static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
339 u16 type)
340{
341 struct p54_common *priv = dev->priv;
342 int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
343 int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
344 int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
345 int i;
346
347 if (len != (entry_size * num_entries)) {
348 printk(KERN_ERR "%s: unknown rssi calibration data packing "
349 " type:(%x) len:%d.\n",
350 wiphy_name(dev->wiphy), type, len);
351
352 print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
353 data, len);
354
355 printk(KERN_ERR "%s: please report this issue.\n",
356 wiphy_name(dev->wiphy));
357 return;
358 }
359
360 for (i = 0; i < num_entries; i++) {
361 struct pda_rssi_cal_entry *cal = data +
362 (offset + i * entry_size);
363 priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
364 priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
365 }
366}
367
338static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) 368static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
339{ 369{
340 struct p54_common *priv = dev->priv; 370 struct p54_common *priv = dev->priv;
@@ -434,6 +464,12 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
434 case PDR_HARDWARE_PLATFORM_COMPONENT_ID: 464 case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
435 priv->version = *(u8 *)(entry->data + 1); 465 priv->version = *(u8 *)(entry->data + 1);
436 break; 466 break;
467 case PDR_RSSI_LINEAR_APPROXIMATION:
468 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
469 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
470 p54_parse_rssical(dev, entry->data, data_len,
471 le16_to_cpu(entry->code));
472 break;
437 case PDR_END: 473 case PDR_END:
438 /* make it overrun */ 474 /* make it overrun */
439 entry_len = len; 475 entry_len = len;
@@ -453,10 +489,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
453 case PDR_DEFAULT_COUNTRY: 489 case PDR_DEFAULT_COUNTRY:
454 case PDR_ANTENNA_GAIN: 490 case PDR_ANTENNA_GAIN:
455 case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA: 491 case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
456 case PDR_RSSI_LINEAR_APPROXIMATION:
457 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
458 case PDR_REGULATORY_POWER_LIMITS: 492 case PDR_REGULATORY_POWER_LIMITS:
459 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
460 case PDR_RADIATED_TRANSMISSION_CORRECTION: 493 case PDR_RADIATED_TRANSMISSION_CORRECTION:
461 case PDR_PRISM_TX_IQ_CALIBRATION: 494 case PDR_PRISM_TX_IQ_CALIBRATION:
462 case PDR_BASEBAND_REGISTERS: 495 case PDR_BASEBAND_REGISTERS:
@@ -527,8 +560,11 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
527 560
528static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) 561static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
529{ 562{
530 /* TODO: get the rssi_add & rssi_mul data from the eeprom */ 563 struct p54_common *priv = dev->priv;
531 return ((rssi * 0x83) / 64 - 400) / 4; 564 int band = dev->conf.channel->band;
565
566 return ((rssi * priv->rssical_db[band].mul) / 64 +
567 priv->rssical_db[band].add) / 4;
532} 568}
533 569
534static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) 570static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
@@ -1466,15 +1502,15 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
1466 return 0; 1502 return 0;
1467} 1503}
1468 1504
1469static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell, 1505static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
1470 u16 frequency)
1471{ 1506{
1472 struct p54_common *priv = dev->priv; 1507 struct p54_common *priv = dev->priv;
1473 struct sk_buff *skb; 1508 struct sk_buff *skb;
1474 struct p54_scan *chan; 1509 struct p54_scan *chan;
1475 unsigned int i; 1510 unsigned int i;
1476 void *entry; 1511 void *entry;
1477 __le16 freq = cpu_to_le16(frequency); 1512 __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
1513 int band = dev->conf.channel->band;
1478 1514
1479 skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) + 1515 skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
1480 sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN, 1516 sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
@@ -1535,11 +1571,11 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell,
1535 } 1571 }
1536 1572
1537 if (priv->fw_var < 0x500) { 1573 if (priv->fw_var < 0x500) {
1538 chan->v1.rssical_mul = cpu_to_le16(130); 1574 chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
1539 chan->v1.rssical_add = cpu_to_le16(0xfe70); 1575 chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add);
1540 } else { 1576 } else {
1541 chan->v2.rssical_mul = cpu_to_le16(130); 1577 chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
1542 chan->v2.rssical_add = cpu_to_le16(0xfe70); 1578 chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
1543 chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); 1579 chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
1544 memset(chan->v2.rts_rates, 0, 8); 1580 memset(chan->v2.rts_rates, 0, 8);
1545 } 1581 }
@@ -1801,8 +1837,7 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
1801 goto out; 1837 goto out;
1802 } 1838 }
1803 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1839 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1804 ret = p54_scan(dev, P54_SCAN_EXIT, 0, 1840 ret = p54_scan(dev, P54_SCAN_EXIT, 0);
1805 conf->channel->center_freq);
1806 if (ret) 1841 if (ret)
1807 goto out; 1842 goto out;
1808 } 1843 }
@@ -1828,8 +1863,7 @@ static int p54_config_interface(struct ieee80211_hw *dev,
1828 } 1863 }
1829 1864
1830 if (conf->changed & IEEE80211_IFCC_BEACON) { 1865 if (conf->changed & IEEE80211_IFCC_BEACON) {
1831 ret = p54_scan(dev, P54_SCAN_EXIT, 0, 1866 ret = p54_scan(dev, P54_SCAN_EXIT, 0);
1832 dev->conf.channel->center_freq);
1833 if (ret) 1867 if (ret)
1834 goto out; 1868 goto out;
1835 ret = p54_setup_mac(dev); 1869 ret = p54_setup_mac(dev);
@@ -1968,8 +2002,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
1968 priv->basic_rate_mask = info->basic_rates; 2002 priv->basic_rate_mask = info->basic_rates;
1969 p54_setup_mac(dev); 2003 p54_setup_mac(dev);
1970 if (priv->fw_var >= 0x500) 2004 if (priv->fw_var >= 0x500)
1971 p54_scan(dev, P54_SCAN_EXIT, 0, 2005 p54_scan(dev, P54_SCAN_EXIT, 0);
1972 dev->conf.channel->center_freq);
1973 } 2006 }
1974 if (changed & BSS_CHANGED_ASSOC) { 2007 if (changed & BSS_CHANGED_ASSOC) {
1975 if (info->assoc) { 2008 if (info->assoc) {
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 06e1643cc295..6c824e40f3ba 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -178,6 +178,11 @@ struct pda_pa_curve_data {
178 u8 data[0]; 178 u8 data[0];
179} __attribute__ ((packed)); 179} __attribute__ ((packed));
180 180
181struct pda_rssi_cal_entry {
182 __le16 mul;
183 __le16 add;
184} __attribute__ ((packed));
185
181/* 186/*
182 * this defines the PDR codes used to build PDAs as defined in document 187 * this defines the PDR codes used to build PDAs as defined in document
183 * number 553155. The current implementation mirrors version 1.1 of the 188 * number 553155. The current implementation mirrors version 1.1 of the
@@ -429,22 +434,18 @@ struct p54_scan {
429 u8 dup_16qam; 434 u8 dup_16qam;
430 u8 dup_64qam; 435 u8 dup_64qam;
431 union { 436 union {
432 struct { 437 struct pda_rssi_cal_entry v1_rssi;
433 __le16 rssical_mul;
434 __le16 rssical_add;
435 } v1 __attribute__ ((packed));
436 438
437 struct { 439 struct {
438 __le32 basic_rate_mask; 440 __le32 basic_rate_mask;
439 u8 rts_rates[8]; 441 u8 rts_rates[8];
440 __le16 rssical_mul; 442 struct pda_rssi_cal_entry rssi;
441 __le16 rssical_add;
442 } v2 __attribute__ ((packed)); 443 } v2 __attribute__ ((packed));
443 } __attribute__ ((packed)); 444 } __attribute__ ((packed));
444} __attribute__ ((packed)); 445} __attribute__ ((packed));
445 446
446#define P54_SCAN_V1_LEN (sizeof(struct p54_scan)-12) 447#define P54_SCAN_V1_LEN 0x70
447#define P54_SCAN_V2_LEN (sizeof(struct p54_scan)) 448#define P54_SCAN_V2_LEN 0x7c
448 449
449struct p54_led { 450struct p54_led {
450 __le16 mode; 451 __le16 mode;