Skip to contentSkip to conversation

rt2x00: Correctly initialize TX power in registers

PATCH In review Ivo van Doorn 1 participant 1 message Apr 27, 2006

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 30/32 rt2x00: Correctly initialize TX power in registers

From: Ivo van Doorn <[email protected]>

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.

drivers/net/wireless/d80211/rt2x00/rt2400pci.c +57 -26
diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
@@ -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, &reg);
 	if (control->queue == IEEE80211_TX_QUEUE_DATA0)
 		rt2x00_set_field32(&reg, 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, &reg);
+		rt2x00_set_field32(&reg, 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, &reg);
+			rt2x00_set_field32(&reg, 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;
 
drivers/net/wireless/d80211/rt2x00/rt2500pci.c +61 -15

121 lines not on this page · raw message

drivers/net/wireless/d80211/rt2x00/rt2500usb.c +67 -16

135 lines not on this page · raw message