From: Ivo van Doorn <ivdoorn@gmail.com>
To: netdev@vger.kernel.org
Cc: linville@tuxdriver.com
Subject: Re: [PATCH 22/24] RT2x00: Optimize config handlers
Date: Wed, 26 Jul 2006 20:31:25 +0200 [thread overview]
Message-ID: <200607262031.25284.IvDoorn@gmail.com> (raw)
In-Reply-To: <200607261905.52685.IvDoorn@gmail.com>
>From Ivo van Doorn <IvDoorn@gmail.com>
Optimize the configuration handlers to only run
when the current configuration has been changed.
This means we need to store the current setting
of most configuration options in rt2x00_dev.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
diff -rU3 wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-07-26 10:55:31.000000000 +0200
+++ wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-07-26 12:49:38.000000000 +0200
@@ -475,6 +475,14 @@
u32 reg;
/*
+ * Only continue when there is something to be done.
+ */
+ if (type == rt2x00dev->interface.type ||
+ (rt2x00dev->interface.monitor_count ^
+ GET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR)))
+ return;
+
+ /*
* Apply hardware packet filter.
*/
rt2x00_register_read(rt2x00dev, RXCSR0, ®);
@@ -520,7 +528,13 @@
/*
* Update working mode.
*/
- rt2x00dev->interface.type = type;
+ if (type != IEEE80211_IF_TYPE_MNTR)
+ rt2x00dev->interface.type = type;
+
+ if (rt2x00dev->interface.monitor_count)
+ SET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
+ else
+ CLEAR_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
}
static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -529,6 +543,12 @@
u32 rf1 = rt2x00dev->rf1;
u32 rf3 = rt2x00dev->rf3;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (channel == rt2x00dev->rx_params.channel)
+ return;
+
INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x.\n",
rf1, rf2, rf3);
@@ -575,15 +595,31 @@
rt2x00dev->rx_params.channel = channel;
/*
+ * Update rf fields
+ */
+ rt2x00dev->rf1 = rf1;
+ rt2x00dev->rf2 = rf2;
+ rt2x00dev->rf3 = rf3;
+
+ /*
* Clear false CRC during channel switch.
*/
rt2x00_register_read(rt2x00dev, CNT0, &rf1);
}
-static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, u8 txpower)
+static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
{
txpower = TXPOWER_TO_DEV(txpower);
+
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (txpower == rt2x00dev->tx_power)
+ return;
+
rt2x00_bbp_write(rt2x00dev, 3, txpower);
+
+ rt2x00dev->tx_power = txpower;
}
static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, int antenna)
@@ -591,6 +627,12 @@
u8 reg_rx;
u8 reg_tx;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.antenna == antenna)
+ return;
+
rt2x00_bbp_read(rt2x00dev, 4, ®_rx);
rt2x00_bbp_read(rt2x00dev, 1, ®_tx);
@@ -713,6 +755,12 @@
{
struct ieee80211_rate *rate;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.phymode == phymode)
+ return;
+
rate = &rt2x00dev->hw.modes[0].rates[
rt2x00dev->hw.modes[0].num_rates - 1];
@@ -1760,6 +1808,9 @@
if (!reg)
return IRQ_NONE;
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return IRQ_HANDLED;
+
/*
* Handle interrupts, walk through all bits
* and run the tasks, the bits are checked in order of
@@ -1982,12 +2033,17 @@
u32 reg;
/*
- * Some configuration changes require the RX to be disabled.
+ * Check if we need to disable the radio,
+ * if this is not the case, at least the RX must be disabled.
*/
if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- rt2x00_register_read(rt2x00dev, RXCSR0, ®);
- rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
- rt2x00_register_write(rt2x00dev, RXCSR0, reg);
+ if (!conf->radio_enabled)
+ rt2400pci_disable_radio(rt2x00dev);
+ else {
+ rt2x00_register_read(rt2x00dev, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00dev, RXCSR0, reg);
+ }
}
rt2400pci_config_channel(rt2x00dev,
@@ -2000,24 +2056,13 @@
/*
* Reenable RX only if the radio should be on.
*/
- if (conf->radio_enabled) {
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt2400pci_open(net_dev)) {
- ERROR("Failed to enabled radio.\n");
- return;
- }
- } else {
- rt2x00_register_read(rt2x00dev, RXCSR0, ®);
- rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
- rt2x00_register_write(rt2x00dev, RXCSR0, reg);
- }
- } else {
- if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt2400pci_stop(net_dev)) {
- ERROR("Failed to disable radio.\n");
- return;
- }
- }
+ if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ rt2x00_register_read(rt2x00dev, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00dev, RXCSR0, reg);
+ } else if (conf->radio_enabled) {
+ if (rt2400pci_enable_radio(rt2x00dev))
+ return;
}
}
@@ -2141,10 +2186,20 @@
{
struct rt2x00_dev *rt2x00dev = ieee80211_dev_hw_data(net_dev);
+ /*
+ * Check if we are not busy with the previous
+ * passive scan request.
+ */
if (rt2x00dev->scan)
return -EBUSY;
/*
+ * Check if the radio is enabled.
+ */
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return -EIO;
+
+ /*
* Allocate scanning structure to store scanning info.
*/
rt2x00dev->scan = kmalloc(sizeof(struct scanning), GFP_ATOMIC);
@@ -2443,6 +2498,9 @@
struct net_device *net_dev = pci_get_drvdata(rt2x00dev_pci(rt2x00dev));
u32 reg[2] = { 0, 0 };
+ if (GET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC))
+ return 0;
+
rt2x00_register_multiread(rt2x00dev, CSR3, ®[0], sizeof(reg));
net_dev->dev_addr[0] = rt2x00_get_field32(reg[0], CSR3_BYTE0);
@@ -2454,6 +2512,10 @@
net_dev->addr_len = 6;
+ if (!is_valid_ether_addr(&net_dev->dev_addr[0]))
+ return -EINVAL;
+
+ SET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC);
return 0;
}
diff -rU3 wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
--- wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-07-26 10:56:10.000000000 +0200
+++ wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-07-26 12:50:25.000000000 +0200
@@ -475,6 +475,14 @@
u32 reg;
/*
+ * Only continue when there is something to be done.
+ */
+ if (type == rt2x00dev->interface.type ||
+ (rt2x00dev->interface.monitor_count ^
+ GET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR)))
+ return;
+
+ /*
* Apply hardware packet filter.
*/
rt2x00_register_read(rt2x00dev, RXCSR0, ®);
@@ -523,7 +531,13 @@
/*
* Update working mode.
*/
- rt2x00dev->interface.type = type;
+ if (type != IEEE80211_IF_TYPE_MNTR)
+ rt2x00dev->interface.type = type;
+
+ if (rt2x00dev->interface.monitor_count)
+ SET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
+ else
+ CLEAR_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
}
static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -533,6 +547,12 @@
u32 rf3 = rt2x00dev->rf3;
u32 rf4 = rt2x00dev->rf4;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (channel == rt2x00dev->rx_params.channel)
+ return;
+
if (txpower == 0xff)
txpower = rt2x00dev->tx_power;
txpower = TXPOWER_TO_DEV(txpower);
@@ -559,14 +579,14 @@
}
}
- INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
- "RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
-
/*
* Set TXpower.
*/
rt2x00_set_field32(&rf3, RF3_TXPOWER, txpower);
+ INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
+ "RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
+
/*
* For RT2525 we should first set the channel to half band higher.
*/
@@ -611,6 +631,16 @@
rt2x00dev->rx_params.channel = channel;
/*
+ * Update rf fields
+ */
+ rt2x00dev->rf1 = rf1;
+ rt2x00dev->rf2 = rf2;
+ rt2x00dev->rf3 = rf3;
+ rt2x00dev->rf4 = rf4;
+
+ rt2x00dev->tx_power = txpower;
+
+ /*
* Clear false CRC during channel switch.
*/
rt2x00_register_read(rt2x00dev, CNT0, &rf1);
@@ -620,8 +650,16 @@
{
txpower = TXPOWER_TO_DEV(txpower);
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (txpower == rt2x00dev->tx_power)
+ return;
+
rt2x00_set_field32(&rt2x00dev->rf3, RF3_TXPOWER, txpower);
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf3);
+
+ rt2x00dev->tx_power = txpower;
}
static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, int antenna)
@@ -630,6 +668,12 @@
u8 reg_rx;
u8 reg_tx;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.antenna == antenna)
+ return;
+
rt2x00_register_read(rt2x00dev, BBPCSR1, ®);
rt2x00_bbp_read(rt2x00dev, 14, ®_rx);
rt2x00_bbp_read(rt2x00dev, 2, ®_tx);
@@ -768,6 +812,12 @@
{
struct ieee80211_rate *rate;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.phymode == phymode)
+ return;
+
if (phymode == MODE_IEEE80211A &&
rt2x00_rf(&rt2x00dev->chip, RF5222))
rate = &rt2x00dev->hw.modes[2].rates[
@@ -1896,6 +1946,9 @@
if (!reg)
return IRQ_NONE;
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return IRQ_HANDLED;
+
/*
* Handle interrupts, walk through all bits
* and run the tasks, the bits are checked in order of
@@ -2117,12 +2170,17 @@
u32 reg;
/*
- * Some configuration changes require the RX to be disabled.
+ * Check if we need to disable the radio,
+ * if this is not the case, at least the RX must be disabled.
*/
if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- rt2x00_register_read(rt2x00dev, RXCSR0, ®);
- rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
- rt2x00_register_write(rt2x00dev, RXCSR0, reg);
+ if (!conf->radio_enabled)
+ rt2500pci_disable_radio(rt2x00dev);
+ else {
+ rt2x00_register_read(rt2x00dev, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00dev, RXCSR0, reg);
+ }
}
rt2500pci_config_channel(rt2x00dev,
@@ -2136,24 +2194,13 @@
/*
* Reenable RX only if the radio should be on.
*/
- if (conf->radio_enabled) {
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt2500pci_open(net_dev)) {
- ERROR("Failed to enabled radio.\n");
- return;
- }
- } else {
- rt2x00_register_read(rt2x00dev, RXCSR0, ®);
- rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
- rt2x00_register_write(rt2x00dev, RXCSR0, reg);
- }
- } else {
- if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt2500pci_stop(net_dev)) {
- ERROR("Failed to disable radio.\n");
- return;
- }
- }
+ if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ rt2x00_register_read(rt2x00dev, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00dev, RXCSR0, reg);
+ } else if (conf->radio_enabled) {
+ if (rt2500pci_enable_radio(rt2x00dev))
+ return;
}
}
@@ -2273,10 +2320,20 @@
{
struct rt2x00_dev *rt2x00dev = ieee80211_dev_hw_data(net_dev);
+ /*
+ * Check if we are not busy with the previous
+ * passive scan request.
+ */
if (rt2x00dev->scan)
return -EBUSY;
/*
+ * Check if the radio is enabled.
+ */
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return -EIO;
+
+ /*
* Allocate scanning structure to store scanning info.
*/
rt2x00dev->scan = kmalloc(sizeof(struct scanning), GFP_ATOMIC);
@@ -2583,6 +2640,9 @@
struct net_device *net_dev = pci_get_drvdata(rt2x00dev_pci(rt2x00dev));
u32 reg[2] = { 0, 0 };
+ if (GET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC))
+ return 0;
+
rt2x00_register_multiread(rt2x00dev, CSR3, ®[0], sizeof(reg));
net_dev->dev_addr[0] = rt2x00_get_field32(reg[0], CSR3_BYTE0);
@@ -2594,6 +2654,10 @@
net_dev->addr_len = 6;
+ if (!is_valid_ether_addr(&net_dev->dev_addr[0]))
+ return -EINVAL;
+
+ SET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC);
return 0;
}
diff -rU3 wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
--- wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-07-26 10:56:11.000000000 +0200
+++ wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-07-26 12:50:28.000000000 +0200
@@ -325,6 +325,14 @@
u16 reg;
/*
+ * Only continue when there is something to be done.
+ */
+ if (type == rt2x00dev->interface.type ||
+ (rt2x00dev->interface.monitor_count ^
+ GET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR)))
+ return;
+
+ /*
* Apply hardware packet filter.
*/
rt2x00_register_read(rt2x00dev, TXRX_CSR2, ®);
@@ -370,7 +378,13 @@
/*
* Update working mode.
*/
- rt2x00dev->interface.type = type;
+ if (type != IEEE80211_IF_TYPE_MNTR)
+ rt2x00dev->interface.type = type;
+
+ if (rt2x00dev->interface.monitor_count)
+ SET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
+ else
+ CLEAR_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
}
static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -380,6 +394,12 @@
u32 rf3 = rt2x00dev->rf3;
u32 rf4 = rt2x00dev->rf4;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (channel == rt2x00dev->rx_params.channel)
+ return;
+
if (txpower == 0xff)
txpower = rt2x00dev->tx_power;
txpower = TXPOWER_TO_DEV(txpower);
@@ -418,11 +438,14 @@
}
}
+ /*
+ * Set TXpower.
+ */
+ rt2x00_set_field32_nb(&rf3, RF3_TXPOWER, txpower);
+
INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
"RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
- rt2x00_set_field32_nb(&rf3, RF3_TXPOWER, txpower);
-
/*
* For RT2525E we should first set the channel to half band higher.
*/
@@ -443,14 +466,34 @@
*/
rt2x00dev->rx_params.freq = freq;
rt2x00dev->rx_params.channel = channel;
+
+ rt2x00dev->tx_power = txpower;
+
+ /*
+ * Update rf fields
+ */
+ rt2x00dev->rf1 = rf1;
+ rt2x00dev->rf2 = rf2;
+ rt2x00dev->rf3 = rf3;
+ rt2x00dev->rf4 = rf4;
+
+ rt2x00dev->tx_power = txpower;
}
static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
{
txpower = TXPOWER_TO_DEV(txpower);
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (txpower == rt2x00dev->tx_power)
+ return;
+
rt2x00_set_field32_nb(&rt2x00dev->rf3, RF3_TXPOWER, txpower);
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf3);
+
+ rt2x00dev->tx_power = txpower;
}
static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, int antenna)
@@ -460,6 +503,12 @@
u16 csr5_reg;
u16 csr6_reg;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.antenna == antenna)
+ return;
+
rt2x00_bbp_read(rt2x00dev, 2, ®_tx);
rt2x00_bbp_read(rt2x00dev, 14, ®_rx);
rt2x00_register_read(rt2x00dev, PHY_CSR5, &csr5_reg);
@@ -578,6 +627,12 @@
{
struct ieee80211_rate *rate;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.phymode == phymode)
+ return;
+
if (phymode == MODE_IEEE80211A &&
rt2x00_rf(&rt2x00dev->chip, RF5222))
rate = &rt2x00dev->hw.modes[2].rates[
@@ -1819,12 +1874,17 @@
u16 reg;
/*
- * Some configuration changes require the RX to be disabled.
+ * Check if we need to disable the radio,
+ * if this is not the case, at least the RX must be disabled.
*/
if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- rt2x00_register_read(rt2x00dev, TXRX_CSR2, ®);
- rt2x00_set_field16_nb(®, TXRX_CSR2_DISABLE_RX, 1);
- rt2x00_register_write(rt2x00dev, TXRX_CSR2, reg);
+ if (!conf->radio_enabled)
+ rt2500usb_disable_radio(rt2x00dev);
+ else {
+ rt2x00_register_read(rt2x00dev, TXRX_CSR2, ®);
+ rt2x00_set_field16_nb(®, TXRX_CSR2_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00dev, TXRX_CSR2, reg);
+ }
}
rt2500usb_config_channel(rt2x00dev,
@@ -1838,24 +1898,13 @@
/*
* Reenable RX only if the radio should be on.
*/
- if (conf->radio_enabled) {
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt2500usb_open(net_dev)) {
- ERROR("Failed to enabled radio.\n");
- return;
- }
- } else {
- rt2x00_register_read(rt2x00dev, TXRX_CSR2, ®);
- rt2x00_set_field16_nb(®, TXRX_CSR2_DISABLE_RX, 0);
- rt2x00_register_write(rt2x00dev, TXRX_CSR2, reg);
- }
- } else {
- if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt2500usb_stop(net_dev)) {
- ERROR("Failed to disable radio.\n");
- return;
- }
- }
+ if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ rt2x00_register_read(rt2x00dev, TXRX_CSR2, ®);
+ rt2x00_set_field16_nb(®, TXRX_CSR2_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00dev, TXRX_CSR2, reg);
+ } else if (conf->radio_enabled) {
+ if (rt2500usb_enable_radio(rt2x00dev))
+ return;
}
}
@@ -1985,10 +2034,20 @@
{
struct rt2x00_dev *rt2x00dev = ieee80211_dev_hw_data(net_dev);
+ /*
+ * Check if we are not busy with the previous
+ * passive scan request.
+ */
if (rt2x00dev->scan)
return -EBUSY;
/*
+ * Check if the radio is enabled.
+ */
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return -EIO;
+
+ /*
* Allocate scanning structure to store scanning info.
*/
rt2x00dev->scan = kmalloc(sizeof(struct scanning), GFP_ATOMIC);
@@ -2241,6 +2300,9 @@
usb_get_intfdata(rt2x00dev_usb(rt2x00dev));
u16 eeprom[3] = { 0, 0, 0 };
+ if (GET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC))
+ return 0;
+
/*
* Read MAC address from EEPROM.
*/
@@ -2261,6 +2323,10 @@
net_dev->addr_len = 6;
+ if (!is_valid_ether_addr(&net_dev->dev_addr[0]))
+ return -EINVAL;
+
+ SET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC);
return 0;
}
diff -rU3 wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt61pci.c wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt61pci.c
--- wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2006-07-26 10:56:17.000000000 +0200
+++ wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2006-07-26 12:50:33.000000000 +0200
@@ -506,6 +506,14 @@
u32 reg;
/*
+ * Only continue when there is something to be done.
+ */
+ if (type == rt2x00dev->interface.type ||
+ (rt2x00dev->interface.monitor_count ^
+ GET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR)))
+ return;
+
+ /*
* Apply hardware packet filter.
*/
rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
@@ -554,7 +562,13 @@
/*
* Update working mode.
*/
- rt2x00dev->interface.type = type;
+ if (type != IEEE80211_IF_TYPE_MNTR)
+ rt2x00dev->interface.type = type;
+
+ if (rt2x00dev->interface.monitor_count)
+ SET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
+ else
+ CLEAR_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
}
static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -565,6 +579,12 @@
u32 rf3 = 0;
u32 rf4 = 0;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (channel == rt2x00dev->rx_params.channel)
+ return;
+
if (txpower == 0xff)
txpower = rt2x00dev->tx_power;
txpower = TXPOWER_TO_DEV(txpower);
@@ -735,14 +755,14 @@
}
}
- INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
- "RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
-
/*
* Set TXpower.
*/
rt2x00_set_field32(&rf3, RF3_TXPOWER, txpower);
+ INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
+ "RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
+
/*
* Set Frequency offset.
*/
@@ -782,12 +802,28 @@
*/
rt2x00dev->rx_params.freq = freq;
rt2x00dev->rx_params.channel = channel;
+
+ rt2x00dev->tx_power = txpower;
+
+ /*
+ * Update rf fields
+ */
+ rt2x00dev->rf1 = rf1;
+ rt2x00dev->rf2 = rf2;
+ rt2x00dev->rf3 = rf3;
+ rt2x00dev->rf4 = rf4;
}
static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
{
txpower = TXPOWER_TO_DEV(txpower);
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (txpower == rt2x00dev->tx_power)
+ return;
+
rt2x00_set_field32(&rt2x00dev->rf3, RF3_TXPOWER, txpower);
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf1);
@@ -808,6 +844,8 @@
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf2);
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf3 & ~cpu_to_le32(0x00000004));
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf4);
+
+ rt2x00dev->tx_power = txpower;
}
static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
@@ -819,6 +857,12 @@
u8 reg_r77;
u8 frame_type;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.antenna == antenna)
+ return;
+
rt2x00_register_read(rt2x00dev, PHY_CSR0, ®);
if (phymode == MODE_IEEE80211A) {
@@ -997,6 +1041,12 @@
{
struct ieee80211_rate *rate;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.phymode == phymode)
+ return;
+
if (phymode == MODE_IEEE80211A &&
(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF5325)))
@@ -2400,6 +2450,9 @@
if (!reg)
return IRQ_NONE;
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return IRQ_HANDLED;
+
/*
* Handle interrupts, walk through all bits
* and run the tasks, the bits are checked in order of
@@ -2632,12 +2685,17 @@
u32 reg;
/*
- * Some configuration changes require the RX to be disabled.
+ * Check if we need to disable the radio,
+ * if this is not the case, at least the RX must be disabled.
*/
if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
- rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1);
- rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
+ if (!conf->radio_enabled)
+ rt61pci_disable_radio(rt2x00dev);
+ else {
+ rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
+ rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
+ }
}
rt61pci_config_channel(rt2x00dev,
@@ -2651,24 +2709,13 @@
/*
* Reenable RX only if the radio should be on.
*/
- if (conf->radio_enabled) {
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt61pci_open(net_dev)) {
- ERROR("Failed to enabled radio.\n");
- return;
- }
- } else {
- rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
- rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0);
- rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
- }
- } else {
- if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt61pci_stop(net_dev)) {
- ERROR("Failed to disable radio.\n");
- return;
- }
- }
+ if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
+ rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
+ } else if (conf->radio_enabled) {
+ if (rt61pci_enable_radio(rt2x00dev))
+ return;
}
}
@@ -2788,10 +2835,20 @@
{
struct rt2x00_dev *rt2x00dev = ieee80211_dev_hw_data(net_dev);
+ /*
+ * Check if we are not busy with the previous
+ * passive scan request.
+ */
if (rt2x00dev->scan)
return -EBUSY;
/*
+ * Check if the radio is enabled.
+ */
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return -EIO;
+
+ /*
* Allocate scanning structure to store scanning info.
*/
rt2x00dev->scan = kmalloc(sizeof(struct scanning), GFP_ATOMIC);
@@ -3143,7 +3200,10 @@
static int rt61pci_init_mac(struct rt2x00_dev *rt2x00dev)
{
struct net_device *net_dev = pci_get_drvdata(rt2x00dev_pci(rt2x00dev));
- u16 eeprom[3];
+ u16 eeprom[3] = { 0, 0, 0 };
+
+ if (GET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC))
+ return 0;
/*
* Read MAC address from EEPROM.
@@ -3165,6 +3225,10 @@
net_dev->addr_len = 6;
+ if (!is_valid_ether_addr(&net_dev->dev_addr[0]))
+ return -EINVAL;
+
+ SET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC);
return 0;
}
diff -rU3 wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt73usb.c wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt73usb.c
--- wireless-dev-control/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2006-07-26 10:56:20.000000000 +0200
+++ wireless-dev-config/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2006-07-26 12:50:39.000000000 +0200
@@ -327,6 +327,14 @@
u32 reg;
/*
+ * Only continue when there is something to be done.
+ */
+ if (type == rt2x00dev->interface.type ||
+ (rt2x00dev->interface.monitor_count ^
+ GET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR)))
+ return;
+
+ /*
* Apply hardware packet filter.
*/
rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
@@ -375,7 +383,13 @@
/*
* Update working mode.
*/
- rt2x00dev->interface.type = type;
+ if (type != IEEE80211_IF_TYPE_MNTR)
+ rt2x00dev->interface.type = type;
+
+ if (rt2x00dev->interface.monitor_count)
+ SET_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
+ else
+ CLEAR_FLAG(rt2x00dev, INTERFACE_ENABLED_MONITOR);
}
static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -386,6 +400,12 @@
u32 rf3 = rt2x00dev->rf3;
u32 rf4 = 0;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (channel == rt2x00dev->rx_params.channel)
+ return;
+
if (txpower == 0xff)
txpower = rt2x00dev->tx_power;
txpower = TXPOWER_TO_DEV(txpower);
@@ -463,14 +483,14 @@
rt2x00_rf(&rt2x00dev->chip, RF5225))
rf4 |= 0x00010000;
- INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
- "RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
-
/*
* Set TXpower.
*/
rt2x00_set_field32(&rf3, RF3_TXPOWER, txpower);
+ INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, "
+ "RF4: 0x%08x.\n", rf1, rf2, rf3, rf4);
+
/*
* Set Frequency offset.
*/
@@ -506,12 +526,30 @@
*/
rt2x00dev->rx_params.freq = freq;
rt2x00dev->rx_params.channel = channel;
+
+ rt2x00dev->tx_power = txpower;
+
+ /*
+ * Update rf fields
+ */
+ rt2x00dev->rf1 = rf1;
+ rt2x00dev->rf2 = rf2;
+ rt2x00dev->rf3 = rf3;
+ rt2x00dev->rf4 = rf4;
+
+ rt2x00dev->tx_power = txpower;
}
static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
{
txpower = TXPOWER_TO_DEV(txpower);
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (txpower == rt2x00dev->tx_power)
+ return;
+
rt2x00_set_field32(&rt2x00dev->rf3, RF3_TXPOWER, txpower);
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf1);
@@ -528,6 +566,8 @@
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf2);
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf3 & ~cpu_to_le32(0x00000004));
rt2x00_rf_write(rt2x00dev, rt2x00dev->rf4);
+
+ rt2x00dev->tx_power = txpower;
}
static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
@@ -539,6 +579,12 @@
u8 reg_r77;
u8 frame_type;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.antenna == antenna)
+ return;
+
rt2x00_register_read(rt2x00dev, PHY_CSR0, ®);
if (phymode == MODE_IEEE80211A) {
@@ -711,6 +757,12 @@
{
struct ieee80211_rate *rate;
+ /*
+ * Only continue when there is something to be done.
+ */
+ if (rt2x00dev->rx_params.phymode == phymode)
+ return;
+
if (phymode == MODE_IEEE80211A &&
(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF5226)))
@@ -2133,12 +2185,17 @@
u32 reg;
/*
- * Some configuration changes require the RX to be disabled.
+ * Check if we need to disable the radio,
+ * if this is not the case, at least the RX must be disabled.
*/
if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
- rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1);
- rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
+ if (!conf->radio_enabled)
+ rt73usb_disable_radio(rt2x00dev);
+ else {
+ rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
+ rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1);
+ rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
+ }
}
rt73usb_config_channel(rt2x00dev,
@@ -2150,29 +2207,15 @@
rt73usb_config_phymode(rt2x00dev, conf->phymode);
/*
- * Reenable RX.
- */
- /*
* Reenable RX only if the radio should be on.
*/
- if (conf->radio_enabled) {
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt73usb_open(net_dev)) {
- ERROR("Failed to enabled radio.\n");
- return;
- }
- } else {
- rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
- rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0);
- rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
- }
- } else {
- if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
- if (rt73usb_stop(net_dev)) {
- ERROR("Failed to disable radio.\n");
- return;
- }
- }
+ if (GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ rt2x00_register_read(rt2x00dev, TXRX_CSR0, ®);
+ rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0);
+ rt2x00_register_write(rt2x00dev, TXRX_CSR0, reg);
+ } else if (conf->radio_enabled) {
+ if (rt73usb_enable_radio(rt2x00dev))
+ return;
}
}
@@ -2302,10 +2345,20 @@
{
struct rt2x00_dev *rt2x00dev = ieee80211_dev_hw_data(net_dev);
+ /*
+ * Check if we are not busy with the previous
+ * passive scan request.
+ */
if (rt2x00dev->scan)
return -EBUSY;
/*
+ * Check if the radio is enabled.
+ */
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ return -EIO;
+
+ /*
* Allocate scanning structure to store scanning info.
*/
rt2x00dev->scan = kmalloc(sizeof(struct scanning), GFP_ATOMIC);
@@ -2640,6 +2693,9 @@
usb_get_intfdata(rt2x00dev_usb(rt2x00dev));
u16 eeprom[3] = { 0, 0, 0 };
+ if (GET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC))
+ return 0;
+
/*
* Read MAC address from EEPROM.
*/
@@ -2660,6 +2716,10 @@
net_dev->addr_len = 6;
+ if (!is_valid_ether_addr(&net_dev->dev_addr[0]))
+ return -EINVAL;
+
+ SET_FLAG(rt2x00dev, DEVICE_INITIALIZED_MAC);
return 0;
}
prev parent reply other threads:[~2006-07-26 18:31 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-26 17:05 [PATCH 22/24] RT2x00: Optimize config handlers Ivo van Doorn
2006-07-26 18:31 ` Ivo van Doorn [this message]
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=200607262031.25284.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=linville@tuxdriver.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.