diff options
author | Christian Lamparter <chunkeey@web.de> | 2008-12-14 08:45:30 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-19 15:23:17 -0500 |
commit | 69ba3e5d74a467a64248cd90ccafb524b1fddcb5 (patch) | |
tree | 81d1dcf8216a132cce176321612cab6b6d36e601 /drivers | |
parent | da9f57eade0a743450a201645db7fc5ac0809900 (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.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 69 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.h | 17 |
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 | ||
64 | struct 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" }; |
336 | static int p54_init_xbow_synth(struct ieee80211_hw *dev); | 336 | static int p54_init_xbow_synth(struct ieee80211_hw *dev); |
337 | 337 | ||
338 | static 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 | |||
338 | static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | 368 | static 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 | ||
528 | static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) | 561 | static 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 | ||
534 | static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | 570 | static 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 | ||
1469 | static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell, | 1505 | static 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 | ||
181 | struct 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 | ||
449 | struct p54_led { | 450 | struct p54_led { |
450 | __le16 mode; | 451 | __le16 mode; |