All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Lamparter <chunkeey@web.de>
To: linux-wireless@vger.kernel.org
Subject: [PATCH] p54: more accurate rssi to dBm conversion
Date: Sun, 14 Dec 2008 14:45:30 +0100	[thread overview]
Message-ID: <200812141445.30851.chunkeey@web.de> (raw)

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>
---
diff -Nurp a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
--- a/drivers/net/wireless/p54/p54common.c	2008-12-13 20:55:27.000000000 +0100
+++ b/drivers/net/wireless/p54/p54common.c	2008-12-13 23:06:53.000000000 +0100
@@ -335,6 +335,36 @@ static const char *p54_rf_chips[] = { "N
                               "Frisbee", "Xbow", "Longbow", "NULL", "NULL" };
 static int p54_init_xbow_synth(struct ieee80211_hw *dev);
 
+static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
+			     u16 type)
+{
+	struct p54_common *priv = dev->priv;
+	int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
+	int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
+	int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
+	int i;
+
+	if (len != (entry_size * num_entries)) {
+		printk(KERN_ERR "%s: unknown rssi calibration data packing "
+				 " type:(%x) len:%d.\n",
+		       wiphy_name(dev->wiphy), type, len);
+
+		print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
+				     data, len);
+
+		printk(KERN_ERR "%s: please report this issue.\n",
+			wiphy_name(dev->wiphy));
+		return;
+	}
+
+	for (i = 0; i < num_entries; i++) {
+		struct pda_rssi_cal_entry *cal = data +
+						 (offset + i * entry_size);
+		priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
+		priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
+	}
+}
+
 static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 {
 	struct p54_common *priv = dev->priv;
@@ -435,6 +465,12 @@ static int p54_parse_eeprom(struct ieee8
 		case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
 			priv->version = *(u8 *)(entry->data + 1);
 			break;
+		case PDR_RSSI_LINEAR_APPROXIMATION:
+		case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
+		case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
+			p54_parse_rssical(dev, entry->data, data_len,
+					  le16_to_cpu(entry->code));
+			break;
 		case PDR_END:
 			/* make it overrun */
 			entry_len = len;
@@ -454,10 +490,7 @@ static int p54_parse_eeprom(struct ieee8
 		case PDR_DEFAULT_COUNTRY:
 		case PDR_ANTENNA_GAIN:
 		case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
-		case PDR_RSSI_LINEAR_APPROXIMATION:
-		case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
 		case PDR_REGULATORY_POWER_LIMITS:
-		case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
 		case PDR_RADIATED_TRANSMISSION_CORRECTION:
 		case PDR_PRISM_TX_IQ_CALIBRATION:
 		case PDR_BASEBAND_REGISTERS:
@@ -528,8 +561,11 @@ static int p54_parse_eeprom(struct ieee8
 
 static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
 {
-	/* TODO: get the rssi_add & rssi_mul data from the eeprom */
-	return ((rssi * 0x83) / 64 - 400) / 4;
+	struct p54_common *priv = dev->priv;
+	int band = dev->conf.channel->band;
+
+	return ((rssi * priv->rssical_db[band].mul) / 64 +
+			 priv->rssical_db[band].add) / 4;
 }
 
 static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
@@ -1467,15 +1503,15 @@ static int p54_setup_mac(struct ieee8021
 	return 0;
 }
 
-static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell,
-		    u16 frequency)
+static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
 {
 	struct p54_common *priv = dev->priv;
 	struct sk_buff *skb;
 	struct p54_scan *chan;
 	unsigned int i;
 	void *entry;
-	__le16 freq = cpu_to_le16(frequency);
+	__le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
+	int band = dev->conf.channel->band;
 
 	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
 			    sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
@@ -1536,11 +1572,11 @@ static int p54_scan(struct ieee80211_hw 
 	}
 
 	if (priv->fw_var < 0x500) {
-		chan->v1.rssical_mul = cpu_to_le16(130);
-		chan->v1.rssical_add = cpu_to_le16(0xfe70);
+		chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
+		chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add);
 	} else {
-		chan->v2.rssical_mul = cpu_to_le16(130);
-		chan->v2.rssical_add = cpu_to_le16(0xfe70);
+		chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
+		chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
 		chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
 		memset(chan->v2.rts_rates, 0, 8);
 	}
@@ -1802,8 +1838,7 @@ static int p54_config(struct ieee80211_h
 			goto out;
 	}
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-		ret = p54_scan(dev, P54_SCAN_EXIT, 0,
-			       conf->channel->center_freq);
+		ret = p54_scan(dev, P54_SCAN_EXIT, 0);
 		if (ret)
 			goto out;
 	}
@@ -1829,8 +1864,7 @@ static int p54_config_interface(struct i
 	}
 
 	if (conf->changed & IEEE80211_IFCC_BEACON) {
-		ret = p54_scan(dev, P54_SCAN_EXIT, 0,
-			       dev->conf.channel->center_freq);
+		ret = p54_scan(dev, P54_SCAN_EXIT, 0);
 		if (ret)
 			goto out;
 		ret = p54_setup_mac(dev);
@@ -1969,8 +2003,7 @@ static void p54_bss_info_changed(struct 
 			priv->basic_rate_mask = info->basic_rates;
 		p54_setup_mac(dev);
 		if (priv->fw_var >= 0x500)
-			p54_scan(dev, P54_SCAN_EXIT, 0,
-				 dev->conf.channel->center_freq);
+			p54_scan(dev, P54_SCAN_EXIT, 0);
 	}
 	if (changed & BSS_CHANGED_ASSOC) {
 		if (info->assoc) {
diff -Nurp a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
--- a/drivers/net/wireless/p54/p54common.h	2008-12-13 21:10:30.000000000 +0100
+++ b/drivers/net/wireless/p54/p54common.h	2008-12-13 23:00:30.000000000 +0100
@@ -178,6 +178,11 @@ struct pda_pa_curve_data {
 	u8 data[0];
 } __attribute__ ((packed));
 
+struct pda_rssi_cal_entry {
+	__le16 mul;
+	__le16 add;
+} __attribute__ ((packed));
+
 /*
  * this defines the PDR codes used to build PDAs as defined in document
  * number 553155. The current implementation mirrors version 1.1 of the
@@ -429,22 +434,18 @@ struct p54_scan {
 	u8 dup_16qam;
 	u8 dup_64qam;
 	union {
-		struct {
-			__le16 rssical_mul;
-			__le16 rssical_add;
-		} v1 __attribute__ ((packed));
+		struct pda_rssi_cal_entry v1_rssi;
 
 		struct {
 			__le32 basic_rate_mask;
 			u8 rts_rates[8];
-			__le16 rssical_mul;
-			__le16 rssical_add;
+			struct pda_rssi_cal_entry rssi;
 		} v2 __attribute__ ((packed));
 	} __attribute__ ((packed));
 } __attribute__ ((packed));
 
-#define P54_SCAN_V1_LEN (sizeof(struct p54_scan)-12)
-#define P54_SCAN_V2_LEN (sizeof(struct p54_scan))
+#define P54_SCAN_V1_LEN 0x70
+#define P54_SCAN_V2_LEN 0x7c
 
 struct p54_led {
 	__le16 mode;
diff -Nurp a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
--- a/drivers/net/wireless/p54/p54.h	2008-12-13 16:16:26.000000000 +0100
+++ b/drivers/net/wireless/p54/p54.h	2008-12-13 23:01:29.000000000 +0100
@@ -61,6 +61,13 @@ struct p54_edcf_queue_param {
 	__le16 txop;
 } __attribute__ ((packed));
 
+struct p54_rssi_linear_approximation {
+	s16 mul;
+	s16 add;
+	s16 longbow_unkn;
+	s16 longbow_unk2;
+};
+
 #define EEPROM_READBACK_LEN 0x3fc
 
 #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -91,6 +98,7 @@ struct p54_common {
 	struct pda_channel_output_limit *output_limit;
 	unsigned int output_limit_len;
 	struct pda_pa_curve_data *curve_data;
+	struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
 	unsigned int filter_flags;
 	bool use_short_slot;
 	u16 rxhw;

                 reply	other threads:[~2008-12-14 13:45 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200812141445.30851.chunkeey@web.de \
    --to=chunkeey@web.de \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.