* [PATCH 1/21] rt2x00: Move quality statistics into seperate structure
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
@ 2007-10-27 11:35 ` Ivo van Doorn
2007-10-27 11:35 ` [PATCH 2/21] rt2x00: Use enum defines Ivo van Doorn
` (20 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:35 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Move all link quality statistics variables into
the link_qual structure. This cleans up the link
structure and allows us to use it for more then
just statistics.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 11 +++---
drivers/net/wireless/rt2x00/rt2500pci.c | 11 +++---
drivers/net/wireless/rt2x00/rt2500usb.c | 12 +++---
drivers/net/wireless/rt2x00/rt2x00.h | 61 ++++++++++++++++++++-----------
drivers/net/wireless/rt2x00/rt2x00dev.c | 46 ++++++++++++------------
drivers/net/wireless/rt2x00/rt61pci.c | 12 +++---
drivers/net/wireless/rt2x00/rt73usb.c | 13 +++----
7 files changed, 92 insertions(+), 74 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 31c1dd2..31bbb44 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -542,7 +542,8 @@ static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev)
/*
* Link tuning
*/
-static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u32 reg;
u8 bbp;
@@ -551,13 +552,13 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev)
* Update FCS error count from register.
*/
rt2x00pci_register_read(rt2x00dev, CNT0, ®);
- rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
+ qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
/*
* Update False CCA count from register.
*/
rt2400pci_bbp_read(rt2x00dev, 39, &bbp);
- rt2x00dev->link.false_cca = bbp;
+ qual->false_cca = bbp;
}
static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -582,10 +583,10 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
*/
rt2400pci_bbp_read(rt2x00dev, 13, ®);
- if (rt2x00dev->link.false_cca > 512 && reg < 0x20) {
+ if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
rt2x00dev->link.vgc_level = reg;
- } else if (rt2x00dev->link.false_cca < 100 && reg > 0x08) {
+ } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
rt2400pci_bbp_write(rt2x00dev, 13, --reg);
rt2x00dev->link.vgc_level = reg;
}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index ff2d632..1f65e71 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -587,7 +587,8 @@ static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev)
/*
* Link tuning
*/
-static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u32 reg;
@@ -595,13 +596,13 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev)
* Update FCS error count from register.
*/
rt2x00pci_register_read(rt2x00dev, CNT0, ®);
- rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
+ qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
/*
* Update False CCA count from register.
*/
rt2x00pci_register_read(rt2x00dev, CNT3, ®);
- rt2x00dev->link.false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
+ qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
}
static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -679,10 +680,10 @@ dynamic_cca_tune:
* R17 is inside the dynamic tuning range,
* start tuning the link based on the false cca counter.
*/
- if (rt2x00dev->link.false_cca > 512 && r17 < 0x40) {
+ if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
rt2x00dev->link.vgc_level = r17;
- } else if (rt2x00dev->link.false_cca < 100 && r17 > 0x32) {
+ } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
rt2500pci_bbp_write(rt2x00dev, 17, --r17);
rt2x00dev->link.vgc_level = r17;
}
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 7cdc80a..8198531 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -535,7 +535,8 @@ static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev)
/*
* Link tuning
*/
-static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u16 reg;
@@ -543,14 +544,13 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev)
* Update FCS error count from register.
*/
rt2500usb_register_read(rt2x00dev, STA_CSR0, ®);
- rt2x00dev->link.rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR);
+ qual->rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR);
/*
* Update False CCA count from register.
*/
rt2500usb_register_read(rt2x00dev, STA_CSR3, ®);
- rt2x00dev->link.false_cca =
- rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
+ qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
}
static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -673,10 +673,10 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
if (r17 > up_bound) {
rt2500usb_bbp_write(rt2x00dev, 17, up_bound);
rt2x00dev->link.vgc_level = up_bound;
- } else if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+ } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
rt2500usb_bbp_write(rt2x00dev, 17, ++r17);
rt2x00dev->link.vgc_level = r17;
- } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+ } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
rt2500usb_bbp_write(rt2x00dev, 17, --r17);
rt2x00dev->link.vgc_level = r17;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 9845e58..046c95e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -180,18 +180,9 @@ struct rf_channel {
};
/*
- * To optimize the quality of the link we need to store
- * the quality of received frames and periodically
- * optimize the link.
+ * Quality statistics about the currently active link.
*/
-struct link {
- /*
- * Link tuner counter
- * The number of times the link has been tuned
- * since the radio has been switched on.
- */
- u32 count;
-
+struct link_qual {
/*
* Statistics required for Link tuning.
* For the average RSSI value we use the "Walking average" approach.
@@ -211,7 +202,6 @@ struct link {
* the new values correctly allowing a effective link tuning.
*/
int avg_rssi;
- int vgc_level;
int false_cca;
/*
@@ -240,6 +230,30 @@ struct link {
#define WEIGHT_RSSI 20
#define WEIGHT_RX 40
#define WEIGHT_TX 40
+};
+
+/*
+ * To optimize the quality of the link we need to store
+ * the quality of received frames and periodically
+ * optimize the link.
+ */
+struct link {
+ /*
+ * Link tuner counter
+ * The number of times the link has been tuned
+ * since the radio has been switched on.
+ */
+ u32 count;
+
+ /*
+ * Quality measurement values.
+ */
+ struct link_qual qual;
+
+ /*
+ * Active VGC level
+ */
+ int vgc_level;
/*
* Work structure for scheduling periodic link tuning.
@@ -249,25 +263,25 @@ struct link {
/*
* Clear all counters inside the link structure.
- * This can be easiest achieved by memsetting everything
- * except for the work structure at the end.
*/
static inline void rt2x00_clear_link(struct link *link)
{
- memset(link, 0x00, sizeof(*link) - sizeof(link->work));
- link->rx_percentage = 50;
- link->tx_percentage = 50;
+ link->count = 0;
+ memset(&link->qual, 0, sizeof(link->qual));
+ link->qual.rx_percentage = 50;
+ link->qual.tx_percentage = 50;
}
+
/*
* Update the rssi using the walking average approach.
*/
static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
{
- if (!link->avg_rssi)
- link->avg_rssi = rssi;
+ if (!link->qual.avg_rssi)
+ link->qual.avg_rssi = rssi;
else
- link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8;
+ link->qual.avg_rssi = ((link->qual.avg_rssi * 7) + rssi) / 8;
}
/*
@@ -277,7 +291,9 @@ static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
*/
static inline int rt2x00_get_link_rssi(struct link *link)
{
- return (link->avg_rssi && link->rx_success) ? link->avg_rssi : -128;
+ if (link->qual.avg_rssi && link->qual.rx_success)
+ return link->qual.avg_rssi;
+ return -128;
}
/*
@@ -402,7 +418,8 @@ struct rt2x00lib_ops {
int (*set_device_state) (struct rt2x00_dev *rt2x00dev,
enum dev_state state);
int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
- void (*link_stats) (struct rt2x00_dev *rt2x00dev);
+ void (*link_stats) (struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual);
void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index ff399f8..5d32e09 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -179,26 +179,26 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
rt2x00lib_start_link_tuner(rt2x00dev);
}
-static void rt2x00lib_precalculate_link_signal(struct link *link)
+static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
{
- if (link->rx_failed || link->rx_success)
- link->rx_percentage =
- (link->rx_success * 100) /
- (link->rx_failed + link->rx_success);
+ if (qual->rx_failed || qual->rx_success)
+ qual->rx_percentage =
+ (qual->rx_success * 100) /
+ (qual->rx_failed + qual->rx_success);
else
- link->rx_percentage = 50;
+ qual->rx_percentage = 50;
- if (link->tx_failed || link->tx_success)
- link->tx_percentage =
- (link->tx_success * 100) /
- (link->tx_failed + link->tx_success);
+ if (qual->tx_failed || qual->tx_success)
+ qual->tx_percentage =
+ (qual->tx_success * 100) /
+ (qual->tx_failed + qual->tx_success);
else
- link->tx_percentage = 50;
+ qual->tx_percentage = 50;
- link->rx_success = 0;
- link->rx_failed = 0;
- link->tx_success = 0;
- link->tx_failed = 0;
+ qual->rx_success = 0;
+ qual->rx_failed = 0;
+ qual->tx_success = 0;
+ qual->tx_failed = 0;
}
static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
@@ -225,8 +225,8 @@ static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
* defines to calculate the current link signal.
*/
signal = ((WEIGHT_RSSI * rssi_percentage) +
- (WEIGHT_TX * rt2x00dev->link.tx_percentage) +
- (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100;
+ (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) +
+ (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100;
return (signal > 100) ? 100 : signal;
}
@@ -246,10 +246,10 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
/*
* Update statistics.
*/
- rt2x00dev->ops->lib->link_stats(rt2x00dev);
+ rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
rt2x00dev->low_level_stats.dot11FCSErrorCount +=
- rt2x00dev->link.rx_failed;
+ rt2x00dev->link.qual.rx_failed;
/*
* Only perform the link tuning when Link tuning
@@ -262,7 +262,7 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
* Precalculate a portion of the link signal which is
* in based on the tx/rx success/failure counters.
*/
- rt2x00lib_precalculate_link_signal(&rt2x00dev->link);
+ rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
/*
* Increase tuner counter, and reschedule the next link tuner run.
@@ -350,8 +350,8 @@ void rt2x00lib_txdone(struct data_entry *entry,
tx_status->ack_signal = 0;
tx_status->excessive_retries = (status == TX_FAIL_RETRY);
tx_status->retry_count = retry;
- rt2x00dev->link.tx_success += success;
- rt2x00dev->link.tx_failed += retry + fail;
+ rt2x00dev->link.qual.tx_success += success;
+ rt2x00dev->link.qual.tx_failed += retry + fail;
if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) {
if (success)
@@ -413,7 +413,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
}
rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
- rt2x00dev->link.rx_success++;
+ rt2x00dev->link.qual.rx_success++;
rx_status->rate = val;
rx_status->signal =
rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 01dbef1..f6b8ae8 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -792,7 +792,8 @@ static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
/*
* Link tuning
*/
-static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u32 reg;
@@ -800,14 +801,13 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev)
* Update FCS error count from register.
*/
rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®);
- rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
+ qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
/*
* Update False CCA count from register.
*/
rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®);
- rt2x00dev->link.false_cca =
- rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
+ qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -904,11 +904,11 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+ if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
if (++r17 > up_bound)
r17 = up_bound;
rt61pci_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+ } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
if (--r17 < low_bound)
r17 = low_bound;
rt61pci_bbp_write(rt2x00dev, 17, r17);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 46c8c08..d2b25ff 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -659,7 +659,8 @@ static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
/*
* Link tuning
*/
-static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u32 reg;
@@ -667,15 +668,13 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev)
* Update FCS error count from register.
*/
rt73usb_register_read(rt2x00dev, STA_CSR0, ®);
- rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
+ qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
/*
* Update False CCA count from register.
*/
rt73usb_register_read(rt2x00dev, STA_CSR1, ®);
- reg = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
- rt2x00dev->link.false_cca =
- rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
+ qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -781,12 +780,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+ if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
r17 += 4;
if (r17 > up_bound)
r17 = up_bound;
rt73usb_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+ } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
r17 -= 4;
if (r17 < low_bound)
r17 = low_bound;
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 2/21] rt2x00: Use enum defines
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2007-10-27 11:35 ` [PATCH 1/21] rt2x00: Move quality statistics into seperate structure Ivo van Doorn
@ 2007-10-27 11:35 ` Ivo van Doorn
2007-10-27 11:36 ` [PATCH 3/21] rt2x00: Correctly translate mac80211 antenna setup to rt2x00 Ivo van Doorn
` (19 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:35 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
When setting the default EEPROM values use
the values from the enums instead of "magic" values.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2500pci.c | 9 ++++++---
drivers/net/wireless/rt2x00/rt2500usb.c | 9 ++++++---
drivers/net/wireless/rt2x00/rt61pci.c | 6 ++++--
drivers/net/wireless/rt2x00/rt73usb.c | 6 ++++--
4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 1f65e71..5ecce34 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1421,9 +1421,12 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+ ANTENNA_SW_DIVERSITY);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+ ANTENNA_SW_DIVERSITY);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE,
+ LED_MODE_DEFAULT);
rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 8198531..487d89e 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1163,9 +1163,12 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+ ANTENNA_SW_DIVERSITY);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+ ANTENNA_SW_DIVERSITY);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE,
+ LED_MODE_DEFAULT);
rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f6b8ae8..b8c3da7 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1908,8 +1908,10 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+ ANTENNA_B);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+ ANTENNA_B);
rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d2b25ff..6297677 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1391,8 +1391,10 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2);
- rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+ ANTENNA_B);
+ rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+ ANTENNA_B);
rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 3/21] rt2x00: Correctly translate mac80211 antenna setup to rt2x00
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2007-10-27 11:35 ` [PATCH 1/21] rt2x00: Move quality statistics into seperate structure Ivo van Doorn
2007-10-27 11:35 ` [PATCH 2/21] rt2x00: Use enum defines Ivo van Doorn
@ 2007-10-27 11:36 ` Ivo van Doorn
2007-10-27 11:36 ` [PATCH 4/21] rt2x00: SW diversity should default to antenna B Ivo van Doorn
` (18 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:36 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
mac80211 has 3 values for the antenna setup:
0 - default
1 - use antenna 1
2 - use antenna 2
This means that rt2x00 should store the default value
from the EEPROM somwhere and use that when mac80211 indicates
that the antenna setup is 0.
This also implies that rt2x00 should no longer write the
hw->config.antenna_sel_* values based on the EEPROM input.
This also adds the basis in rt2x00lib for correct software
diversity handling. By default rt2x00lib will now configure
antenna B instead of hardware diversity.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 25 +++++++++----
drivers/net/wireless/rt2x00/rt2500pci.c | 14 +++----
drivers/net/wireless/rt2x00/rt2500usb.c | 25 +++++++++----
drivers/net/wireless/rt2x00/rt2x00.h | 25 +++++++++++++-
drivers/net/wireless/rt2x00/rt2x00config.c | 51 ++++++++++++++++++++++++++-
drivers/net/wireless/rt2x00/rt2x00dev.c | 1 +
drivers/net/wireless/rt2x00/rt61pci.c | 32 +++++++----------
drivers/net/wireless/rt2x00/rt73usb.c | 23 +++++-------
8 files changed, 137 insertions(+), 59 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 31bbb44..2284cb3 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -397,7 +397,7 @@ static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
}
static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
- int antenna_tx, int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r1;
u8 r4;
@@ -408,7 +408,7 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
/*
* Configure the TX antenna.
*/
- switch (antenna_tx) {
+ switch (ant->tx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
@@ -424,7 +424,7 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
/*
* Configure the RX antenna.
*/
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
@@ -485,9 +485,7 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
rt2400pci_config_txpower(rt2x00dev,
libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA)
- rt2400pci_config_antenna(rt2x00dev,
- libconf->conf->antenna_sel_tx,
- libconf->conf->antenna_sel_rx);
+ rt2400pci_config_antenna(rt2x00dev, &libconf->ant);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
rt2400pci_config_duration(rt2x00dev, libconf);
}
@@ -1316,12 +1314,23 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify default antenna configuration.
*/
- rt2x00dev->hw->conf.antenna_sel_tx =
+ rt2x00dev->default_ant.tx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
- rt2x00dev->hw->conf.antenna_sel_rx =
+ rt2x00dev->default_ant.rx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
/*
+ * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead.
+ * I am not 100% sure about this, but the legacy drivers do not
+ * indicate antenna swapping in software is required when
+ * diversity is enabled.
+ */
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY;
+ if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY;
+
+ /*
* Store led mode, for correct led behaviour.
*/
rt2x00dev->led_mode =
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 5ecce34..a004cd9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -424,7 +424,7 @@ static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev,
}
static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx, const int antenna_rx)
+ struct antenna_setup *ant)
{
u32 reg;
u8 r14;
@@ -437,7 +437,7 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
/*
* Configure the TX antenna.
*/
- switch (antenna_tx) {
+ switch (ant->tx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
@@ -459,7 +459,7 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
/*
* Configure the RX antenna.
*/
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
@@ -541,9 +541,7 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
rt2500pci_config_txpower(rt2x00dev,
libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA)
- rt2500pci_config_antenna(rt2x00dev,
- libconf->conf->antenna_sel_tx,
- libconf->conf->antenna_sel_rx);
+ rt2500pci_config_antenna(rt2x00dev, &libconf->ant);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
rt2500pci_config_duration(rt2x00dev, libconf);
}
@@ -1485,9 +1483,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify default antenna configuration.
*/
- rt2x00dev->hw->conf.antenna_sel_tx =
+ rt2x00dev->default_ant.tx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
- rt2x00dev->hw->conf.antenna_sel_rx =
+ rt2x00dev->default_ant.rx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 487d89e..4b92f10 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -385,7 +385,7 @@ static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
}
static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx, const int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r2;
u8 r14;
@@ -400,7 +400,7 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
/*
* Configure the TX antenna.
*/
- switch (antenna_tx) {
+ switch (ant->tx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 1);
@@ -422,7 +422,7 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
/*
* Configure the RX antenna.
*/
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 1);
@@ -487,9 +487,7 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
rt2500usb_config_txpower(rt2x00dev,
libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA)
- rt2500usb_config_antenna(rt2x00dev,
- libconf->conf->antenna_sel_tx,
- libconf->conf->antenna_sel_rx);
+ rt2500usb_config_antenna(rt2x00dev, &libconf->ant);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
rt2500usb_config_duration(rt2x00dev, libconf);
}
@@ -1278,12 +1276,23 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify default antenna configuration.
*/
- rt2x00dev->hw->conf.antenna_sel_tx =
+ rt2x00dev->default_ant.tx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
- rt2x00dev->hw->conf.antenna_sel_rx =
+ rt2x00dev->default_ant.rx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
/*
+ * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead.
+ * I am not 100% sure about this, but the legacy drivers do not
+ * indicate antenna swapping in software is required when
+ * diversity is enabled.
+ */
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY;
+ if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY;
+
+ /*
* Store led mode, for correct led behaviour.
*/
rt2x00dev->led_mode =
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 046c95e..dcf7fd7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -180,6 +180,14 @@ struct rf_channel {
};
/*
+ * Antenna setup values.
+ */
+struct antenna_setup {
+ enum antenna rx;
+ enum antenna tx;
+};
+
+/*
* Quality statistics about the currently active link.
*/
struct link_qual {
@@ -251,6 +259,13 @@ struct link {
struct link_qual qual;
/*
+ * Currently active TX/RX antenna setup.
+ * When software diversity is used, this will indicate
+ * which antenna is actually used at this time.
+ */
+ struct antenna_setup active_ant;
+
+ /*
* Active VGC level
*/
int vgc_level;
@@ -272,7 +287,6 @@ static inline void rt2x00_clear_link(struct link *link)
link->qual.tx_percentage = 50;
}
-
/*
* Update the rssi using the walking average approach.
*/
@@ -378,6 +392,8 @@ struct rt2x00lib_conf {
struct ieee80211_conf *conf;
struct rf_channel rf;
+ struct antenna_setup ant;
+
int phymode;
int basic_rates;
@@ -583,6 +599,13 @@ struct rt2x00_dev {
struct hw_mode_spec spec;
/*
+ * This is the default TX/RX antenna setup as indicated
+ * by the device's EEPROM. When mac80211 sets its
+ * antenna value to 0 we should be using these values.
+ */
+ struct antenna_setup default_ant;
+
+ /*
* Register pointers
* csr_addr: Base register address. (PCI)
* csr_cache: CSR cache for usb_control_msg. (USB)
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 12914cf..04518b0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -100,6 +100,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf libconf;
struct ieee80211_hw_mode *mode;
struct ieee80211_rate *rate;
+ struct antenna_setup *default_ant = &rt2x00dev->default_ant;
+ struct antenna_setup *active_ant = &rt2x00dev->link.active_ant;
int flags = 0;
int short_slot_time;
@@ -122,7 +124,35 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
flags |= CONFIG_UPDATE_CHANNEL;
if (rt2x00dev->tx_power != conf->power_level)
flags |= CONFIG_UPDATE_TXPOWER;
- if (rt2x00dev->rx_status.antenna == conf->antenna_sel_rx)
+
+ /*
+ * Determining changes in the antenna setups request several checks:
+ * antenna_sel_{r,t}x = 0
+ * -> Does active_{r,t}x match default_{r,t}x
+ * -> Is default_{r,t}x SW_DIVERSITY
+ * antenna_sel_{r,t}x = 1/2
+ * -> Does active_{r,t}x match antenna_sel_{r,t}x
+ * The reason for not updating the antenna while SW diversity
+ * should be used is simple: Software diversity means that
+ * we should switch between the antenna's based on the
+ * quality. This means that the current antenna is good enough
+ * to work with untill the link tuner decides that an antenna
+ * switch should be performed.
+ */
+ if (!conf->antenna_sel_rx &&
+ default_ant->rx != ANTENNA_SW_DIVERSITY &&
+ default_ant->rx != active_ant->rx)
+ flags |= CONFIG_UPDATE_ANTENNA;
+ else if (conf->antenna_sel_rx &&
+ conf->antenna_sel_rx != active_ant->rx)
+ flags |= CONFIG_UPDATE_ANTENNA;
+
+ if (!conf->antenna_sel_tx &&
+ default_ant->tx != ANTENNA_SW_DIVERSITY &&
+ default_ant->tx != active_ant->tx)
+ flags |= CONFIG_UPDATE_ANTENNA;
+ else if (conf->antenna_sel_tx &&
+ conf->antenna_sel_tx != active_ant->tx)
flags |= CONFIG_UPDATE_ANTENNA;
/*
@@ -171,6 +201,22 @@ config:
sizeof(libconf.rf));
}
+ if (flags & CONFIG_UPDATE_ANTENNA) {
+ if (conf->antenna_sel_rx)
+ libconf.ant.rx = conf->antenna_sel_rx;
+ else if (default_ant->rx != ANTENNA_SW_DIVERSITY)
+ libconf.ant.rx = default_ant->rx;
+ else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
+ libconf.ant.rx = ANTENNA_B;
+
+ if (conf->antenna_sel_tx)
+ libconf.ant.tx = conf->antenna_sel_tx;
+ else if (default_ant->tx != ANTENNA_SW_DIVERSITY)
+ libconf.ant.tx = default_ant->tx;
+ else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
+ libconf.ant.tx = ANTENNA_B;
+ }
+
if (flags & CONFIG_UPDATE_SLOT_TIME) {
short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME;
@@ -201,5 +247,6 @@ config:
rt2x00dev->rx_status.freq = conf->freq;
rt2x00dev->rx_status.channel = conf->channel;
rt2x00dev->tx_power = conf->power_level;
- rt2x00dev->rx_status.antenna = conf->antenna_sel_rx;
+ rt2x00dev->link.active_ant.rx = libconf.ant.rx;
+ rt2x00dev->link.active_ant.tx = libconf.ant.tx;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5d32e09..b2016f4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -419,6 +419,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
rx_status->ssi = desc->rssi;
rx_status->flag = desc->flags;
+ rx_status->antenna = rt2x00dev->link.active_ant.rx;
/*
* Send frame to mac80211
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index b8c3da7..f96a77c 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -411,8 +411,7 @@ static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
}
static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx,
- const int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r3;
u8 r4;
@@ -425,7 +424,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
!rt2x00_rf(&rt2x00dev->chip, RF5225));
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
@@ -458,8 +457,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
}
static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx,
- const int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r3;
u8 r4;
@@ -474,7 +472,7 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
@@ -514,8 +512,7 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
}
static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx,
- const int antenna_rx)
+ struct antenna_setup *ant)
{
u16 eeprom;
u8 r3;
@@ -625,7 +622,7 @@ static const struct antenna_sel antenna_sel_bg[] = {
};
static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx, const int antenna_rx)
+ struct antenna_setup *ant)
{
const struct antenna_sel *sel;
unsigned int lna;
@@ -655,16 +652,14 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF5325))
- rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx);
+ rt61pci_config_antenna_5x(rt2x00dev, ant);
else if (rt2x00_rf(&rt2x00dev->chip, RF2527))
- rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx);
+ rt61pci_config_antenna_2x(rt2x00dev, ant);
else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) {
if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
- rt61pci_config_antenna_2x(rt2x00dev, antenna_tx,
- antenna_rx);
+ rt61pci_config_antenna_2x(rt2x00dev, ant);
else
- rt61pci_config_antenna_2529(rt2x00dev, antenna_tx,
- antenna_rx);
+ rt61pci_config_antenna_2529(rt2x00dev, ant);
}
}
@@ -709,8 +704,7 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA)
- rt61pci_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx,
- libconf->conf->antenna_sel_rx);
+ rt61pci_config_antenna(rt2x00dev, &libconf->ant);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
rt61pci_config_duration(rt2x00dev, libconf);
}
@@ -2017,9 +2011,9 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify default antenna configuration.
*/
- rt2x00dev->hw->conf.antenna_sel_tx =
+ rt2x00dev->default_ant.tx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
- rt2x00dev->hw->conf.antenna_sel_rx =
+ rt2x00dev->default_ant.rx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 6297677..a1d915f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -396,8 +396,7 @@ static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
}
static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx,
- const int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r3;
u8 r4;
@@ -409,7 +408,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
@@ -442,8 +441,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
}
static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx,
- const int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r3;
u8 r4;
@@ -457,7 +455,7 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
- switch (antenna_rx) {
+ switch (ant->rx) {
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
@@ -509,7 +507,7 @@ static const struct antenna_sel antenna_sel_bg[] = {
};
static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
- const int antenna_tx, const int antenna_rx)
+ struct antenna_setup *ant)
{
const struct antenna_sel *sel;
unsigned int lna;
@@ -539,10 +537,10 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
rt2x00_rf(&rt2x00dev->chip, RF5225))
- rt73usb_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx);
+ rt73usb_config_antenna_5x(rt2x00dev, ant);
else if (rt2x00_rf(&rt2x00dev->chip, RF2528) ||
rt2x00_rf(&rt2x00dev->chip, RF2527))
- rt73usb_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx);
+ rt73usb_config_antenna_2x(rt2x00dev, ant);
}
static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
@@ -586,8 +584,7 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA)
- rt73usb_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx,
- libconf->conf->antenna_sel_rx);
+ rt73usb_config_antenna(rt2x00dev, &libconf->ant);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
rt73usb_config_duration(rt2x00dev, libconf);
}
@@ -1503,9 +1500,9 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Identify default antenna configuration.
*/
- rt2x00dev->hw->conf.antenna_sel_tx =
+ rt2x00dev->default_ant.tx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
- rt2x00dev->hw->conf.antenna_sel_rx =
+ rt2x00dev->default_ant.rx =
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
/*
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 4/21] rt2x00: SW diversity should default to antenna B
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (2 preceding siblings ...)
2007-10-27 11:36 ` [PATCH 3/21] rt2x00: Correctly translate mac80211 antenna setup to rt2x00 Ivo van Doorn
@ 2007-10-27 11:36 ` Ivo van Doorn
2007-10-27 11:37 ` [PATCH 5/21] rt2x00: Remove rt2x00_clear_link Ivo van Doorn
` (17 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:36 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Although ANTENNA_SW_DIVERSITY should never be send
to the driver, we should still handle it to prevent bugs.
But instead of defaulting to ANTENNA_HW_DIVERSITY we
should default to ANTENNA_B instead.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 16 ++++++++++++++--
drivers/net/wireless/rt2x00/rt2500pci.c | 26 ++++++++++++++++----------
drivers/net/wireless/rt2x00/rt2500usb.c | 16 ++++++++++++++--
drivers/net/wireless/rt2x00/rt61pci.c | 16 ++++++++++++++--
drivers/net/wireless/rt2x00/rt73usb.c | 16 ++++++++++++++--
5 files changed, 72 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 2284cb3..5b3adba 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -409,13 +409,19 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
* Configure the TX antenna.
*/
switch (ant->tx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
break;
case ANTENNA_A:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
break;
@@ -425,13 +431,19 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
* Configure the RX antenna.
*/
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index a004cd9..b6d7462 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -438,17 +438,19 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
* Configure the TX antenna.
*/
switch (ant->tx) {
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
- rt2x00_set_field32(®, BBPCSR1_CCK, 2);
- rt2x00_set_field32(®, BBPCSR1_OFDM, 2);
- break;
case ANTENNA_A:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
rt2x00_set_field32(®, BBPCSR1_CCK, 0);
rt2x00_set_field32(®, BBPCSR1_OFDM, 0);
break;
+ case ANTENNA_HW_DIVERSITY:
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
rt2x00_set_field32(®, BBPCSR1_CCK, 2);
@@ -460,13 +462,17 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
* Configure the RX antenna.
*/
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
- break;
case ANTENNA_A:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
break;
+ case ANTENNA_HW_DIVERSITY:
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
break;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 4b92f10..02f1731 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -401,7 +401,6 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
* Configure the TX antenna.
*/
switch (ant->tx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 1);
rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 1);
@@ -412,6 +411,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0);
rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2);
@@ -423,13 +429,19 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
* Configure the RX antenna.
*/
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 1);
break;
case ANTENNA_A:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
break;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f96a77c..86fa07a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -425,7 +425,6 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
!rt2x00_rf(&rt2x00dev->chip, RF5225));
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
@@ -440,6 +439,13 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
else
rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
@@ -473,7 +479,6 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
@@ -481,6 +486,13 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index a1d915f..07224c0 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -409,7 +409,6 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
@@ -424,6 +423,13 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
else
rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
@@ -456,7 +462,6 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
switch (ant->rx) {
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
@@ -464,6 +469,13 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
+ case ANTENNA_SW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 5/21] rt2x00: Remove rt2x00_clear_link
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (3 preceding siblings ...)
2007-10-27 11:36 ` [PATCH 4/21] rt2x00: SW diversity should default to antenna B Ivo van Doorn
@ 2007-10-27 11:37 ` Ivo van Doorn
2007-10-27 11:37 ` [PATCH 6/21] rt2x00: Implement SW diversity Ivo van Doorn
` (16 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:37 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
rt2x00_clear_link() was becoming too large for statically inline,
also it was used on a single location and shouldn't really be
used anywhere else. So move the entire code into the function
rt2x00lib_start_link_tuner()
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 18 +++---------------
drivers/net/wireless/rt2x00/rt2x00dev.c | 16 +++++++++++++++-
2 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index dcf7fd7..acf6f1c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -277,25 +277,13 @@ struct link {
};
/*
- * Clear all counters inside the link structure.
- */
-static inline void rt2x00_clear_link(struct link *link)
-{
- link->count = 0;
- memset(&link->qual, 0, sizeof(link->qual));
- link->qual.rx_percentage = 50;
- link->qual.tx_percentage = 50;
-}
-
-/*
* Update the rssi using the walking average approach.
*/
static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
{
- if (!link->qual.avg_rssi)
- link->qual.avg_rssi = rssi;
- else
- link->qual.avg_rssi = ((link->qual.avg_rssi * 7) + rssi) / 8;
+ if (link->qual.avg_rssi)
+ rssi = ((link->qual.avg_rssi * 7) + rssi) / 8;
+ link->qual.avg_rssi = rssi;
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b2016f4..0f824b2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -67,7 +67,21 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring);
*/
static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt2x00_clear_link(&rt2x00dev->link);
+ rt2x00dev->link.count = 0;
+ rt2x00dev->link.vgc_level = 0;
+
+ memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
+
+ /*
+ * The RX and TX percentage should start at 50%
+ * this will assure we will get at least get some
+ * decent value when the link tuner starts.
+ * The value will be dropped and overwritten with
+ * the correct (measured )value anyway during the
+ * first run of the link tuner.
+ */
+ rt2x00dev->link.qual.rx_percentage = 50;
+ rt2x00dev->link.qual.tx_percentage = 50;
/*
* Reset the link tuner.
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 6/21] rt2x00: Implement SW diversity
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (4 preceding siblings ...)
2007-10-27 11:37 ` [PATCH 5/21] rt2x00: Remove rt2x00_clear_link Ivo van Doorn
@ 2007-10-27 11:37 ` Ivo van Doorn
2007-10-27 11:38 ` [PATCH 7/21] rt2x00: Cleanup if-statements Ivo van Doorn
` (15 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:37 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
When mac80211 indicates that the default antenna setup
should be used _and_ that this default setup is SW_DIVERSITY.
This requires sampling and storing the RSSI per antenna
and check once every 2 seconds to determine if the RSSI
has changed significantly. Once this is the case we should sample
the other antenna for a short period and evaluate if
we need to swap antenna or not.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 87 ++++++++++++++---
drivers/net/wireless/rt2x00/rt2x00config.c | 26 +++++-
drivers/net/wireless/rt2x00/rt2x00dev.c | 138 +++++++++++++++++++++++++++-
drivers/net/wireless/rt2x00/rt2x00lib.h | 2 +
4 files changed, 232 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index acf6f1c..c9df8f1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -241,6 +241,43 @@ struct link_qual {
};
/*
+ * Antenna settings about the currently active link.
+ */
+struct link_ant {
+ /*
+ * Antenna flags
+ */
+ unsigned int flags;
+#define ANTENNA_RX_DIVERSITY 0x00000001
+#define ANTENNA_TX_DIVERSITY 0x00000002
+#define ANTENNA_MODE_SAMPLE 0x00000004
+
+ /*
+ * Currently active TX/RX antenna setup.
+ * When software diversity is used, this will indicate
+ * which antenna is actually used at this time.
+ */
+ struct antenna_setup active;
+
+ /*
+ * RSSI information for the different antenna's.
+ * These statistics are used to determine when
+ * to switch antenna when using software diversity.
+ *
+ * rssi[0] -> Antenna A RSSI
+ * rssi[1] -> Antenna B RSSI
+ */
+ int rssi_history[2];
+
+ /*
+ * Current RSSI average of the currently active antenna.
+ * Similar to the avg_rssi in the link_qual structure
+ * this value is updated by using the walking average.
+ */
+ int rssi_ant;
+};
+
+/*
* To optimize the quality of the link we need to store
* the quality of received frames and periodically
* optimize the link.
@@ -259,11 +296,9 @@ struct link {
struct link_qual qual;
/*
- * Currently active TX/RX antenna setup.
- * When software diversity is used, this will indicate
- * which antenna is actually used at this time.
+ * TX/RX antenna setup.
*/
- struct antenna_setup active_ant;
+ struct link_ant ant;
/*
* Active VGC level
@@ -277,25 +312,47 @@ struct link {
};
/*
- * Update the rssi using the walking average approach.
+ * Small helper macro to work with moving/walking averages.
*/
-static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
-{
- if (link->qual.avg_rssi)
- rssi = ((link->qual.avg_rssi * 7) + rssi) / 8;
- link->qual.avg_rssi = rssi;
-}
+#define MOVING_AVERAGE(__avg, __val, __samples) \
+ ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
+
+/*
+ * When we lack RSSI information return something less then -80 to
+ * tell the driver to tune the device to maximum sensitivity.
+ */
+#define DEFAULT_RSSI ( -128 )
/*
- * When the avg_rssi is unset or no frames have been received),
- * we need to return the default value which needs to be less
- * than -80 so the device will select the maximum sensitivity.
+ * Link quality access functions.
*/
static inline int rt2x00_get_link_rssi(struct link *link)
{
if (link->qual.avg_rssi && link->qual.rx_success)
return link->qual.avg_rssi;
- return -128;
+ return DEFAULT_RSSI;
+}
+
+static inline int rt2x00_get_link_ant_rssi(struct link *link)
+{
+ if (link->ant.rssi_ant && link->qual.rx_success)
+ return link->ant.rssi_ant;
+ return DEFAULT_RSSI;
+}
+
+static inline int rt2x00_get_link_ant_rssi_history(struct link *link,
+ enum antenna ant)
+{
+ if (link->ant.rssi_history[ant - ANTENNA_A])
+ return link->ant.rssi_history[ant - ANTENNA_A];
+ return DEFAULT_RSSI;
+}
+
+static inline int rt2x00_update_ant_rssi(struct link *link, int rssi)
+{
+ int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A];
+ link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi;
+ return old_rssi;
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 04518b0..2b0edd2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -94,6 +94,26 @@ void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type)
rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync);
}
+void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
+ enum antenna rx, enum antenna tx)
+{
+ struct rt2x00lib_conf libconf;
+
+ libconf.ant.rx = rx;
+ libconf.ant.tx = tx;
+
+ /*
+ * Write new antenna setup to device and reset the link tuner.
+ * The latter is required since we need to recalibrate the
+ * noise-sensitivity ratio for the new setup.
+ */
+ rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf);
+ rt2x00lib_reset_link_tuner(rt2x00dev);
+
+ rt2x00dev->link.ant.active.rx = libconf.ant.rx;
+ rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+}
+
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config)
{
@@ -101,7 +121,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_hw_mode *mode;
struct ieee80211_rate *rate;
struct antenna_setup *default_ant = &rt2x00dev->default_ant;
- struct antenna_setup *active_ant = &rt2x00dev->link.active_ant;
+ struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
int flags = 0;
int short_slot_time;
@@ -247,6 +267,6 @@ config:
rt2x00dev->rx_status.freq = conf->freq;
rt2x00dev->rx_status.channel = conf->channel;
rt2x00dev->tx_power = conf->power_level;
- rt2x00dev->link.active_ant.rx = libconf.ant.rx;
- rt2x00dev->link.active_ant.tx = libconf.ant.tx;
+ rt2x00dev->link.ant.active.rx = libconf.ant.rx;
+ rt2x00dev->link.ant.active.tx = libconf.ant.tx;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 0f824b2..360f03a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -193,6 +193,133 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
rt2x00lib_start_link_tuner(rt2x00dev);
}
+static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
+{
+ enum antenna rx = rt2x00dev->link.ant.active.rx;
+ enum antenna tx = rt2x00dev->link.ant.active.tx;
+ int sample_a =
+ rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
+ int sample_b =
+ rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
+
+ /*
+ * We are done sampling. Now we should evaluate the results.
+ */
+ rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
+
+ /*
+ * During the last period we have sampled the RSSI
+ * from both antenna's. It now is time to determine
+ * which antenna demonstrated the best performance.
+ * When we are already on the antenna with the best
+ * performance, then there really is nothing for us
+ * left to do.
+ */
+ if (sample_a == sample_b)
+ return;
+
+ if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) {
+ if (sample_a > sample_b && rx == ANTENNA_B)
+ rx = ANTENNA_A;
+ else if (rx == ANTENNA_A)
+ rx = ANTENNA_B;
+ }
+
+ if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) {
+ if (sample_a > sample_b && tx == ANTENNA_B)
+ tx = ANTENNA_A;
+ else if (tx == ANTENNA_A)
+ tx = ANTENNA_B;
+ }
+
+ rt2x00lib_config_antenna(rt2x00dev, rx, tx);
+}
+
+static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
+{
+ enum antenna rx = rt2x00dev->link.ant.active.rx;
+ enum antenna tx = rt2x00dev->link.ant.active.tx;
+ int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
+ int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
+
+ /*
+ * Legacy driver indicates that we should swap antenna's
+ * when the difference in RSSI is greater that 5. This
+ * also should be done when the RSSI was actually better
+ * then the previous sample.
+ * When the difference exceeds the threshold we should
+ * sample the rssi from the other antenna to make a valid
+ * comparison between the 2 antennas.
+ */
+ if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5)
+ return;
+
+ rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
+
+ if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
+ rx = (rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+ if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
+ tx = (tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+ rt2x00lib_config_antenna(rt2x00dev, rx, tx);
+}
+
+static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
+{
+ /*
+ * Determine if software diversity is enabled for
+ * either the TX or RX antenna (or both).
+ * Always perform this check since within the link
+ * tuner interval the configuration might have changed.
+ */
+ rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
+ rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
+
+ if (rt2x00dev->hw->conf.antenna_sel_rx == 0 &&
+ rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY)
+ rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
+ if (rt2x00dev->hw->conf.antenna_sel_tx == 0 &&
+ rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY)
+ rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
+
+ if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
+ !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
+ rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
+ return;
+ }
+
+ /*
+ * If we have only sampled the data over the last period
+ * we should now harvest the data. Otherwise just evaluate
+ * the data. The latter should only be performed once
+ * every 2 seconds.
+ */
+ if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE)
+ rt2x00lib_evaluate_antenna_sample(rt2x00dev);
+ else if (rt2x00dev->link.count & 1)
+ rt2x00lib_evaluate_antenna_eval(rt2x00dev);
+}
+
+static void rt2x00lib_update_link_stats(struct link *link, int rssi)
+{
+ int avg_rssi = rssi;
+
+ /*
+ * Update global RSSI
+ */
+ if (link->qual.avg_rssi)
+ avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8);
+ link->qual.avg_rssi = avg_rssi;
+
+ /*
+ * Update antenna RSSI
+ */
+ if (link->ant.rssi_ant)
+ rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8);
+ link->ant.rssi_ant = rssi;
+}
+
static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
{
if (qual->rx_failed || qual->rx_success)
@@ -261,7 +388,6 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
* Update statistics.
*/
rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
-
rt2x00dev->low_level_stats.dot11FCSErrorCount +=
rt2x00dev->link.qual.rx_failed;
@@ -273,6 +399,11 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
rt2x00dev->ops->lib->link_tuner(rt2x00dev);
/*
+ * Evaluate antenna setup.
+ */
+ rt2x00lib_evaluate_antenna(rt2x00dev);
+
+ /*
* Precalculate a portion of the link signal which is
* in based on the tx/rx success/failure counters.
*/
@@ -426,14 +557,15 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
}
}
- rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
+ rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi);
rt2x00dev->link.qual.rx_success++;
+
rx_status->rate = val;
rx_status->signal =
rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
rx_status->ssi = desc->rssi;
rx_status->flag = desc->flags;
- rx_status->antenna = rt2x00dev->link.active_ant.rx;
+ rx_status->antenna = rt2x00dev->link.ant.active.rx;
/*
* Send frame to mac80211
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 06d9bc0..7319411 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -53,6 +53,8 @@ void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac);
void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid);
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type);
+void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
+ enum antenna rx, enum antenna tx);
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 7/21] rt2x00: Cleanup if-statements
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (5 preceding siblings ...)
2007-10-27 11:37 ` [PATCH 6/21] rt2x00: Implement SW diversity Ivo van Doorn
@ 2007-10-27 11:38 ` Ivo van Doorn
2007-10-27 11:38 ` [PATCH 8/21] rt2x00: Fix antenna selection Ivo van Doorn
` (14 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:38 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Cleanup if-statements for simple 1/0 register field values.
This also fixes a endian bug in rt2500usb when working
with the PHY_CSR2 initialization. As well as a bug
in the enabling of the LED in rt73usb.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 28 ++++++-----------
drivers/net/wireless/rt2x00/rt2500pci.c | 28 ++++++-----------
drivers/net/wireless/rt2x00/rt2500usb.c | 22 +++++--------
drivers/net/wireless/rt2x00/rt2500usb.h | 13 +++++++-
drivers/net/wireless/rt2x00/rt2x00.h | 12 ++++----
drivers/net/wireless/rt2x00/rt61pci.c | 50 +++++++++++++++----------------
drivers/net/wireless/rt2x00/rt73usb.c | 28 ++++++++---------
7 files changed, 83 insertions(+), 98 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 5b3adba..fc16212 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -524,18 +524,10 @@ static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70);
rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30);
-
- if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) {
- rt2x00_set_field32(®, LEDCSR_LINK, 1);
- rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0);
- } else if (rt2x00dev->led_mode == LED_MODE_ASUS) {
- rt2x00_set_field32(®, LEDCSR_LINK, 0);
- rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1);
- } else {
- rt2x00_set_field32(®, LEDCSR_LINK, 1);
- rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1);
- }
-
+ rt2x00_set_field32(®, LEDCSR_LINK,
+ (rt2x00dev->led_mode != LED_MODE_ASUS));
+ rt2x00_set_field32(®, LEDCSR_ACTIVITY,
+ (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
}
@@ -1110,12 +1102,12 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
- if (queue == IEEE80211_TX_QUEUE_DATA0)
- rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1);
- else if (queue == IEEE80211_TX_QUEUE_DATA1)
- rt2x00_set_field32(®, TXCSR0_KICK_TX, 1);
- else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
- rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1);
+ rt2x00_set_field32(®, TXCSR0_KICK_PRIO,
+ (queue == IEEE80211_TX_QUEUE_DATA0));
+ rt2x00_set_field32(®, TXCSR0_KICK_TX,
+ (queue == IEEE80211_TX_QUEUE_DATA1));
+ rt2x00_set_field32(®, TXCSR0_KICK_ATIM,
+ (queue == IEEE80211_TX_QUEUE_AFTER_BEACON));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index b6d7462..c59ca0a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -563,18 +563,10 @@ static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70);
rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30);
-
- if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) {
- rt2x00_set_field32(®, LEDCSR_LINK, 1);
- rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0);
- } else if (rt2x00dev->led_mode == LED_MODE_ASUS) {
- rt2x00_set_field32(®, LEDCSR_LINK, 0);
- rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1);
- } else {
- rt2x00_set_field32(®, LEDCSR_LINK, 1);
- rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1);
- }
-
+ rt2x00_set_field32(®, LEDCSR_LINK,
+ (rt2x00dev->led_mode != LED_MODE_ASUS));
+ rt2x00_set_field32(®, LEDCSR_ACTIVITY,
+ (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
}
@@ -1244,12 +1236,12 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
- if (queue == IEEE80211_TX_QUEUE_DATA0)
- rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1);
- else if (queue == IEEE80211_TX_QUEUE_DATA1)
- rt2x00_set_field32(®, TXCSR0_KICK_TX, 1);
- else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
- rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1);
+ rt2x00_set_field32(®, TXCSR0_KICK_PRIO,
+ (queue == IEEE80211_TX_QUEUE_DATA0));
+ rt2x00_set_field32(®, TXCSR0_KICK_TX,
+ (queue == IEEE80211_TX_QUEUE_DATA1));
+ rt2x00_set_field32(®, TXCSR0_KICK_ATIM,
+ (queue == IEEE80211_TX_QUEUE_AFTER_BEACON));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 02f1731..6c2e275 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -517,18 +517,10 @@ static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev)
rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);
rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®);
-
- if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) {
- rt2x00_set_field16(®, MAC_CSR20_LINK, 1);
- rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0);
- } else if (rt2x00dev->led_mode == LED_MODE_ASUS) {
- rt2x00_set_field16(®, MAC_CSR20_LINK, 0);
- rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 1);
- } else {
- rt2x00_set_field16(®, MAC_CSR20_LINK, 1);
- rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 1);
- }
-
+ rt2x00_set_field16(®, MAC_CSR20_LINK,
+ (rt2x00dev->led_mode != LED_MODE_ASUS));
+ rt2x00_set_field16(®, MAC_CSR20_ACTIVITY,
+ (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg);
}
@@ -765,9 +757,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
if (rt2x00_get_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
rt2500usb_register_read(rt2x00dev, PHY_CSR2, ®);
- reg &= ~0x0002;
+ rt2x00_set_field16(®, PHY_CSR2_LNA, 0);
} else {
- reg = 0x3002;
+ reg = 0;
+ rt2x00_set_field16(®, PHY_CSR2_LNA, 1);
+ rt2x00_set_field16(®, PHY_CSR2_LNA_MODE, 3);
}
rt2500usb_register_write(rt2x00dev, PHY_CSR2, reg);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index b18d56e..2741840 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -430,10 +430,21 @@
/*
* MAC configuration registers.
+ */
+
+/*
* PHY_CSR2: TX MAC configuration.
- * PHY_CSR3: RX MAC configuration.
+ * NOTE: Both register fields are complete dummy,
+ * documentation and legacy drivers are unclear un
+ * what this register means or what fields exists.
*/
#define PHY_CSR2 0x04c4
+#define PHY_CSR2_LNA FIELD16(0x0002)
+#define PHY_CSR2_LNA_MODE FIELD16(0x3000)
+
+/*
+ * PHY_CSR3: RX MAC configuration.
+ */
#define PHY_CSR3 0x04c6
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c9df8f1..e3fbcb8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -133,20 +133,20 @@
*/
static inline int is_rts_frame(u16 fc)
{
- return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS));
+ return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
+ ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS));
}
static inline int is_cts_frame(u16 fc)
{
- return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS));
+ return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
+ ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS));
}
static inline int is_probe_resp(u16 fc)
{
- return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP));
+ return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
+ ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP));
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 86fa07a..0830000 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -428,7 +428,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
- !!(rt2x00dev->curr_hwmode != HWMODE_A));
+ (rt2x00dev->curr_hwmode != HWMODE_A));
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
@@ -646,17 +646,17 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->curr_hwmode == HWMODE_A) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0);
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1);
} else {
sel = antenna_sel_bg;
lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
-
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1);
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0);
}
+ rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
+ (rt2x00dev->curr_hwmode == HWMODE_B ||
+ rt2x00dev->curr_hwmode == HWMODE_G));
+ rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
+ (rt2x00dev->curr_hwmode == HWMODE_A));
+
for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
@@ -727,7 +727,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- u16 led_reg;
u8 arg0;
u8 arg1;
@@ -736,15 +735,14 @@ static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30);
rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg);
- led_reg = rt2x00dev->led_reg;
- rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 1);
- if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)
- rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 1);
- else
- rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 1);
+ rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
+ rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
+ (rt2x00dev->rx_status.phymode == MODE_IEEE80211A));
+ rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
+ (rt2x00dev->rx_status.phymode != MODE_IEEE80211A));
- arg0 = led_reg & 0xff;
- arg1 = (led_reg >> 8) & 0xff;
+ arg0 = rt2x00dev->led_reg & 0xff;
+ arg1 = (rt2x00dev->led_reg >> 8) & 0xff;
rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1);
}
@@ -1655,16 +1653,16 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
- if (queue == IEEE80211_TX_QUEUE_DATA0)
- rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1);
- else if (queue == IEEE80211_TX_QUEUE_DATA1)
- rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1);
- else if (queue == IEEE80211_TX_QUEUE_DATA2)
- rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1);
- else if (queue == IEEE80211_TX_QUEUE_DATA3)
- rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1);
- else if (queue == IEEE80211_TX_QUEUE_DATA4)
- rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, 1);
+ rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0,
+ (queue == IEEE80211_TX_QUEUE_DATA0));
+ rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1,
+ (queue == IEEE80211_TX_QUEUE_DATA1));
+ rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2,
+ (queue == IEEE80211_TX_QUEUE_DATA2));
+ rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3,
+ (queue == IEEE80211_TX_QUEUE_DATA3));
+ rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT,
+ (queue == IEEE80211_TX_QUEUE_DATA4));
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 07224c0..048f9f4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -200,8 +200,8 @@ rf_write:
* all others contain 20 bits.
*/
rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS,
- 20 + !!(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
- rt2x00_rf(&rt2x00dev->chip, RF2527)));
+ 20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2527)));
rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0);
rt2x00_set_field32(®, PHY_CSR4_BUSY, 1);
@@ -412,7 +412,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
- !!(rt2x00dev->curr_hwmode != HWMODE_A));
+ (rt2x00dev->curr_hwmode != HWMODE_A));
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
@@ -531,17 +531,17 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->curr_hwmode == HWMODE_A) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0);
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1);
} else {
sel = antenna_sel_bg;
lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
-
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1);
- rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0);
}
+ rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
+ (rt2x00dev->curr_hwmode == HWMODE_B ||
+ rt2x00dev->curr_hwmode == HWMODE_G));
+ rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
+ (rt2x00dev->curr_hwmode == HWMODE_A));
+
for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
@@ -614,12 +614,10 @@ static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev)
rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
- if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)
- rt2x00_set_field16(&rt2x00dev->led_reg,
- MCU_LEDCS_LINK_A_STATUS, 1);
- else
- rt2x00_set_field16(&rt2x00dev->led_reg,
- MCU_LEDCS_LINK_BG_STATUS, 1);
+ rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
+ (rt2x00dev->rx_status.phymode == MODE_IEEE80211A));
+ rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
+ (rt2x00dev->rx_status.phymode != MODE_IEEE80211A));
rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
rt2x00dev->led_reg, REGISTER_TIMEOUT);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 8/21] rt2x00: Fix antenna selection.
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (6 preceding siblings ...)
2007-10-27 11:38 ` [PATCH 7/21] rt2x00: Cleanup if-statements Ivo van Doorn
@ 2007-10-27 11:38 ` Ivo van Doorn
2007-10-27 11:39 ` [PATCH 9/21] rt2x00: Release rt2x00 2.0.11 Ivo van Doorn
` (13 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:38 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
From: Mattias Nissler <mattias.nissler@gmx.de>
In the config() handler, make sure that we do configure an antenna if the
current active antenna is uninitialized. Furthermore, don't overwrite the
active antenna with bogus values if we didn't touch the antenna setup.
Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00config.c | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 2b0edd2..b4fad74 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -166,6 +166,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
else if (conf->antenna_sel_rx &&
conf->antenna_sel_rx != active_ant->rx)
flags |= CONFIG_UPDATE_ANTENNA;
+ else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
+ flags |= CONFIG_UPDATE_ANTENNA;
if (!conf->antenna_sel_tx &&
default_ant->tx != ANTENNA_SW_DIVERSITY &&
@@ -174,6 +176,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
else if (conf->antenna_sel_tx &&
conf->antenna_sel_tx != active_ant->tx)
flags |= CONFIG_UPDATE_ANTENNA;
+ else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
+ flags |= CONFIG_UPDATE_ANTENNA;
/*
* The following configuration options are never
@@ -262,11 +266,17 @@ config:
if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA))
rt2x00lib_reset_link_tuner(rt2x00dev);
- rt2x00dev->curr_hwmode = libconf.phymode;
- rt2x00dev->rx_status.phymode = conf->phymode;
+ if (flags & CONFIG_UPDATE_PHYMODE) {
+ rt2x00dev->curr_hwmode = libconf.phymode;
+ rt2x00dev->rx_status.phymode = conf->phymode;
+ }
+
rt2x00dev->rx_status.freq = conf->freq;
rt2x00dev->rx_status.channel = conf->channel;
rt2x00dev->tx_power = conf->power_level;
- rt2x00dev->link.ant.active.rx = libconf.ant.rx;
- rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+
+ if (flags & CONFIG_UPDATE_ANTENNA) {
+ rt2x00dev->link.ant.active.rx = libconf.ant.rx;
+ rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+ }
}
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 9/21] rt2x00: Release rt2x00 2.0.11
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (7 preceding siblings ...)
2007-10-27 11:38 ` [PATCH 8/21] rt2x00: Fix antenna selection Ivo van Doorn
@ 2007-10-27 11:39 ` Ivo van Doorn
2007-10-27 11:39 ` [PATCH 10/21] rt2x00: Disable RX when switching antenna Ivo van Doorn
` (12 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:39 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Version bump.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e3fbcb8..e488d9b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -42,7 +42,7 @@
* Module information.
* DRV_NAME should be set within the individual module source files.
*/
-#define DRV_VERSION "2.0.10"
+#define DRV_VERSION "2.0.11"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 10/21] rt2x00: Disable RX when switching antenna
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (8 preceding siblings ...)
2007-10-27 11:39 ` [PATCH 9/21] rt2x00: Release rt2x00 2.0.11 Ivo van Doorn
@ 2007-10-27 11:39 ` Ivo van Doorn
2007-10-27 11:39 ` [PATCH 11/21] rt2x00: Split rt61/rt73 antenna selection into RX and TX antenna Ivo van Doorn
` (11 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:39 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Antenna switching will be ignored when RX is enabled
during the switch. Make sure we disable the RX during
the switch and don't forget to reenable it later.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00config.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index b4fad74..9f0733b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -103,6 +103,13 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
libconf.ant.tx = tx;
/*
+ * Antenna setup changes require the RX to be disabled,
+ * else the changes will be ignored by the device.
+ */
+ if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+
+ /*
* Write new antenna setup to device and reset the link tuner.
* The latter is required since we need to recalibrate the
* noise-sensitivity ratio for the new setup.
@@ -112,6 +119,9 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00dev->link.ant.active.rx = libconf.ant.rx;
rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+
+ if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 11/21] rt2x00: Split rt61/rt73 antenna selection into RX and TX antenna
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (9 preceding siblings ...)
2007-10-27 11:39 ` [PATCH 10/21] rt2x00: Disable RX when switching antenna Ivo van Doorn
@ 2007-10-27 11:39 ` Ivo van Doorn
2007-10-27 11:40 ` [PATCH 12/21] rt2x00: Input-polldev requires input device Ivo van Doorn
` (10 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:39 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Based on investigation of the legacy drivers, I have made the
following assumptions of the antenna setup:
- R77 is the TX antenna configuration
- RF2529 fetches default antenna selection from NIC eeprom word
With these assumptions we can change the antenna configuration
to correctly read both antenna setup values and correctly
configure the antenna. And we can now also configure the antenna
for RF2529 without a double antenna.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt61pci.c | 215 +++++++++++++++++++++-----------
drivers/net/wireless/rt2x00/rt61pci.h | 2 +-
drivers/net/wireless/rt2x00/rt73usb.c | 58 +++++++--
drivers/net/wireless/rt2x00/rt73usb.h | 2 +-
4 files changed, 189 insertions(+), 88 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0830000..7f0665e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -424,6 +424,29 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
!rt2x00_rf(&rt2x00dev->chip, RF5225));
+ /*
+ * Configure the TX antenna.
+ */
+ switch (ant->tx) {
+ case ANTENNA_A:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
+ break;
+ case ANTENNA_SW_DIVERSITY:
+ case ANTENNA_HW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
+ case ANTENNA_B:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
+ break;
+ }
+
+ /*
+ * Configure the RX antenna.
+ */
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
@@ -433,11 +456,6 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
- if (rt2x00dev->curr_hwmode == HWMODE_A)
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
- else
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -449,11 +467,6 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
- if (rt2x00dev->curr_hwmode == HWMODE_A)
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
- else
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
break;
}
@@ -478,13 +491,35 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
+ /*
+ * Configure the TX antenna.
+ */
+ switch (ant->tx) {
+ case ANTENNA_A:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
+ break;
+ case ANTENNA_SW_DIVERSITY:
+ case ANTENNA_HW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
+ case ANTENNA_B:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
+ break;
+ }
+
+ /*
+ * Configure the RX antenna.
+ */
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -495,7 +530,6 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
*/
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
break;
}
@@ -530,74 +564,75 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
u8 r3;
u8 r4;
u8 r77;
+ u8 rx_ant;
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt61pci_bbp_read(rt2x00dev, 4, &r4);
rt61pci_bbp_read(rt2x00dev, 77, &r77);
+
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+ rx_ant = !!(rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) & 2);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
- rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1);
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
- } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) {
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) {
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
- rt61pci_bbp_write(rt2x00dev, 77, r77);
- }
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
- } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
- rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+ /*
+ * Configure the TX antenna.
+ */
+ switch (ant->tx) {
+ case ANTENNA_A:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
+ break;
+ case ANTENNA_SW_DIVERSITY:
+ case ANTENNA_HW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
+ case ANTENNA_B:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
+ break;
+ }
- switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
- case 0:
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
- break;
- case 1:
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
- break;
- case 2:
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
- break;
- case 3:
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
- break;
- }
- } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
- !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
+ /*
+ * Configure the RX antenna.
+ */
+ switch (ant->rx) {
+ case ANTENNA_A:
+ rt61pci_config_antenna_2529_rx(rt2x00dev, 0, rx_ant);
+ break;
+ case ANTENNA_SW_DIVERSITY:
+ case ANTENNA_HW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
+ case ANTENNA_B:
+ rt61pci_config_antenna_2529_rx(rt2x00dev, 1, rx_ant);
+ break;
+ }
+
+ /*
+ * FIXME: We are using the default antenna setup to
+ * determine the remaining settings. This because we
+ * need to know what the EEPROM indicated.
+ * It is however unclear if this is required, and overall
+ * using the default antenna settings here is incorrect
+ * since mac80211 might have told us to use fixed settings.
+ */
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+ else
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
- switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
- case 0:
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
- rt61pci_bbp_write(rt2x00dev, 77, r77);
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
- break;
- case 1:
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
- rt61pci_bbp_write(rt2x00dev, 77, r77);
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
- break;
- case 2:
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
- rt61pci_bbp_write(rt2x00dev, 77, r77);
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
- break;
- case 3:
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
- rt61pci_bbp_write(rt2x00dev, 77, r77);
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
- break;
- }
- }
+ rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
+ (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) &&
+ (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY));
+ rt61pci_bbp_write(rt2x00dev, 77, r77);
rt61pci_bbp_write(rt2x00dev, 3, r3);
rt61pci_bbp_write(rt2x00dev, 4, r4);
}
@@ -2019,6 +2054,12 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
}
/*
+ * Determine number of antenna's.
+ */
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
+ __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
+
+ /*
* Identify default antenna configuration.
*/
rt2x00dev->default_ant.tx =
@@ -2033,12 +2074,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
/*
- * Determine number of antenna's.
- */
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
- __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
-
- /*
* Detect if this device has an hardware controlled radio.
*/
#ifdef CONFIG_RT61PCI_RFKILL
@@ -2066,6 +2101,38 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
/*
+ * When working with a RF2529 chip without double antenna
+ * the antenna settings should be gathered from the NIC
+ * eeprom word.
+ */
+ if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
+ !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
+ switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
+ case 0:
+ rt2x00dev->default_ant.tx = ANTENNA_B;
+ rt2x00dev->default_ant.rx = ANTENNA_A;
+ break;
+ case 1:
+ rt2x00dev->default_ant.tx = ANTENNA_B;
+ rt2x00dev->default_ant.rx = ANTENNA_B;
+ break;
+ case 2:
+ rt2x00dev->default_ant.tx = ANTENNA_A;
+ rt2x00dev->default_ant.rx = ANTENNA_A;
+ break;
+ case 3:
+ rt2x00dev->default_ant.tx = ANTENNA_A;
+ rt2x00dev->default_ant.rx = ANTENNA_B;
+ break;
+ }
+
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY))
+ rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY;
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY))
+ rt2x00dev->default_ant.rx = ANTENNA_SW_DIVERSITY;
+ }
+
+ /*
* Store led settings, for correct led behaviour.
* If the eeprom value is invalid,
* switch to default led mode.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6721d7d..ba51016 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1083,7 +1083,7 @@ struct hw_pairwise_ta_entry {
/*
* R77
*/
-#define BBP_R77_PAIR FIELD8(0x03)
+#define BBP_R77_TX_ANTENNA FIELD8(0x03)
/*
* RF registers
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 048f9f4..d1119e3 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -408,6 +408,29 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
+ /*
+ * Configure the TX antenna.
+ */
+ switch (ant->tx) {
+ case ANTENNA_A:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
+ break;
+ case ANTENNA_SW_DIVERSITY:
+ case ANTENNA_HW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
+ case ANTENNA_B:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
+ break;
+ }
+
+ /*
+ * Configure the RX antenna.
+ */
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
@@ -417,11 +440,6 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
- if (rt2x00dev->curr_hwmode == HWMODE_A)
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
- else
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -433,11 +451,6 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
- if (rt2x00dev->curr_hwmode == HWMODE_A)
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
- else
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
break;
}
@@ -461,13 +474,35 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
+ /*
+ * Configure the TX antenna.
+ */
+ switch (ant->tx) {
+ case ANTENNA_A:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
+ break;
+ case ANTENNA_SW_DIVERSITY:
+ case ANTENNA_HW_DIVERSITY:
+ /*
+ * NOTE: We should never come here because rt2x00lib is
+ * supposed to catch this and send us the correct antenna
+ * explicitely. However we are nog going to bug about this.
+ * Instead, just default to antenna B.
+ */
+ case ANTENNA_B:
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
+ break;
+ }
+
+ /*
+ * Configure the RX antenna.
+ */
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -478,7 +513,6 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
*/
case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
break;
}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index f095151..13f479c 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -719,7 +719,7 @@ struct hw_pairwise_ta_entry {
/*
* R77
*/
-#define BBP_R77_PAIR FIELD8(0x03)
+#define BBP_R77_TX_ANTENNA FIELD8(0x03)
/*
* RF registers
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 12/21] rt2x00: Input-polldev requires input device
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (10 preceding siblings ...)
2007-10-27 11:39 ` [PATCH 11/21] rt2x00: Split rt61/rt73 antenna selection into RX and TX antenna Ivo van Doorn
@ 2007-10-27 11:40 ` Ivo van Doorn
2007-10-27 11:40 ` [PATCH 13/21] rt2x00: Detect initial rfkill state on register Ivo van Doorn
` (9 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:40 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
input-polldev requires a correctly allocated
and initialized input device to be set for the
input_polled_dev->input field.
Failure to do that will prevent correct polling
of the device.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00rfkill.c | 35 ++++++++++++++++++++++++---
1 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index a0f8b8e..db513f1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -68,8 +68,10 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
struct rt2x00_dev *rt2x00dev = poll_dev->private;
int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
- if (rt2x00dev->rfkill->state != state)
+ if (rt2x00dev->rfkill->state != state) {
input_report_key(poll_dev->input, KEY_WLAN, 1);
+ input_report_key(poll_dev->input, KEY_WLAN, 0);
+ }
}
int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -114,7 +116,7 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!rt2x00dev->rfkill) {
ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
- return -ENOMEM;
+ goto exit;
}
rt2x00dev->rfkill->name = rt2x00dev->ops->name;
@@ -125,15 +127,39 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev->poll_dev = input_allocate_polled_device();
if (!rt2x00dev->poll_dev) {
ERROR(rt2x00dev, "Failed to allocate polled device.\n");
- rfkill_free(rt2x00dev->rfkill);
- return -ENOMEM;
+ goto exit_free_rfkill;
}
rt2x00dev->poll_dev->private = rt2x00dev;
rt2x00dev->poll_dev->poll = rt2x00rfkill_poll;
rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
+ rt2x00dev->poll_dev->input = input_allocate_device();
+ if (!rt2x00dev->poll_dev->input) {
+ ERROR(rt2x00dev, "Failed to allocate input device.\n");
+ goto exit_free_polldev;
+ }
+
+ rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name;
+ rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+ rt2x00dev->poll_dev->input->id.bustype = BUS_HOST;
+ rt2x00dev->poll_dev->input->id.vendor = 0x1814;
+ rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt;
+ rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev;
+ rt2x00dev->poll_dev->input->dev.parent = device;
+ rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit);
+
return 0;
+
+exit_free_polldev:
+ input_free_polled_device(rt2x00dev->poll_dev);
+
+exit_free_rfkill:
+ rfkill_free(rt2x00dev->rfkill);
+
+exit:
+ return -ENOMEM;
}
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
@@ -141,6 +167,7 @@ void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
+ input_free_device(rt2x00dev->poll_dev->input);
input_free_polled_device(rt2x00dev->poll_dev);
rfkill_free(rt2x00dev->rfkill);
}
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 13/21] rt2x00: Detect initial rfkill state on register
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (11 preceding siblings ...)
2007-10-27 11:40 ` [PATCH 12/21] rt2x00: Input-polldev requires input device Ivo van Doorn
@ 2007-10-27 11:40 ` Ivo van Doorn
2007-10-27 11:41 ` [PATCH 14/21] rt2x00: Unconstify rt2x00dev Ivo van Doorn
` (8 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:40 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
When registering rfkill, make sure a initial
poll event is directly executed to detect the initial
rfkill state and send the event to the rfkill layer.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00rfkill.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index db513f1..16d365d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -94,6 +94,13 @@ int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
return retval;
}
+ /*
+ * Force initial poll which will detect the initial device state,
+ * and correctly sends the signal to the rfkill layer about this
+ * state.
+ */
+ rt2x00rfkill_poll(rt2x00dev->poll_dev);
+
return 0;
}
@@ -121,7 +128,7 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev->rfkill->name = rt2x00dev->ops->name;
rt2x00dev->rfkill->data = rt2x00dev;
- rt2x00dev->rfkill->state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+ rt2x00dev->rfkill->state = -1;
rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
rt2x00dev->poll_dev = input_allocate_polled_device();
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 14/21] rt2x00: Unconstify rt2x00dev
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (12 preceding siblings ...)
2007-10-27 11:40 ` [PATCH 13/21] rt2x00: Detect initial rfkill state on register Ivo van Doorn
@ 2007-10-27 11:41 ` Ivo van Doorn
2007-10-27 11:41 ` [PATCH 15/21] rt2x00: Rework rt61 antenna selection Ivo van Doorn
` (7 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:41 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
From: Adam Baker <linux@baker-net.org.uk>
Some register accesses need rt2x00dev to be non-const
they all need modifying so the prototype is consistent.
Signed-off-by: Adam Baker <linux@baker-net.org.uk>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 12 ++++++------
drivers/net/wireless/rt2x00/rt2500pci.c | 12 ++++++------
drivers/net/wireless/rt2x00/rt2500usb.c | 22 ++++++++++------------
drivers/net/wireless/rt2x00/rt2x00.h | 10 +++++-----
drivers/net/wireless/rt2x00/rt2x00debug.h | 4 ++--
drivers/net/wireless/rt2x00/rt2x00pci.h | 8 ++++----
drivers/net/wireless/rt2x00/rt2x00usb.c | 4 ++--
drivers/net/wireless/rt2x00/rt2x00usb.h | 11 +++++------
drivers/net/wireless/rt2x00/rt61pci.c | 14 +++++++-------
drivers/net/wireless/rt2x00/rt73usb.c | 22 ++++++++++------------
10 files changed, 57 insertions(+), 62 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index fc16212..f2d0feb 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -54,7 +54,7 @@
* the access attempt is considered to have failed,
* and we will print an error.
*/
-static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt2400pci_bbp_check(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
unsigned int i;
@@ -69,7 +69,7 @@ static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
return reg;
}
-static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u8 value)
{
u32 reg;
@@ -95,7 +95,7 @@ static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
}
-static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;
@@ -132,7 +132,7 @@ static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
}
-static void rt2400pci_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
u32 reg;
@@ -195,13 +195,13 @@ static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-static void rt2400pci_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_read_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
}
-static void rt2400pci_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_write_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c59ca0a..fbda28e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -54,7 +54,7 @@
* the access attempt is considered to have failed,
* and we will print an error.
*/
-static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt2500pci_bbp_check(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
unsigned int i;
@@ -69,7 +69,7 @@ static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
return reg;
}
-static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u8 value)
{
u32 reg;
@@ -95,7 +95,7 @@ static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
}
-static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;
@@ -132,7 +132,7 @@ static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
}
-static void rt2500pci_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
u32 reg;
@@ -195,13 +195,13 @@ static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-static void rt2500pci_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_read_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
}
-static void rt2500pci_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_write_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 6c2e275..de89e60 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -53,7 +53,7 @@
* the access attempt is considered to have failed,
* and we will print an error.
*/
-static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
u16 *value)
{
@@ -64,8 +64,7 @@ static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev,
*value = le16_to_cpu(reg);
}
-static inline void rt2500usb_register_multiread(const struct rt2x00_dev
- *rt2x00dev,
+static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u16 length)
{
@@ -75,7 +74,7 @@ static inline void rt2500usb_register_multiread(const struct rt2x00_dev
value, length, timeout);
}
-static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
u16 value)
{
@@ -85,8 +84,7 @@ static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev,
®, sizeof(u16), REGISTER_TIMEOUT);
}
-static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev
- *rt2x00dev,
+static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u16 length)
{
@@ -96,7 +94,7 @@ static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev
value, length, timeout);
}
-static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev)
{
u16 reg;
unsigned int i;
@@ -111,7 +109,7 @@ static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
return reg;
}
-static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u8 value)
{
u16 reg;
@@ -136,7 +134,7 @@ static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg);
}
-static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u16 reg;
@@ -173,7 +171,7 @@ static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
}
-static void rt2500usb_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
u16 reg;
@@ -210,13 +208,13 @@ rf_write:
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u16)) )
-static void rt2500usb_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_read_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
rt2500usb_register_read(rt2x00dev, CSR_OFFSET(word), (u16 *) data);
}
-static void rt2500usb_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_write_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
rt2500usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e488d9b..82e061c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -777,13 +777,13 @@ struct rt2x00_dev {
* Generic RF access.
* The RF is being accessed by word index.
*/
-static inline void rt2x00_rf_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
*data = rt2x00dev->rf[word];
}
-static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
rt2x00dev->rf[word] = data;
@@ -793,19 +793,19 @@ static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
* Generic EEPROM access.
* The EEPROM is being accessed by word index.
*/
-static inline void *rt2x00_eeprom_addr(const struct rt2x00_dev *rt2x00dev,
+static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev,
const unsigned int word)
{
return (void *)&rt2x00dev->eeprom[word];
}
-static inline void rt2x00_eeprom_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_eeprom_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u16 *data)
{
*data = le16_to_cpu(rt2x00dev->eeprom[word]);
}
-static inline void rt2x00_eeprom_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u16 data)
{
rt2x00dev->eeprom[word] = cpu_to_le16(data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h
index 860e8fa..d37efbd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.h
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.h
@@ -30,9 +30,9 @@ struct rt2x00_dev;
#define RT2X00DEBUGFS_REGISTER_ENTRY(__name, __type) \
struct reg##__name { \
- void (*read)(const struct rt2x00_dev *rt2x00dev, \
+ void (*read)(struct rt2x00_dev *rt2x00dev, \
const unsigned int word, __type *data); \
- void (*write)(const struct rt2x00_dev *rt2x00dev, \
+ void (*write)(struct rt2x00_dev *rt2x00dev, \
const unsigned int word, __type data); \
\
unsigned int word_size; \
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 82adeac..0357205 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -57,7 +57,7 @@
/*
* Register access.
*/
-static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
const unsigned long offset,
u32 *value)
{
@@ -65,14 +65,14 @@ static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev,
}
static inline void
-rt2x00pci_register_multiread(const struct rt2x00_dev *rt2x00dev,
+rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned long offset,
void *value, const u16 length)
{
memcpy_fromio(value, rt2x00dev->csr_addr + offset, length);
}
-static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
const unsigned long offset,
u32 value)
{
@@ -80,7 +80,7 @@ static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev,
}
static inline void
-rt2x00pci_register_multiwrite(const struct rt2x00_dev *rt2x00dev,
+rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned long offset,
void *value, const u16 length)
{
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 73cc726..47a9e5d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -38,7 +38,7 @@
/*
* Interfacing with the HW.
*/
-int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, const u16 value,
void *buffer, const u16 buffer_length,
@@ -76,7 +76,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request);
-int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, void *buffer,
const u16 buffer_length, const int timeout)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 2681abe..53282b0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -91,7 +91,7 @@
* a buffer allocated by kmalloc. Failure to do so can lead
* to unexpected behavior depending on the architecture.
*/
-int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, const u16 value,
void *buffer, const u16 buffer_length,
@@ -107,7 +107,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
* kmalloc. Hence the reason for using a previously allocated cache
* which has been allocated properly.
*/
-int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, void *buffer,
const u16 buffer_length, const int timeout);
@@ -117,8 +117,7 @@ int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
* command to the device. Since we don't use the buffer argument we
* don't have to worry about kmalloc here.
*/
-static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev
- *rt2x00dev,
+static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev,
const u8 request,
const u16 offset,
const u16 value,
@@ -134,8 +133,8 @@ static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev
* from the device. Note that the eeprom argument _must_ be allocated using
* kmalloc for correct handling inside the kernel USB layer.
*/
-static inline int rt2x00usb_eeprom_read(const struct rt2x00_dev *rt2x00dev,
- __le16 *eeprom, const u16 lenght)
+static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,
+ __le16 *eeprom, const u16 lenght)
{
int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16));
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 7f0665e..d540525 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -52,7 +52,7 @@
* the access attempt is considered to have failed,
* and we will print an error.
*/
-static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt61pci_bbp_check(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
unsigned int i;
@@ -67,7 +67,7 @@ static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
return reg;
}
-static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u8 value)
{
u32 reg;
@@ -93,7 +93,7 @@ static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
}
-static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;
@@ -130,7 +130,7 @@ static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
}
-static void rt61pci_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
u32 reg;
@@ -160,7 +160,7 @@ rf_write:
rt2x00_rf_write(rt2x00dev, word, value);
}
-static void rt61pci_mcu_request(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1)
{
@@ -220,13 +220,13 @@ static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-static void rt61pci_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_read_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
}
-static void rt61pci_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_write_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d1119e3..57fa18d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -53,7 +53,7 @@
* the access attempt is considered to have failed,
* and we will print an error.
*/
-static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
const unsigned int offset, u32 *value)
{
__le32 reg;
@@ -63,8 +63,7 @@ static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev,
*value = le32_to_cpu(reg);
}
-static inline void rt73usb_register_multiread(const struct rt2x00_dev
- *rt2x00dev,
+static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u32 length)
{
@@ -74,7 +73,7 @@ static inline void rt73usb_register_multiread(const struct rt2x00_dev
value, length, timeout);
}
-static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev,
const unsigned int offset, u32 value)
{
__le32 reg = cpu_to_le32(value);
@@ -83,8 +82,7 @@ static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev,
®, sizeof(u32), REGISTER_TIMEOUT);
}
-static inline void rt73usb_register_multiwrite(const struct rt2x00_dev
- *rt2x00dev,
+static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u32 length)
{
@@ -94,7 +92,7 @@ static inline void rt73usb_register_multiwrite(const struct rt2x00_dev
value, length, timeout);
}
-static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
unsigned int i;
@@ -109,7 +107,7 @@ static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
return reg;
}
-static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u8 value)
{
u32 reg;
@@ -135,7 +133,7 @@ static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
rt73usb_register_write(rt2x00dev, PHY_CSR3, reg);
}
-static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;
@@ -172,7 +170,7 @@ static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
}
-static void rt73usb_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
u32 reg;
@@ -212,13 +210,13 @@ rf_write:
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-static void rt73usb_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_read_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 *data)
{
rt73usb_register_read(rt2x00dev, CSR_OFFSET(word), data);
}
-static void rt73usb_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_write_csr(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u32 data)
{
rt73usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 15/21] rt2x00: Rework rt61 antenna selection.
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (13 preceding siblings ...)
2007-10-27 11:41 ` [PATCH 14/21] rt2x00: Unconstify rt2x00dev Ivo van Doorn
@ 2007-10-27 11:41 ` Ivo van Doorn
2007-10-27 11:42 ` [PATCH 16/21] rt2x00: Remove unused variables Ivo van Doorn
` (6 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:41 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
From: Mattias Nissler <mattias.nissler@gmx.de>
This patch changes rt61 antenna selection again. It helps at least with the
rt61 pci card in my box, I hope I haven't broken behaviour on other RF chips.
RF 2529 antenna setup is incomplete, we need to at code for diversity when we
figure out how it is done properly.
Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt61pci.c | 143 +++++++++------------------------
drivers/net/wireless/rt2x00/rt61pci.h | 10 ++-
2 files changed, 46 insertions(+), 107 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index d540525..0839946 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -422,40 +422,24 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt61pci_bbp_read(rt2x00dev, 77, &r77);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
- !rt2x00_rf(&rt2x00dev->chip, RF5225));
-
- /*
- * Configure the TX antenna.
- */
- switch (ant->tx) {
- case ANTENNA_A:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
- break;
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
- case ANTENNA_B:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
- break;
- }
+ rt2x00_rf(&rt2x00dev->chip, RF5325));
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
(rt2x00dev->curr_hwmode != HWMODE_A));
break;
case ANTENNA_A:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+ if (rt2x00dev->curr_hwmode == HWMODE_A)
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+ else
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -465,8 +449,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
* Instead, just default to antenna B.
*/
case ANTENNA_B:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+ if (rt2x00dev->curr_hwmode == HWMODE_A)
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+ else
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
break;
}
@@ -487,39 +475,20 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt61pci_bbp_read(rt2x00dev, 77, &r77);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
- !rt2x00_rf(&rt2x00dev->chip, RF2527));
+ rt2x00_rf(&rt2x00dev->chip, RF2529));
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
/*
- * Configure the TX antenna.
- */
- switch (ant->tx) {
- case ANTENNA_A:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
- break;
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
- case ANTENNA_B:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
- break;
- }
-
- /*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
break;
case ANTENNA_A:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -529,7 +498,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
* Instead, just default to antenna B.
*/
case ANTENNA_B:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
break;
}
@@ -545,16 +515,13 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
- if (p1 != 0xff) {
- rt2x00_set_field32(®, MAC_CSR13_BIT4, !!p1);
- rt2x00_set_field32(®, MAC_CSR13_BIT12, 0);
- rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
- }
- if (p2 != 0xff) {
- rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2);
- rt2x00_set_field32(®, MAC_CSR13_BIT11, 0);
- rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
- }
+ rt2x00_set_field32(®, MAC_CSR13_BIT4, p1);
+ rt2x00_set_field32(®, MAC_CSR13_BIT12, 0);
+
+ rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2);
+ rt2x00_set_field32(®, MAC_CSR13_BIT11, 0);
+
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
}
static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
@@ -570,37 +537,18 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
rt61pci_bbp_read(rt2x00dev, 4, &r4);
rt61pci_bbp_read(rt2x00dev, 77, &r77);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
- rx_ant = !!(rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) & 2);
-
- rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
-
- /*
- * Configure the TX antenna.
+ /* FIXME: Antenna selection for the rf 2529 is very confusing in the
+ * legacy driver. The code below should be ok for non-diversity setups.
*/
- switch (ant->tx) {
- case ANTENNA_A:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
- break;
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
- case ANTENNA_B:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
- break;
- }
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_A:
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, rx_ant);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+ rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
break;
case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
@@ -611,27 +559,12 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
* Instead, just default to antenna B.
*/
case ANTENNA_B:
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, rx_ant);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+ rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
break;
}
- /*
- * FIXME: We are using the default antenna setup to
- * determine the remaining settings. This because we
- * need to know what the EEPROM indicated.
- * It is however unclear if this is required, and overall
- * using the default antenna settings here is incorrect
- * since mac80211 might have told us to use fixed settings.
- */
- if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
- else
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
- (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) &&
- (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY));
-
rt61pci_bbp_write(rt2x00dev, 77, r77);
rt61pci_bbp_write(rt2x00dev, 3, r3);
rt61pci_bbp_write(rt2x00dev, 4, r4);
@@ -676,8 +609,6 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
unsigned int i;
u32 reg;
- rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®);
-
if (rt2x00dev->curr_hwmode == HWMODE_A) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
@@ -686,15 +617,17 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
}
+ for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
+ rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
+
+ rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®);
+
rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
(rt2x00dev->curr_hwmode == HWMODE_B ||
rt2x00dev->curr_hwmode == HWMODE_G));
rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
(rt2x00dev->curr_hwmode == HWMODE_A));
- for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
- rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
-
rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index ba51016..50d9f6a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1077,13 +1077,19 @@ struct hw_pairwise_ta_entry {
* R4: RX antenna control
* FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
*/
-#define BBP_R4_RX_ANTENNA FIELD8(0x03)
+
+/*
+ * ANTENNA_CONTROL semantics (guessed):
+ * 0x1: Software controlled antenna switching (fixed or SW diversity)
+ * 0x2: Hardware diversity.
+ */
+#define BBP_R4_RX_ANTENNA_CONTROL FIELD8(0x03)
#define BBP_R4_RX_FRAME_END FIELD8(0x20)
/*
* R77
*/
-#define BBP_R77_TX_ANTENNA FIELD8(0x03)
+#define BBP_R77_RX_ANTENNA FIELD8(0x03)
/*
* RF registers
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 16/21] rt2x00: Remove unused variables
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (14 preceding siblings ...)
2007-10-27 11:41 ` [PATCH 15/21] rt2x00: Rework rt61 antenna selection Ivo van Doorn
@ 2007-10-27 11:42 ` Ivo van Doorn
2007-10-27 11:42 ` [PATCH 17/21] rt2x00: Rework rt73 antenna selection Ivo van Doorn
` (5 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:42 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
With the updated antenna setup the following
variables are no longer used.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt61pci.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0839946..0b8aeec 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -527,11 +527,9 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant)
{
- u16 eeprom;
u8 r3;
u8 r4;
u8 r77;
- u8 rx_ant;
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt61pci_bbp_read(rt2x00dev, 4, &r4);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 17/21] rt2x00: Rework rt73 antenna selection
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (15 preceding siblings ...)
2007-10-27 11:42 ` [PATCH 16/21] rt2x00: Remove unused variables Ivo van Doorn
@ 2007-10-27 11:42 ` Ivo van Doorn
2007-10-27 11:43 ` [PATCH 18/21] rt2x00: Remove data_desc structure Ivo van Doorn
` (4 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:42 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
From: Mattias Nissler <mattias.nissler@gmx.de>
This patch changes rt73 antenna selection to what I believe is the correct way.
It also fixes a small selection bug that switched the antennas by accident.
Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt73usb.c | 78 ++++++++++----------------------
drivers/net/wireless/rt2x00/rt73usb.h | 10 +++-
2 files changed, 33 insertions(+), 55 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 57fa18d..1c44081 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -399,6 +399,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
u8 r3;
u8 r4;
u8 r77;
+ u8 temp;
rt73usb_bbp_read(rt2x00dev, 3, &r3);
rt73usb_bbp_read(rt2x00dev, 4, &r4);
@@ -407,37 +408,22 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
/*
- * Configure the TX antenna.
- */
- switch (ant->tx) {
- case ANTENNA_A:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
- break;
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
- case ANTENNA_B:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
- break;
- }
-
- /*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
- (rt2x00dev->curr_hwmode != HWMODE_A));
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
+ temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
+ && (rt2x00dev->curr_hwmode != HWMODE_A);
+ rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
break;
case ANTENNA_A:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+ if (rt2x00dev->curr_hwmode == HWMODE_A)
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+ else
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -447,8 +433,12 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
* Instead, just default to antenna B.
*/
case ANTENNA_B:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+ if (rt2x00dev->curr_hwmode == HWMODE_A)
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+ else
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
break;
}
@@ -473,34 +463,15 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
/*
- * Configure the TX antenna.
- */
- switch (ant->tx) {
- case ANTENNA_A:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
- break;
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
- case ANTENNA_B:
- rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
- break;
- }
-
- /*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
break;
case ANTENNA_A:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
break;
case ANTENNA_SW_DIVERSITY:
/*
@@ -510,7 +481,8 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
* Instead, just default to antenna B.
*/
case ANTENNA_B:
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+ rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
break;
}
@@ -558,8 +530,6 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
unsigned int i;
u32 reg;
- rt73usb_register_read(rt2x00dev, PHY_CSR0, ®);
-
if (rt2x00dev->curr_hwmode == HWMODE_A) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
@@ -568,15 +538,17 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
}
+ for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
+ rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
+
+ rt73usb_register_read(rt2x00dev, PHY_CSR0, ®);
+
rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
(rt2x00dev->curr_hwmode == HWMODE_B ||
rt2x00dev->curr_hwmode == HWMODE_G));
rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
(rt2x00dev->curr_hwmode == HWMODE_A));
- for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
- rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
-
rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 13f479c..b967df2 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -713,13 +713,19 @@ struct hw_pairwise_ta_entry {
* R4: RX antenna control
* FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
*/
-#define BBP_R4_RX_ANTENNA FIELD8(0x03)
+
+/*
+ * ANTENNA_CONTROL semantics (guessed):
+ * 0x1: Software controlled antenna switching (fixed or SW diversity)
+ * 0x2: Hardware diversity.
+ */
+#define BBP_R4_RX_ANTENNA_CONTROL FIELD8(0x03)
#define BBP_R4_RX_FRAME_END FIELD8(0x20)
/*
* R77
*/
-#define BBP_R77_TX_ANTENNA FIELD8(0x03)
+#define BBP_R77_RX_ANTENNA FIELD8(0x03)
/*
* RF registers
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 18/21] rt2x00: Remove data_desc structure
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (16 preceding siblings ...)
2007-10-27 11:42 ` [PATCH 17/21] rt2x00: Rework rt73 antenna selection Ivo van Doorn
@ 2007-10-27 11:43 ` Ivo van Doorn
2007-10-27 11:43 ` [PATCH 19/21] rt2x00: Place mutex around USB register access Ivo van Doorn
` (3 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:43 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Coverty indicated that data_desc with a single
element array is bad coding style. This removes
the structure and forces everybody to use __le32.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 10 +++++-----
drivers/net/wireless/rt2x00/rt2400pci.h | 4 ++--
drivers/net/wireless/rt2x00/rt2500pci.c | 10 +++++-----
drivers/net/wireless/rt2x00/rt2500pci.h | 4 ++--
drivers/net/wireless/rt2x00/rt2500usb.c | 9 ++++-----
drivers/net/wireless/rt2x00/rt2500usb.h | 4 ++--
drivers/net/wireless/rt2x00/rt2x00.h | 4 ++--
drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ++--
drivers/net/wireless/rt2x00/rt2x00ring.h | 22 ++++------------------
drivers/net/wireless/rt2x00/rt2x00usb.c | 4 ++--
drivers/net/wireless/rt2x00/rt61pci.c | 12 ++++++------
drivers/net/wireless/rt2x00/rt61pci.h | 4 ++--
drivers/net/wireless/rt2x00/rt73usb.c | 6 +++---
drivers/net/wireless/rt2x00/rt73usb.h | 4 ++--
15 files changed, 44 insertions(+), 59 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index f2d0feb..8889f6d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -600,7 +600,7 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
static void rt2400pci_init_rxring(struct rt2x00_dev *rt2x00dev)
{
struct data_ring *ring = rt2x00dev->rx;
- struct data_desc *rxd;
+ __le32 *rxd;
unsigned int i;
u32 word;
@@ -630,7 +630,7 @@ static void rt2400pci_init_rxring(struct rt2x00_dev *rt2x00dev)
static void rt2400pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
{
struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
- struct data_desc *txd;
+ __le32 *txd;
unsigned int i;
u32 word;
@@ -1017,7 +1017,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
* TX descriptor initialization
*/
static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
@@ -1117,7 +1117,7 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
static void rt2400pci_fill_rxdone(struct data_entry *entry,
struct rxdata_entry_desc *desc)
{
- struct data_desc *rxd = entry->priv;
+ __le32 *rxd = entry->priv;
u32 word0;
u32 word2;
@@ -1147,7 +1147,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
{
struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
struct data_entry *entry;
- struct data_desc *txd;
+ __le32 *txd;
u32 word;
int tx_status;
int retry;
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index ae22501..f5dbde7 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -803,8 +803,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 8 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE ( 8 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE ( 8 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 8 * sizeof(__le32) )
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index fbda28e..0aedc46 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -691,7 +691,7 @@ dynamic_cca_tune:
static void rt2500pci_init_rxring(struct rt2x00_dev *rt2x00dev)
{
struct data_ring *ring = rt2x00dev->rx;
- struct data_desc *rxd;
+ __le32 *rxd;
unsigned int i;
u32 word;
@@ -716,7 +716,7 @@ static void rt2500pci_init_rxring(struct rt2x00_dev *rt2x00dev)
static void rt2500pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
{
struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
- struct data_desc *txd;
+ __le32 *txd;
unsigned int i;
u32 word;
@@ -1167,7 +1167,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
* TX descriptor initialization
*/
static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
@@ -1251,7 +1251,7 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
static void rt2500pci_fill_rxdone(struct data_entry *entry,
struct rxdata_entry_desc *desc)
{
- struct data_desc *rxd = entry->priv;
+ __le32 *rxd = entry->priv;
u32 word0;
u32 word2;
@@ -1278,7 +1278,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
{
struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
struct data_entry *entry;
- struct data_desc *txd;
+ __le32 *txd;
u32 word;
int tx_status;
int retry;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index d92aa56..92ba090 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1082,8 +1082,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 11 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE ( 11 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE ( 11 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 11 * sizeof(__le32) )
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index de89e60..041a847 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -990,7 +990,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
* TX descriptor initialization
*/
static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
@@ -1082,9 +1082,8 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry,
struct rxdata_entry_desc *desc)
{
struct urb *urb = entry->priv;
- struct data_desc *rxd = (struct data_desc *)(entry->skb->data +
- (urb->actual_length -
- entry->ring->desc_size));
+ __le32 *rxd = (__le32 *)(entry->skb->data +
+ (urb->actual_length - entry->ring->desc_size));
u32 word0;
u32 word1;
@@ -1683,7 +1682,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
skb_push(skb, ring->desc_size);
memset(skb->data, 0, ring->desc_size);
- rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
+ rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
(struct ieee80211_hdr *)(skb->data +
ring->desc_size),
skb->len - ring->desc_size, control);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 2741840..9e04337 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -703,8 +703,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 5 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE ( 4 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE ( 5 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 4 * sizeof(__le32) )
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 82e061c..e41eb06 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -488,7 +488,7 @@ struct rt2x00lib_ops {
* TX control handlers
*/
void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
@@ -882,7 +882,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
* TX descriptor initializer
*/
void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 360f03a..304830b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -578,7 +578,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
* TX descriptor initializer
*/
void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 2780df0..045b954 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -80,7 +80,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
{
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
struct data_entry *entry = rt2x00_get_data_entry(ring);
- struct data_desc *txd = entry->priv;
+ __le32 *txd = entry->priv;
u32 word;
if (rt2x00_ring_full(ring)) {
@@ -122,9 +122,9 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
{
struct data_ring *ring = rt2x00dev->rx;
struct data_entry *entry;
- struct data_desc *rxd;
struct sk_buff *skb;
struct rxdata_entry_desc desc;
+ __le32 *rxd;
u32 word;
while (1) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h
index 1a864d3..ee6c423 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ring.h
+++ b/drivers/net/wireless/rt2x00/rt2x00ring.h
@@ -27,20 +27,6 @@
#define RT2X00RING_H
/*
- * data_desc
- * Each data entry also contains a descriptor which is used by the
- * device to determine what should be done with the packet and
- * what the current status is.
- * This structure is greatly simplified, but the descriptors
- * are basically a list of little endian 32 bit values.
- * Make the array by default 1 word big, this will allow us
- * to use sizeof() correctly.
- */
-struct data_desc {
- __le32 word[1];
-};
-
-/*
* rxdata_entry_desc
* Summary of information that has been read from the
* RX frame descriptor.
@@ -253,16 +239,16 @@ static inline int rt2x00_ring_free(struct data_ring *ring)
/*
* TX/RX Descriptor access functions.
*/
-static inline void rt2x00_desc_read(struct data_desc *desc,
+static inline void rt2x00_desc_read(__le32 *desc,
const u8 word, u32 *value)
{
- *value = le32_to_cpu(desc->word[word]);
+ *value = le32_to_cpu(desc[word]);
}
-static inline void rt2x00_desc_write(struct data_desc *desc,
+static inline void rt2x00_desc_write(__le32 *desc,
const u8 word, const u32 value)
{
- desc->word[word] = cpu_to_le32(value);
+ desc[word] = cpu_to_le32(value);
}
#endif /* RT2X00RING_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 47a9e5d..dfafb0e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -113,7 +113,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
struct data_entry *entry = (struct data_entry *)urb->context;
struct data_ring *ring = entry->ring;
struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
- struct data_desc *txd = (struct data_desc *)entry->skb->data;
+ __le32 *txd = (__le32 *)entry->skb->data;
u32 word;
int tx_status;
@@ -182,7 +182,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
skb_push(skb, ring->desc_size);
memset(skb->data, 0, ring->desc_size);
- rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
+ rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
(struct ieee80211_hdr *)(skb->data +
ring->desc_size),
skb->len - ring->desc_size, control);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0b8aeec..37fe772 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -996,7 +996,7 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev)
{
struct data_ring *ring = rt2x00dev->rx;
- struct data_desc *rxd;
+ __le32 *rxd;
unsigned int i;
u32 word;
@@ -1021,7 +1021,7 @@ static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev)
static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
{
struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
- struct data_desc *txd;
+ __le32 *txd;
unsigned int i;
u32 word;
@@ -1535,7 +1535,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
* TX descriptor initialization
*/
static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
@@ -1679,7 +1679,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
static void rt61pci_fill_rxdone(struct data_entry *entry,
struct rxdata_entry_desc *desc)
{
- struct data_desc *rxd = entry->priv;
+ __le32 *rxd = entry->priv;
u32 word0;
u32 word1;
@@ -1708,7 +1708,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
{
struct data_ring *ring;
struct data_entry *entry;
- struct data_desc *txd;
+ __le32 *txd;
u32 word;
u32 reg;
u32 old_reg;
@@ -2443,7 +2443,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skb_push(skb, TXD_DESC_SIZE);
memset(skb->data, 0, TXD_DESC_SIZE);
- rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
+ rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
(struct ieee80211_hdr *)(skb->data +
TXD_DESC_SIZE),
skb->len - TXD_DESC_SIZE, control);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 50d9f6a..4c6524e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1246,8 +1246,8 @@ struct hw_pairwise_ta_entry {
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 16 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE ( 16 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE ( 16 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 16 * sizeof(__le32) )
/*
* TX descriptor format for TX, PRIO and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1c44081..d9cf997 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1203,7 +1203,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
* TX descriptor initialization
*/
static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct data_desc *txd,
+ __le32 *txd,
struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
@@ -1350,7 +1350,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
static void rt73usb_fill_rxdone(struct data_entry *entry,
struct rxdata_entry_desc *desc)
{
- struct data_desc *rxd = (struct data_desc *)entry->skb->data;
+ __le32 *rxd = (__le32 *)entry->skb->data;
u32 word0;
u32 word1;
@@ -1953,7 +1953,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skb_push(skb, TXD_DESC_SIZE);
memset(skb->data, 0, TXD_DESC_SIZE);
- rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
+ rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
(struct ieee80211_hdr *)(skb->data +
TXD_DESC_SIZE),
skb->len - TXD_DESC_SIZE, control);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index b967df2..d49dcaa 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -866,8 +866,8 @@ struct hw_pairwise_ta_entry {
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 6 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE ( 6 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE ( 6 * sizeof(__le32) )
+#define RXD_DESC_SIZE ( 6 * sizeof(__le32) )
/*
* TX descriptor format for TX, PRIO and Beacon Ring.
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 19/21] rt2x00: Place mutex around USB register access
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (17 preceding siblings ...)
2007-10-27 11:43 ` [PATCH 18/21] rt2x00: Remove data_desc structure Ivo van Doorn
@ 2007-10-27 11:43 ` Ivo van Doorn
2007-10-27 11:43 ` [PATCH 20/21] rt2x00: Correctly set ACK bit in tx descriptors Ivo van Doorn
` (2 subsequent siblings)
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:43 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
From: Adam Baker <linux@baker-net.org.uk>
There is a buffer, csr_cache which is used to hold copies of data being passed
to the USB stack which can get corrupted if multiple threads attempt to access
CSR registers simultaneously. There is also the possibility if multiple
threads try to access BBP or RF registers for the multiple USB operations
needed to get interleaved leading to incorrect results. This patch introduces
a mutex to prevent such simultaneous access. The interleaved access problem
may also affect the PCI devices but if so that will be handled in a follow-up
patch.
Signed-off-by: Adam Baker <linux@baker-net.org.uk>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2500usb.c | 52 ++++++++++++++++++++++++++----
drivers/net/wireless/rt2x00/rt2x00.h | 13 ++++++++
drivers/net/wireless/rt2x00/rt2x00usb.c | 32 ++++++++++++++++--
drivers/net/wireless/rt2x00/rt2x00usb.h | 8 +++++
drivers/net/wireless/rt2x00/rt73usb.c | 42 ++++++++++++++++++++++---
5 files changed, 131 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 041a847..fdc6da5 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -52,6 +52,8 @@
* between each attampt. When the busy bit is still set at that time,
* the access attempt is considered to have failed,
* and we will print an error.
+ * If the usb_cache_mutex is already held then the _lock variants must
+ * be used instead.
*/
static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
@@ -64,6 +66,17 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
*value = le16_to_cpu(reg);
}
+static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u16 *value)
+{
+ __le16 reg;
+ rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
+ USB_VENDOR_REQUEST_IN, offset,
+ ®, sizeof(u16), REGISTER_TIMEOUT);
+ *value = le16_to_cpu(reg);
+}
+
static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u16 length)
@@ -84,6 +97,16 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
®, sizeof(u16), REGISTER_TIMEOUT);
}
+static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u16 value)
+{
+ __le16 reg = cpu_to_le16(value);
+ rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT, offset,
+ ®, sizeof(u16), REGISTER_TIMEOUT);
+}
+
static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u16 length)
@@ -100,7 +123,7 @@ static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev)
unsigned int i;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2500usb_register_read(rt2x00dev, PHY_CSR8, ®);
+ rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, ®);
if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY))
break;
udelay(REGISTER_BUSY_DELAY);
@@ -114,12 +137,15 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
{
u16 reg;
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
/*
* Wait until the BBP becomes ready.
*/
reg = rt2500usb_bbp_check(rt2x00dev);
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
return;
}
@@ -131,7 +157,9 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field16(®, PHY_CSR7_REG_ID, word);
rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0);
- rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg);
+ rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
+
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
}
static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -139,6 +167,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
{
u16 reg;
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
/*
* Wait until the BBP becomes ready.
*/
@@ -155,7 +185,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field16(®, PHY_CSR7_REG_ID, word);
rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1);
- rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg);
+ rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
/*
* Wait until the BBP becomes ready.
@@ -164,11 +194,14 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
*value = 0xff;
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
return;
}
- rt2500usb_register_read(rt2x00dev, PHY_CSR7, ®);
+ rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®);
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
+
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
}
static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -180,20 +213,23 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
if (!word)
return;
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2500usb_register_read(rt2x00dev, PHY_CSR10, ®);
+ rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®);
if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY))
goto rf_write;
udelay(REGISTER_BUSY_DELAY);
}
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
return;
rf_write:
reg = 0;
rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value);
- rt2500usb_register_write(rt2x00dev, PHY_CSR9, reg);
+ rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg);
reg = 0;
rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16);
@@ -201,8 +237,10 @@ rf_write:
rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0);
rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1);
- rt2500usb_register_write(rt2x00dev, PHY_CSR10, reg);
+ rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
rt2x00_rf_write(rt2x00dev, word, value);
+
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
}
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e41eb06..c555abb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -31,6 +31,7 @@
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/firmware.h>
+#include <linux/mutex.h>
#include <net/mac80211.h>
@@ -659,6 +660,18 @@ struct rt2x00_dev {
void *csr_cache;
/*
+ * Mutex to protect register accesses on USB devices.
+ * There are 2 reasons this is needed, one is to ensure
+ * use of the csr_cache (for USB devices) by one thread
+ * isn't corrupted by another thread trying to access it.
+ * The other is that access to BBP and RF registers
+ * require multiple BUS transactions and if another thread
+ * attempted to access one of those registers at the same
+ * time one of the writes could silently fail.
+ */
+ struct mutex usb_cache_mutex;
+
+ /*
* Interface configuration.
*/
struct interface interface;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index dfafb0e..f61dee5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
+#include <linux/bug.h>
#include "rt2x00.h"
#include "rt2x00usb.h"
@@ -52,6 +53,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
(requesttype == USB_VENDOR_REQUEST_IN) ?
usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
+
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
status = usb_control_msg(usb_dev, pipe, request, requesttype,
value, offset, buffer, buffer_length,
@@ -76,13 +78,15 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request);
-int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
- const u8 request, const u8 requesttype,
- const u16 offset, void *buffer,
- const u16 buffer_length, const int timeout)
+int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
+ const u8 request, const u8 requesttype,
+ const u16 offset, void *buffer,
+ const u16 buffer_length, const int timeout)
{
int status;
+ BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
+
/*
* Check for Cache availability.
*/
@@ -103,6 +107,25 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
return status;
}
+EXPORT_SYMBOL_GPL(rt2x00usb_vendor_req_buff_lock);
+
+int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
+ const u8 request, const u8 requesttype,
+ const u16 offset, void *buffer,
+ const u16 buffer_length, const int timeout)
+{
+ int status;
+
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
+ status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
+ requesttype, offset, buffer,
+ buffer_length, timeout);
+
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ return status;
+}
EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
/*
@@ -489,6 +512,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
rt2x00dev->dev = usb_intf;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
+ mutex_init(&rt2x00dev->usb_cache_mutex);
retval = rt2x00usb_alloc_reg(rt2x00dev);
if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 53282b0..2fa45c5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -113,6 +113,14 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
const u16 buffer_length, const int timeout);
/*
+ * A version of rt2x00usb_vendor_request_buff which must be called
+ * if the usb_cache_mutex is already held. */
+int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
+ const u8 request, const u8 requesttype,
+ const u16 offset, void *buffer,
+ const u16 buffer_length, const int timeout);
+
+/*
* Simple wrapper around rt2x00usb_vendor_request to write a single
* command to the device. Since we don't use the buffer argument we
* don't have to worry about kmalloc here.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d9cf997..d1375b8 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -52,6 +52,7 @@
* between each attampt. When the busy bit is still set at that time,
* the access attempt is considered to have failed,
* and we will print an error.
+ * The _lock versions must be used if you already hold the usb_cache_mutex
*/
static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
const unsigned int offset, u32 *value)
@@ -63,6 +64,16 @@ static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
*value = le32_to_cpu(reg);
}
+static inline void rt73usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset, u32 *value)
+{
+ __le32 reg;
+ rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
+ USB_VENDOR_REQUEST_IN, offset,
+ ®, sizeof(u32), REGISTER_TIMEOUT);
+ *value = le32_to_cpu(reg);
+}
+
static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u32 length)
@@ -82,6 +93,15 @@ static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev,
®, sizeof(u32), REGISTER_TIMEOUT);
}
+static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset, u32 value)
+{
+ __le32 reg = cpu_to_le32(value);
+ rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT, offset,
+ ®, sizeof(u32), REGISTER_TIMEOUT);
+}
+
static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u32 length)
@@ -98,7 +118,7 @@ static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev)
unsigned int i;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt73usb_register_read(rt2x00dev, PHY_CSR3, ®);
+ rt73usb_register_read_lock(rt2x00dev, PHY_CSR3, ®);
if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY))
break;
udelay(REGISTER_BUSY_DELAY);
@@ -112,12 +132,15 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
/*
* Wait until the BBP becomes ready.
*/
reg = rt73usb_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
return;
}
@@ -130,7 +153,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(®, PHY_CSR3_BUSY, 1);
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0);
- rt73usb_register_write(rt2x00dev, PHY_CSR3, reg);
+ rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
}
static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -138,12 +162,15 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
/*
* Wait until the BBP becomes ready.
*/
reg = rt73usb_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
return;
}
@@ -155,7 +182,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(®, PHY_CSR3_BUSY, 1);
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1);
- rt73usb_register_write(rt2x00dev, PHY_CSR3, reg);
+ rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
/*
* Wait until the BBP becomes ready.
@@ -168,6 +195,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
}
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
}
static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -179,13 +207,16 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
if (!word)
return;
+ mutex_lock(&rt2x00dev->usb_cache_mutex);
+
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt73usb_register_read(rt2x00dev, PHY_CSR4, ®);
+ rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®);
if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
goto rf_write;
udelay(REGISTER_BUSY_DELAY);
}
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
return;
@@ -203,8 +234,9 @@ rf_write:
rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0);
rt2x00_set_field32(®, PHY_CSR4_BUSY, 1);
- rt73usb_register_write(rt2x00dev, PHY_CSR4, reg);
+ rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
rt2x00_rf_write(rt2x00dev, word, value);
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
}
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 20/21] rt2x00: Correctly set ACK bit in tx descriptors
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (18 preceding siblings ...)
2007-10-27 11:43 ` [PATCH 19/21] rt2x00: Place mutex around USB register access Ivo van Doorn
@ 2007-10-27 11:43 ` Ivo van Doorn
2007-10-27 11:44 ` [PATCH 21/21] rt2x00: Release rt2x00 2.0.12 Ivo van Doorn
2007-10-27 12:47 ` [Rt2400-devel] Please pull 'upstream' branch of rt2x00 John W. Linville
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:43 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
From: Mattias Nissler <mattias.nissler@gmx.de>
Add a flag to struct txdata_entry_desc that specifies whether an ack for the
frame is to be expected. Use this flag to set the ACK bit in the tx descriptor.
Previously, the ACK bit could be set incorrectly on CTS-to-self frames, so they
caused retries and were reported to be failed in the txdone handlers.
Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2500pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00dev.c | 11 ++++++++++-
drivers/net/wireless/rt2x00/rt2x00ring.h | 1 +
drivers/net/wireless/rt2x00/rt61pci.c | 2 +-
drivers/net/wireless/rt2x00/rt73usb.c | 2 +-
7 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 8889f6d..d48b6ca 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1072,7 +1072,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_ACK,
- !(control->flags & IEEE80211_TXCTL_NO_ACK));
+ test_bit(ENTRY_TXD_ACK, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_RTS,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 0aedc46..c5a5c43 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1203,7 +1203,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_ACK,
- !(control->flags & IEEE80211_TXCTL_NO_ACK));
+ test_bit(ENTRY_TXD_ACK, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index fdc6da5..43f1e0f 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1058,7 +1058,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_ACK,
- !(control->flags & IEEE80211_TXCTL_NO_ACK));
+ test_bit(ENTRY_TXD_ACK, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 304830b..3ab1fb9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -629,12 +629,21 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
tx_rate = control->tx_rate;
/*
+ * Check whether this frame is to be acked
+ */
+ if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
+ __set_bit(ENTRY_TXD_ACK, &desc.flags);
+
+ /*
* Check if this is a RTS/CTS frame
*/
if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
__set_bit(ENTRY_TXD_BURST, &desc.flags);
- if (is_rts_frame(frame_control))
+ if (is_rts_frame(frame_control)) {
__set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags);
+ __set_bit(ENTRY_TXD_ACK, &desc.flags);
+ } else
+ __clear_bit(ENTRY_TXD_ACK, &desc.flags);
if (control->rts_cts_rate)
tx_rate = control->rts_cts_rate;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h
index ee6c423..5b871ad 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ring.h
+++ b/drivers/net/wireless/rt2x00/rt2x00ring.h
@@ -52,6 +52,7 @@ struct txdata_entry_desc {
#define ENTRY_TXD_MORE_FRAG 4
#define ENTRY_TXD_REQ_TIMESTAMP 5
#define ENTRY_TXD_BURST 6
+#define ENTRY_TXD_ACK 7
/*
* Queue ID. ID's 0-4 are data TX rings
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 37fe772..105dc86 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1578,7 +1578,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_ACK,
- !(control->flags & IEEE80211_TXCTL_NO_ACK));
+ test_bit(ENTRY_TXD_ACK, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d1375b8..532e75d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1275,7 +1275,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_ACK,
- !(control->flags & IEEE80211_TXCTL_NO_ACK));
+ test_bit(ENTRY_TXD_ACK, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* [PATCH 21/21] rt2x00: Release rt2x00 2.0.12
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (19 preceding siblings ...)
2007-10-27 11:43 ` [PATCH 20/21] rt2x00: Correctly set ACK bit in tx descriptors Ivo van Doorn
@ 2007-10-27 11:44 ` Ivo van Doorn
2007-10-27 12:47 ` [Rt2400-devel] Please pull 'upstream' branch of rt2x00 John W. Linville
21 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 11:44 UTC (permalink / raw)
To: John W. Linville; +Cc: rt2400-devel, linux-wireless
Version bump.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c555abb..82014d8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -43,7 +43,7 @@
* Module information.
* DRV_NAME should be set within the individual module source files.
*/
-#define DRV_VERSION "2.0.11"
+#define DRV_VERSION "2.0.12"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
--
1.5.3.4
^ permalink raw reply related [flat|nested] 78+ messages in thread* Re: [Rt2400-devel] Please pull 'upstream' branch of rt2x00
2007-10-27 11:34 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (20 preceding siblings ...)
2007-10-27 11:44 ` [PATCH 21/21] rt2x00: Release rt2x00 2.0.12 Ivo van Doorn
@ 2007-10-27 12:47 ` John W. Linville
2007-10-27 14:45 ` Ivo van Doorn
21 siblings, 1 reply; 78+ messages in thread
From: John W. Linville @ 2007-10-27 12:47 UTC (permalink / raw)
To: Ivo van Doorn; +Cc: linux-wireless, rt2400-devel
On Sat, Oct 27, 2007 at 01:34:34PM +0200, Ivo van Doorn wrote:
> Here is the 2.0.12 release of rt2x00.
> I noticed you only pulled 2 patches from the 2.0.11 release,
> and I don't know why you dropped the remaining patches.
> This means that this pull requests also contains the remaining
> 2.0.11 patches...
I haven't dropped them. I'll be merging them for 2.6.25. The patches
that got merged were sent as fixes for 2.6.24.
Thanks,
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply [flat|nested] 78+ messages in thread* Re: [Rt2400-devel] Please pull 'upstream' branch of rt2x00
2007-10-27 12:47 ` [Rt2400-devel] Please pull 'upstream' branch of rt2x00 John W. Linville
@ 2007-10-27 14:45 ` Ivo van Doorn
2007-10-27 16:19 ` Ivo van Doorn
0 siblings, 1 reply; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 14:45 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
On Saturday 27 October 2007, John W. Linville wrote:
> On Sat, Oct 27, 2007 at 01:34:34PM +0200, Ivo van Doorn wrote:
>
> > Here is the 2.0.12 release of rt2x00.
> > I noticed you only pulled 2 patches from the 2.0.11 release,
> > and I don't know why you dropped the remaining patches.
> > This means that this pull requests also contains the remaining
> > 2.0.11 patches...
>
> I haven't dropped them. I'll be merging them for 2.6.25. The patches
> that got merged were sent as fixes for 2.6.24.
Ah ok. Thanks.
Ivo
^ permalink raw reply [flat|nested] 78+ messages in thread
* Re: [Rt2400-devel] Please pull 'upstream' branch of rt2x00
2007-10-27 14:45 ` Ivo van Doorn
@ 2007-10-27 16:19 ` Ivo van Doorn
0 siblings, 0 replies; 78+ messages in thread
From: Ivo van Doorn @ 2007-10-27 16:19 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
On Saturday 27 October 2007, Ivo van Doorn wrote:
> On Saturday 27 October 2007, John W. Linville wrote:
> > On Sat, Oct 27, 2007 at 01:34:34PM +0200, Ivo van Doorn wrote:
> >
> > > Here is the 2.0.12 release of rt2x00.
> > > I noticed you only pulled 2 patches from the 2.0.11 release,
> > > and I don't know why you dropped the remaining patches.
> > > This means that this pull requests also contains the remaining
> > > 2.0.11 patches...
> >
> > I haven't dropped them. I'll be merging them for 2.6.25. The patches
> > that got merged were sent as fixes for 2.6.24.
>
> Ah ok. Thanks.
Btw, is there any branch in wireless-2.6 which in this case contains all
pending patches? (So those that also includes the patches which will
be merged for the next kernel).
I could use that branch to update rt2x00.git from.
Ivo
^ permalink raw reply [flat|nested] 78+ messages in thread