From: Ivo van Doorn <ivdoorn@gmail.com>
To: netdev@vger.kernel.org
Cc: rt2x00-devel@lfcorreia.dyndns.org
Subject: [PATCH 30/32] rt2x00: Correctly initialize TX power in registers
Date: Fri, 28 Apr 2006 00:03:20 +0200 [thread overview]
Message-ID: <200604280003.20622.IvDoorn@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 14733 bytes --]
From: Ivo van Doorn <IvDoorn@gmail.com>
The rate does not need to be configured for each
TX packet. The actual rate for sending is determined
in the PLCP, the rate configuration is only capable
of setting the supported rates, which is dependent
of the physical mode we are in.
When we the configuration function is called,
disable the RX for proper behaviour.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:04:47.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:05:21.000000000 +0200
@@ -660,6 +660,22 @@ rt2400pci_config_rate(struct rt2x00_pci
}
static void
+rt2400pci_config_phymode(struct rt2x00_pci *rt2x00pci, const int phymode)
+{
+ struct ieee80211_rate *rate;
+
+ rate = &rt2x00pci->hw.modes[0].rates[
+ rt2x00pci->hw.modes[0].num_rates - 1];
+
+ rt2400pci_config_rate(rt2x00pci, rate->val2);
+
+ /*
+ * Update physical mode for rx ring.
+ */
+ rt2x00pci->rx_params.phymode = phymode;
+}
+
+static void
rt2400pci_config_mac_address(struct rt2x00_pci *rt2x00pci, void *addr)
{
u32 reg[2] = {0, 0};
@@ -815,11 +831,6 @@ rt2400pci_write_tx_desc(
u16 signal;
u16 service;
- /*
- * Update rate control register.
- */
- rt2400pci_config_rate(rt2x00pci, control->tx_rate);
-
rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 1);
rt2x00_set_field32(&txd->word0, TXD_W0_ACK, !control->no_ack);
@@ -1545,14 +1556,6 @@ rt2400pci_tx(struct net_device *net_dev,
rt2x00_ring_index_inc(ring);
- /*
- * We are going to cheat now, we update the register
- * with the CWmin and CWmax values for the current
- * queue. This is the alternative since we cannot
- * set the CWmin and CWmax per descriptor.
- */
- rt2400pci_config_cw(rt2x00pci, &ring->tx_params);
-
rt2x00_register_read(rt2x00pci, TXCSR0, ®);
if (control->queue == IEEE80211_TX_QUEUE_DATA0)
rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1);
@@ -1769,19 +1772,46 @@ rt2400pci_config_update(void *data)
struct rt2x00_pci *rt2x00pci = data;
struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev);
struct ieee80211_conf *conf = ieee80211_get_hw_conf(net_dev);
+ u32 reg;
+
+ /*
+ * Some configuration changes require the RX to be disabled.
+ */
+ if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) {
+ rt2x00_register_read(rt2x00pci, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00pci, RXCSR0, reg);
+ }
- rt2400pci_config_bssid(rt2x00pci, conf->client_bssid);
- rt2400pci_config_type(rt2x00pci, conf->mode);
rt2400pci_config_channel(rt2x00pci,
conf->channel_val, conf->channel, conf->freq);
rt2400pci_config_txpower(rt2x00pci, conf->power_level);
rt2400pci_config_antenna(rt2x00pci, conf->antenna_sel);
rt2400pci_config_duration(rt2x00pci, conf->short_slot_time);
+ rt2400pci_config_phymode(rt2x00pci, conf->phymode);
/*
- * Update active info for RX.
+ * Reenable RX only if the radio should be on.
*/
- rt2x00pci->rx_params.phymode = conf->phymode;
+ if (conf->radio_enabled) {
+ if (!GET_FLAG(rt2x00pci, RADIO_ENABLED)) {
+ if (rt2400pci_open(net_dev)) {
+ ERROR("Failed to enabled radio.\n");
+ return;
+ }
+ } else {
+ rt2x00_register_read(rt2x00pci, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00pci, RXCSR0, reg);
+ }
+ } else {
+ if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) {
+ if (rt2400pci_stop(net_dev)) {
+ ERROR("Failed to disable radio.\n");
+ return;
+ }
+ }
+ }
}
static int
@@ -1863,8 +1893,8 @@ rt2400pci_scan(void *data)
* Switch channel and update active info for RX.
*/
if (rt2x00pci->scan->state == IEEE80211_SCAN_START) {
- rt2x00pci->rx_params.phymode =
- rt2x00pci->scan->conf.scan_phymode;
+ rt2400pci_config_phymode(rt2x00pci,
+ rt2x00pci->scan->conf.scan_phymode);
rt2400pci_config_channel(rt2x00pci,
rt2x00pci->scan->conf.scan_channel_val,
@@ -1874,8 +1904,8 @@ rt2400pci_scan(void *data)
rt2400pci_config_txpower(rt2x00pci,
rt2x00pci->scan->conf.scan_power_level);
} else {
- rt2x00pci->rx_params.phymode =
- rt2x00pci->scan->conf.running_phymode;
+ rt2400pci_config_phymode(rt2x00pci,
+ rt2x00pci->scan->conf.running_phymode);
rt2400pci_config_channel(rt2x00pci,
rt2x00pci->scan->conf.running_channel_val,
@@ -2000,10 +2030,6 @@ rt2400pci_conf_tx(struct net_device *net
memcpy(&ring->tx_params, params, sizeof(*params));
/*
- * TODO: We can't use different cw_min and cw_max variables
- * per queue, we need to find a good method for dealing with
- * this shortage. Also we need to find a method to possibly
- * support the other values passed in ieee80211_tx_queue_params.
* The passed variables are stored as real value ((2^n)-1).
* RT2400 registers require to know the bit number 'n'.
*/
@@ -2017,6 +2043,11 @@ rt2400pci_conf_tx(struct net_device *net
else
ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */
+ /*
+ * Write configuration to register.
+ */
+ rt2400pci_config_cw(rt2x00pci, &ring->tx_params);
+
return 0;
}
@@ -2330,7 +2361,7 @@ rt2400pci_init_hw(struct rt2x00_pci *rt2
* RF2420 is capable of faster channel switches.
*/
if (rt2x00_rf(&rt2x00pci->chip, RF2420))
- hw->channel_change_time = 100;
+ hw->channel_change_time = 150;
else
hw->channel_change_time = 2500;
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:04:47.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:05:21.000000000 +0200
@@ -703,6 +703,30 @@ rt2500pci_config_rate(struct rt2x00_pci
}
static void
+rt2500pci_config_phymode(struct rt2x00_pci *rt2x00pci, const int phymode)
+{
+ struct ieee80211_rate *rate;
+
+ if (phymode == MODE_IEEE80211A
+ && rt2x00_rf(&rt2x00pci->chip, RF5222))
+ rate = &rt2x00pci->hw.modes[2].rates[
+ rt2x00pci->hw.modes[2].num_rates - 1];
+ else if (phymode == MODE_IEEE80211B)
+ rate = &rt2x00pci->hw.modes[1].rates[
+ rt2x00pci->hw.modes[1].num_rates - 1];
+ else
+ rate = &rt2x00pci->hw.modes[0].rates[
+ rt2x00pci->hw.modes[0].num_rates - 1];
+
+ rt2500pci_config_rate(rt2x00pci, rate->val2);
+
+ /*
+ * Update physical mode for rx ring.
+ */
+ rt2x00pci->rx_params.phymode = phymode;
+}
+
+static void
rt2500pci_config_mac_address(struct rt2x00_pci *rt2x00pci, void *addr)
{
u32 reg[2] = {0, 0};
@@ -870,11 +894,6 @@ rt2500pci_write_tx_desc(
u16 service;
u8 rate;
- /*
- * Update rate control register.
- */
- rt2500pci_config_rate(rt2x00pci, control->tx_rate);
-
rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 1);
rt2x00_set_field32(&txd->word0, TXD_W0_ACK, !control->no_ack);
@@ -1879,19 +1898,46 @@ rt2500pci_config_update(void *data)
struct rt2x00_pci *rt2x00pci = data;
struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev);
struct ieee80211_conf *conf = ieee80211_get_hw_conf(net_dev);
+ u32 reg;
+
+ /*
+ * Some configuration changes require the RX to be disabled.
+ */
+ if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) {
+ rt2x00_register_read(rt2x00pci, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00pci, RXCSR0, reg);
+ }
- rt2500pci_config_bssid(rt2x00pci, conf->client_bssid);
- rt2500pci_config_type(rt2x00pci, conf->mode);
rt2500pci_config_channel(rt2x00pci,
conf->channel_val, conf->channel, conf->freq,
conf->power_level);
rt2500pci_config_antenna(rt2x00pci, conf->antenna_sel);
rt2500pci_config_duration(rt2x00pci, conf->short_slot_time);
+ rt2500pci_config_phymode(rt2x00pci, conf->phymode);
/*
- * Update active info for RX.
+ * Reenable RX only if the radio should be on.
*/
- rt2x00pci->rx_params.phymode = conf->phymode;
+ if (conf->radio_enabled) {
+ if (!GET_FLAG(rt2x00pci, RADIO_ENABLED)) {
+ if (rt2500pci_open(net_dev)) {
+ ERROR("Failed to enabled radio.\n");
+ return;
+ }
+ } else {
+ rt2x00_register_read(rt2x00pci, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00pci, RXCSR0, reg);
+ }
+ } else {
+ if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) {
+ if (rt2500pci_stop(net_dev)) {
+ ERROR("Failed to disable radio.\n");
+ return;
+ }
+ }
+ }
}
static int
@@ -1973,17 +2019,17 @@ rt2500pci_scan(void *data)
* Switch channel and update active info for RX.
*/
if (rt2x00pci->scan->state == IEEE80211_SCAN_START) {
- rt2x00pci->rx_params.phymode =
- rt2x00pci->scan->conf.scan_phymode;
-
+ rt2500pci_config_phymode(rt2x00pci,
+ rt2x00pci->scan->conf.scan_phymode);
+
rt2500pci_config_channel(rt2x00pci,
rt2x00pci->scan->conf.scan_channel_val,
rt2x00pci->scan->conf.scan_channel,
rt2x00pci->scan->conf.scan_freq,
rt2x00pci->scan->conf.scan_power_level);
} else {
- rt2x00pci->rx_params.phymode =
- rt2x00pci->scan->conf.running_phymode;
+ rt2500pci_config_phymode(rt2x00pci,
+ rt2x00pci->scan->conf.running_phymode);
rt2500pci_config_channel(rt2x00pci,
rt2x00pci->scan->conf.running_channel_val,
@@ -2570,7 +2616,7 @@ rt2500pci_init_hw(struct rt2x00_pci *rt2
hw->device_strips_mic = 0;
hw->monitor_during_oper = 1;
hw->fraglist = 0;
- hw->channel_change_time = 2500;
+ hw->channel_change_time = 2000;
/*
* We have 2 TX queues: TX and PRIO.
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
--- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 22:04:47.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 22:05:21.000000000 +0200
@@ -384,6 +384,12 @@ rt2500usb_config_channel(struct rt2x00_u
rt2x00_rf_write(rt2x00usb, rf3);
if (rf4)
rt2x00_rf_write(rt2x00usb, rf4);
+
+ /*
+ * Update active info for RX.
+ */
+ rt2x00usb->rx_params.freq = freq;
+ rt2x00usb->rx_params.channel = channel;
}
static void
@@ -509,9 +515,32 @@ rt2500usb_config_rate(struct rt2x00_usb
}
static void
-rt2500usb_config_mac_address(struct net_device *net_dev, void *addr)
+rt2500usb_config_phymode(struct rt2x00_usb *rt2x00usb, const int phymode)
+{
+ struct ieee80211_rate *rate;
+
+ if (phymode == MODE_IEEE80211A
+ && rt2x00_rf(&rt2x00usb->chip, RF5222))
+ rate = &rt2x00usb->hw.modes[2].rates[
+ rt2x00usb->hw.modes[2].num_rates - 1];
+ else if (phymode == MODE_IEEE80211B)
+ rate = &rt2x00usb->hw.modes[1].rates[
+ rt2x00usb->hw.modes[1].num_rates - 1];
+ else
+ rate = &rt2x00usb->hw.modes[0].rates[
+ rt2x00usb->hw.modes[0].num_rates - 1];
+
+ rt2500usb_config_rate(rt2x00usb, rate->val2);
+
+ /*
+ * Update physical mode for rx ring.
+ */
+ rt2x00usb->rx_params.phymode = phymode;
+}
+
+static void
+rt2500usb_config_mac_address(struct rt2x00_usb *rt2x00usb, void *addr)
{
- struct rt2x00_usb *rt2x00usb = ieee80211_dev_hw_data(net_dev);
u16 reg[3] = {0, 0, 0};
rt2x00_set_field16_nb(®[0], MAC_CSR2_BYTE0, ((u8*)addr)[0]);
@@ -698,11 +727,6 @@ rt2500usb_write_tx_desc(
u8 service;
u8 rate;
- /*
- * Update rate control register.
- */
- rt2500usb_config_rate(rt2x00usb, control->tx_rate);
-
rt2x00_set_field32(&txd->word0, TXD_W0_ACK, !control->no_ack);
ring = rt2x00usb_get_ring(rt2x00usb, control->queue);
@@ -1546,19 +1570,46 @@ rt2500usb_config_update(void *data)
struct net_device *net_dev =
usb_get_intfdata(rt2x00usb->usb_intf);
struct ieee80211_conf *conf = ieee80211_get_hw_conf(net_dev);
+ u16 reg;
+
+ /*
+ * Some configuration changes require the RX to be disabled.
+ */
+ if (GET_FLAG(rt2x00usb, RADIO_ENABLED)) {
+ rt2x00_register_read(rt2x00usb, TXRX_CSR2, ®);
+ rt2x00_set_field16_nb(®, TXRX_CSR2_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00usb, TXRX_CSR2, reg);
+ }
- rt2500usb_config_bssid(rt2x00usb, conf->client_bssid);
- rt2500usb_config_type(rt2x00usb, conf->mode);
rt2500usb_config_channel(rt2x00usb,
conf->channel_val, conf->channel, conf->freq,
conf->power_level);
rt2500usb_config_antenna(rt2x00usb, conf->antenna_sel);
rt2500usb_config_duration(rt2x00usb, conf->short_slot_time);
+ rt2500usb_config_phymode(rt2x00usb, conf->phymode);
/*
- * Update active info for RX.
+ * Reenable RX only if the radio should be on.
*/
- rt2x00usb->rx_params.phymode = conf->phymode;
+ if (conf->radio_enabled) {
+ if (!GET_FLAG(rt2x00usb, RADIO_ENABLED)) {
+ if (rt2500usb_open(net_dev)) {
+ ERROR("Failed to enabled radio.\n");
+ return;
+ }
+ } else {
+ rt2x00_register_read(rt2x00usb, TXRX_CSR2, ®);
+ rt2x00_set_field16_nb(®, TXRX_CSR2_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00usb, TXRX_CSR2, reg);
+ }
+ } else {
+ if (GET_FLAG(rt2x00usb, RADIO_ENABLED)) {
+ if (rt2500usb_stop(net_dev)) {
+ ERROR("Failed to disable radio.\n");
+ return;
+ }
+ }
+ }
}
static int
@@ -1640,8 +1691,8 @@ rt2500usb_scan(void *data)
* Switch channel and update active info for RX.
*/
if (rt2x00usb->scan->state == IEEE80211_SCAN_START) {
- rt2x00usb->rx_params.phymode =
- rt2x00usb->scan->conf.scan_phymode;
+ rt2500usb_config_phymode(rt2x00usb,
+ rt2x00usb->scan->conf.scan_phymode);
rt2500usb_config_channel(rt2x00usb,
rt2x00usb->scan->conf.scan_channel_val,
@@ -1649,8 +1700,8 @@ rt2500usb_scan(void *data)
rt2x00usb->scan->conf.scan_freq,
rt2x00usb->scan->conf.scan_power_level);
} else {
- rt2x00usb->rx_params.phymode =
- rt2x00usb->scan->conf.running_phymode;
+ rt2500usb_config_phymode(rt2x00usb,
+ rt2x00usb->scan->conf.running_phymode);
rt2500usb_config_channel(rt2x00usb,
rt2x00usb->scan->conf.running_channel_val,
@@ -2186,7 +2237,7 @@ rt2500usb_init_hw(struct rt2x00_usb *rt2
hw->device_strips_mic = 0;
hw->monitor_during_oper = 1;
hw->fraglist = 0;
- hw->channel_change_time = 500;
+ hw->channel_change_time = 500000;
/*
* We have 2 TX queues: TX and PRIO.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
reply other threads:[~2006-04-27 22:02 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200604280003.20622.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=rt2x00-devel@lfcorreia.dyndns.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).