rpms/kernel/devel linux-2.6-rt2x00-updates.patch, NONE, 1.1 linux-2.6-wireless-round_jiffies_relative.patch, NONE, 1.1
John W. Linville (linville)
fedora-extras-commits at redhat.com
Fri Oct 19 01:46:49 UTC 2007
Author: linville
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv29620
Added Files:
linux-2.6-rt2x00-updates.patch
linux-2.6-wireless-round_jiffies_relative.patch
Log Message:
actually add the patches for rt2x00 2.0.11 and round_jiffies_relative...
linux-2.6-rt2x00-updates.patch:
--- NEW FILE linux-2.6-rt2x00-updates.patch ---
diff -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00.h.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00.h.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00.h 2007-10-18 21:21:51.000000000 -0400
@@ -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"
/*
@@ -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));
}
/*
@@ -180,18 +180,17 @@ struct rf_channel {
};
/*
- * To optimize the quality of the link we need to store
- * the quality of received frames and periodically
- * optimize the link.
+ * Antenna setup values.
*/
-struct link {
- /*
- * Link tuner counter
- * The number of times the link has been tuned
- * since the radio has been switched on.
- */
- u32 count;
+struct antenna_setup {
+ enum antenna rx;
+ enum antenna tx;
+};
+/*
+ * Quality statistics about the currently active link.
+ */
+struct link_qual {
/*
* Statistics required for Link tuning.
* For the average RSSI value we use the "Walking average" approach.
@@ -211,7 +210,6 @@ struct link {
* the new values correctly allowing a effective link tuning.
*/
int avg_rssi;
- int vgc_level;
int false_cca;
/*
@@ -240,6 +238,72 @@ struct link {
#define WEIGHT_RSSI 20
#define WEIGHT_RX 40
#define WEIGHT_TX 40
+};
+
+/*
+ * 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.
+ */
+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;
+
+ /*
+ * TX/RX antenna setup.
+ */
+ struct link_ant ant;
+
+ /*
+ * Active VGC level
+ */
+ int vgc_level;
/*
* Work structure for scheduling periodic link tuning.
@@ -248,36 +312,47 @@ 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.
+ * Small helper macro to work with moving/walking averages.
*/
-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;
-}
+#define MOVING_AVERAGE(__avg, __val, __samples) \
+ ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
/*
- * Update the rssi using the walking average approach.
+ * When we lack RSSI information return something less then -80 to
+ * tell the driver to tune the device to maximum sensitivity.
*/
-static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
-{
- if (!link->avg_rssi)
- link->avg_rssi = rssi;
- else
- link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8;
-}
+#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)
{
- 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 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;
}
/*
@@ -362,6 +437,8 @@ struct rt2x00lib_conf {
struct ieee80211_conf *conf;
struct rf_channel rf;
+ struct antenna_setup ant;
+
int phymode;
int basic_rates;
@@ -402,7 +479,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);
@@ -566,6 +644,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 -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00dev.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00dev.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00dev.c.orig 2007-10-18 20:56:16.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00dev.c 2007-10-18 21:21:51.000000000 -0400
@@ -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.
@@ -179,26 +193,153 @@ void rt2x00lib_toggle_rx(struct rt2x00_d
rt2x00lib_start_link_tuner(rt2x00dev);
}
-static void rt2x00lib_precalculate_link_signal(struct link *link)
+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)
{
- if (link->rx_failed || link->rx_success)
- link->rx_percentage =
- (link->rx_success * 100) /
- (link->rx_failed + link->rx_success);
+ 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)
+ 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 +366,8 @@ static int rt2x00lib_calculate_link_sign
* 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 +387,9 @@ static void rt2x00lib_link_tuner(struct
/*
* 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
@@ -259,10 +399,15 @@ static void rt2x00lib_link_tuner(struct
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.
*/
- 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 +495,8 @@ void rt2x00lib_txdone(struct data_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)
@@ -412,13 +557,15 @@ void rt2x00lib_rxdone(struct data_entry
}
}
- rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
- rt2x00dev->link.rx_success++;
+ 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.ant.active.rx;
/*
* Send frame to mac80211
diff -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2400pci.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2400pci.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2400pci.c.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2400pci.c 2007-10-18 21:21:51.000000000 -0400
@@ -397,7 +397,7 @@ static void rt2400pci_config_txpower(str
}
static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
- int antenna_tx, int antenna_rx)
+ struct antenna_setup *ant)
{
u8 r1;
u8 r4;
@@ -408,14 +408,20 @@ static void rt2400pci_config_antenna(str
/*
* Configure the TX antenna.
*/
- switch (antenna_tx) {
- case ANTENNA_SW_DIVERSITY:
+ switch (ant->tx) {
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;
@@ -424,14 +430,20 @@ static void rt2400pci_config_antenna(str
/*
* Configure the RX antenna.
*/
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
+ switch (ant->rx) {
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;
@@ -485,9 +497,7 @@ static void rt2400pci_config(struct rt2x
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);
}
@@ -514,18 +524,10 @@ static void rt2400pci_enable_led(struct
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);
}
@@ -542,7 +544,8 @@ static void rt2400pci_disable_led(struct
/*
* 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 +554,13 @@ static void rt2400pci_link_stats(struct
* 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 +585,10 @@ static void rt2400pci_link_tuner(struct
*/
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;
}
@@ -1099,12 +1102,12 @@ static void rt2400pci_kick_tx_queue(stru
}
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);
}
@@ -1315,12 +1318,23 @@ static int rt2400pci_init_eeprom(struct
/*
* 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 -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.c.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.c 2007-10-18 21:21:51.000000000 -0400
@@ -385,7 +385,7 @@ static void rt2500usb_config_txpower(str
}
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,8 +400,7 @@ static void rt2500usb_config_antenna(str
/*
* Configure the TX antenna.
*/
- switch (antenna_tx) {
- case ANTENNA_SW_DIVERSITY:
+ switch (ant->tx) {
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(str
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);
@@ -422,14 +428,20 @@ static void rt2500usb_config_antenna(str
/*
* Configure the RX antenna.
*/
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
+ switch (ant->rx) {
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;
@@ -487,9 +499,7 @@ static void rt2500usb_config(struct rt2x
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);
}
@@ -507,18 +517,10 @@ static void rt2500usb_enable_led(struct
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);
}
@@ -535,7 +537,8 @@ static void rt2500usb_disable_led(struct
/*
* 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 +546,13 @@ static void rt2500usb_link_stats(struct
* 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 +675,10 @@ static void rt2500usb_link_tuner(struct
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;
}
@@ -755,9 +757,11 @@ static int rt2500usb_init_registers(stru
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);
@@ -1163,9 +1167,12 @@ static int rt2500usb_validate_eeprom(str
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);
@@ -1275,12 +1282,23 @@ static int rt2500usb_init_eeprom(struct
/*
* 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 -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h 2007-10-18 21:21:51.000000000 -0400
@@ -53,6 +53,8 @@ void rt2x00lib_uninitialize(struct rt2x0
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);
diff -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00config.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00config.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00config.c.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00config.c 2007-10-18 21:21:51.000000000 -0400
@@ -94,12 +94,34 @@ void rt2x00lib_config_type(struct rt2x00
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)
{
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.ant.active;
int flags = 0;
int short_slot_time;
@@ -122,7 +144,39 @@ void rt2x00lib_config(struct rt2x00_dev
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;
+ else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
+ 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;
+ else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
flags |= CONFIG_UPDATE_ANTENNA;
/*
@@ -171,6 +225,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;
@@ -196,10 +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->rx_status.antenna = conf->antenna_sel_rx;
+
+ if (flags & CONFIG_UPDATE_ANTENNA) {
+ rt2x00dev->link.ant.active.rx = libconf.ant.rx;
+ rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+ }
}
diff -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.h.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.h
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.h.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500usb.h 2007-10-18 21:21:51.000000000 -0400
@@ -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 -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500pci.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500pci.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500pci.c.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2500pci.c 2007-10-18 21:21:51.000000000 -0400
@@ -424,7 +424,7 @@ static void rt2500pci_config_txpower(str
}
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,18 +437,20 @@ static void rt2500pci_config_antenna(str
/*
* Configure the TX antenna.
*/
- switch (antenna_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;
+ switch (ant->tx) {
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);
@@ -459,14 +461,18 @@ static void rt2500pci_config_antenna(str
/*
* Configure the RX antenna.
*/
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
- case ANTENNA_HW_DIVERSITY:
- rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
- break;
+ switch (ant->rx) {
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;
@@ -541,9 +547,7 @@ static void rt2500pci_config(struct rt2x
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);
}
@@ -559,18 +563,10 @@ static void rt2500pci_enable_led(struct
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);
}
@@ -587,7 +583,8 @@ static void rt2500pci_disable_led(struct
/*
* 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 +592,13 @@ static void rt2500pci_link_stats(struct
* 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 +676,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;
}
@@ -1239,12 +1236,12 @@ static void rt2500pci_kick_tx_queue(stru
}
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);
}
@@ -1420,9 +1417,12 @@ static int rt2500pci_validate_eeprom(str
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);
@@ -1481,9 +1481,9 @@ static int rt2500pci_init_eeprom(struct
/*
* 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 -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt61pci.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt61pci.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt61pci.c.orig 2007-10-18 20:56:10.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt61pci.c 2007-10-18 21:21:51.000000000 -0400
@@ -411,8 +411,7 @@ static void rt61pci_config_txpower(struc
}
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,12 +424,11 @@ static void rt61pci_config_antenna_5x(st
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
!rt2x00_rf(&rt2x00dev->chip, RF5225));
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
+ 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));
+ (rt2x00dev->curr_hwmode != HWMODE_A));
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
@@ -441,6 +439,13 @@ static void rt61pci_config_antenna_5x(st
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);
@@ -458,8 +463,7 @@ static void rt61pci_config_antenna_5x(st
}
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,8 +478,7 @@ static void rt61pci_config_antenna_2x(st
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
+ switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
@@ -483,6 +486,13 @@ static void rt61pci_config_antenna_2x(st
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);
@@ -514,8 +524,7 @@ static void rt61pci_config_antenna_2529_
}
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 +634,7 @@ static const struct antenna_sel antenna_
};
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;
@@ -637,17 +646,17 @@ static void rt61pci_config_antenna(struc
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]);
@@ -655,16 +664,14 @@ static void rt61pci_config_antenna(struc
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 +716,7 @@ static void rt61pci_config(struct rt2x00
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);
}
@@ -721,7 +727,6 @@ static void rt61pci_config(struct rt2x00
static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- u16 led_reg;
u8 arg0;
u8 arg1;
@@ -730,15 +735,14 @@ static void rt61pci_enable_led(struct rt
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);
}
@@ -792,7 +796,8 @@ static void rt61pci_activity_led(struct
/*
* 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 +805,13 @@ static void rt61pci_link_stats(struct rt
* 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 +908,11 @@ static void rt61pci_link_tuner(struct rt
* 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);
@@ -1649,16 +1653,16 @@ static void rt61pci_kick_tx_queue(struct
}
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);
}
@@ -1908,8 +1912,10 @@ static int rt61pci_validate_eeprom(struc
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);
@@ -2015,9 +2021,9 @@ static int rt61pci_init_eeprom(struct rt
/*
* 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 -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt73usb.c.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt73usb.c
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt73usb.c.orig 2007-10-18 20:56:16.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt73usb.c 2007-10-18 21:21:51.000000000 -0400
@@ -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);
@@ -396,8 +396,7 @@ static void rt73usb_config_txpower(struc
}
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,12 +408,11 @@ static void rt73usb_config_antenna_5x(st
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
+ 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));
+ (rt2x00dev->curr_hwmode != HWMODE_A));
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
@@ -425,6 +423,13 @@ static void rt73usb_config_antenna_5x(st
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);
@@ -442,8 +447,7 @@ static void rt73usb_config_antenna_5x(st
}
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,8 +461,7 @@ static void rt73usb_config_antenna_2x(st
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
- switch (antenna_rx) {
- case ANTENNA_SW_DIVERSITY:
+ switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
@@ -466,6 +469,13 @@ static void rt73usb_config_antenna_2x(st
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);
@@ -509,7 +519,7 @@ static const struct antenna_sel antenna_
};
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;
@@ -521,17 +531,17 @@ static void rt73usb_config_antenna(struc
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]);
@@ -539,10 +549,10 @@ static void rt73usb_config_antenna(struc
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 +596,7 @@ static void rt73usb_config(struct rt2x00
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);
}
@@ -605,12 +614,10 @@ static void rt73usb_enable_led(struct rt
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);
@@ -659,7 +666,8 @@ static void rt73usb_activity_led(struct
/*
* 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 +675,13 @@ static void rt73usb_link_stats(struct rt
* 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 +787,12 @@ static void rt73usb_link_tuner(struct rt
* 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;
@@ -1392,8 +1398,10 @@ static int rt73usb_validate_eeprom(struc
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);
@@ -1502,9 +1510,9 @@ static int rt73usb_init_eeprom(struct rt
/*
* 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);
/*
linux-2.6-wireless-round_jiffies_relative.patch:
--- NEW FILE linux-2.6-wireless-round_jiffies_relative.patch ---
diff -up linux-2.6.23.noarch/drivers/net/wireless/b43/main.c.orig linux-2.6.23.noarch/drivers/net/wireless/b43/main.c
--- linux-2.6.23.noarch/drivers/net/wireless/b43/main.c.orig 2007-10-18 21:25:53.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/b43/main.c 2007-10-18 21:31:31.000000000 -0400
@@ -2391,7 +2391,7 @@ out_requeue:
if (b43_debug(dev, B43_DBG_PWORK_FAST))
delay = msecs_to_jiffies(50);
else
- delay = round_jiffies(HZ * 15);
+ delay = round_jiffies_relative(HZ * 15);
queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
out:
mutex_unlock(&wl->mutex);
diff -up linux-2.6.23.noarch/drivers/net/wireless/b43legacy/main.c.orig linux-2.6.23.noarch/drivers/net/wireless/b43legacy/main.c
--- linux-2.6.23.noarch/drivers/net/wireless/b43legacy/main.c.orig 2007-10-18 21:25:53.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/b43legacy/main.c 2007-10-18 21:31:31.000000000 -0400
@@ -2260,7 +2260,7 @@ out_requeue:
if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST))
delay = msecs_to_jiffies(50);
else
- delay = round_jiffies(HZ);
+ delay = round_jiffies_relative(HZ);
queue_delayed_work(dev->wl->hw->workqueue,
&dev->periodic_work, delay);
out:
diff -up linux-2.6.23.noarch/drivers/net/wireless/ipw2100.c.orig linux-2.6.23.noarch/drivers/net/wireless/ipw2100.c
--- linux-2.6.23.noarch/drivers/net/wireless/ipw2100.c.orig 2007-10-18 21:25:53.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/ipw2100.c 2007-10-18 21:31:31.000000000 -0400
@@ -1769,7 +1769,7 @@ static int ipw2100_up(struct ipw2100_pri
if (priv->stop_rf_kill) {
priv->stop_rf_kill = 0;
queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies(HZ));
+ round_jiffies_relative(HZ));
}
deferred = 1;
@@ -2102,7 +2102,8 @@ static void isr_indicate_rf_kill(struct
/* Make sure the RF Kill check timer is running */
priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill);
- queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
+ queue_delayed_work(priv->workqueue, &priv->rf_kill,
+ round_jiffies_relative(HZ));
}
static void send_scan_event(void *data)
@@ -4271,7 +4272,7 @@ static int ipw_radio_kill_sw(struct ipw2
priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill);
queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies(HZ));
+ round_jiffies_relative(HZ));
} else
schedule_reset(priv);
}
@@ -6010,7 +6011,7 @@ static void ipw2100_rf_kill(struct work_
IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
if (!priv->stop_rf_kill)
queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies(HZ));
+ round_jiffies_relative(HZ));
goto exit_unlock;
}
diff -up linux-2.6.23.noarch/drivers/net/wireless/ipw2200.c.orig linux-2.6.23.noarch/drivers/net/wireless/ipw2200.c
--- linux-2.6.23.noarch/drivers/net/wireless/ipw2200.c.orig 2007-10-18 21:25:45.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/ipw2200.c 2007-10-18 21:31:31.000000000 -0400
@@ -1753,7 +1753,7 @@ static int ipw_radio_kill_sw(struct ipw_
/* Make sure the RF_KILL check timer is running */
cancel_delayed_work(&priv->rf_kill);
queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies(2 * HZ));
+ round_jiffies_relative(2 * HZ));
} else
queue_work(priv->workqueue, &priv->up);
}
@@ -4364,7 +4364,7 @@ static void handle_scan_event(struct ipw
if (!priv->user_requested_scan) {
if (!delayed_work_pending(&priv->scan_event))
queue_delayed_work(priv->workqueue, &priv->scan_event,
- round_jiffies(msecs_to_jiffies(4000)));
+ round_jiffies_relative(msecs_to_jiffies(4000)));
} else {
union iwreq_data wrqu;
@@ -4728,7 +4728,7 @@ static void ipw_rx_notification(struct i
&& priv->status & STATUS_ASSOCIATED)
queue_delayed_work(priv->workqueue,
&priv->request_scan,
- round_jiffies(HZ));
+ round_jiffies_relative(HZ));
/* Send an empty event to user space.
* We don't send the received data on the event because
diff -up linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h.orig linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h
--- linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h.orig 2007-10-18 21:25:53.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/wireless/rt2x00/rt2x00lib.h 2007-10-18 21:31:31.000000000 -0400
@@ -30,7 +30,7 @@
* Interval defines
* Both the link tuner as the rfkill will be called once per second.
*/
-#define LINK_TUNE_INTERVAL ( round_jiffies(HZ) )
+#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
#define RFKILL_POLL_INTERVAL ( 1000 )
/*
More information about the fedora-extras-commits
mailing list