aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rt2x00/rt2x00config.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-02-29 13:41:25 -0800
committerDavid S. Miller <davem@davemloft.net>2008-02-29 13:41:25 -0800
commit4a80f2788952055a627f2093a0174537d70aec1b (patch)
tree411c8ec555fe85cf9faa9da90e62ab781b33661c /drivers/net/wireless/rt2x00/rt2x00config.c
parent03a64c93b68e1eff299b9bbbb0d13105171cddc4 (diff)
parente4861829072c61883114c64a3af61f305a789ff0 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.26
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00config.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c163
1 files changed, 85 insertions, 78 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 07adc576db4..69959124d25 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -29,64 +29,89 @@
#include "rt2x00.h"
#include "rt2x00lib.h"
-
-/*
- * The MAC and BSSID addressess are simple array of bytes,
- * these arrays are little endian, so when sending the addressess
- * to the drivers, copy the it into a endian-signed variable.
- *
- * Note that all devices (except rt2500usb) have 32 bits
- * register word sizes. This means that whatever variable we
- * pass _must_ be a multiple of 32 bits. Otherwise the device
- * might not accept what we are sending to it.
- * This will also make it easier for the driver to write
- * the data to the device.
- *
- * Also note that when NULL is passed as address the
- * we will send 00:00:00:00:00 to the device to clear the address.
- * This will prevent the device being confused when it wants
- * to ACK frames or consideres itself associated.
- */
-void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac)
-{
- __le32 reg[2];
-
- memset(&reg, 0, sizeof(reg));
- if (mac)
- memcpy(&reg, mac, ETH_ALEN);
-
- rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, &reg[0]);
-}
-
-void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
+void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ enum ieee80211_if_types type,
+ u8 *mac, u8 *bssid)
{
- __le32 reg[2];
-
- memset(&reg, 0, sizeof(reg));
- if (bssid)
- memcpy(&reg, bssid, ETH_ALEN);
-
- rt2x00dev->ops->lib->config_bssid(rt2x00dev, &reg[0]);
-}
+ struct rt2x00intf_conf conf;
+ unsigned int flags = 0;
-void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type)
-{
- int tsf_sync;
+ conf.type = type;
switch (type) {
case IEEE80211_IF_TYPE_IBSS:
case IEEE80211_IF_TYPE_AP:
- tsf_sync = TSF_SYNC_BEACON;
+ conf.sync = TSF_SYNC_BEACON;
break;
case IEEE80211_IF_TYPE_STA:
- tsf_sync = TSF_SYNC_INFRA;
+ conf.sync = TSF_SYNC_INFRA;
break;
default:
- tsf_sync = TSF_SYNC_NONE;
+ conf.sync = TSF_SYNC_NONE;
break;
}
- rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync);
+ /*
+ * Note that when NULL is passed as address we will send
+ * 00:00:00:00:00 to the device to clear the address.
+ * This will prevent the device being confused when it wants
+ * to ACK frames or consideres itself associated.
+ */
+ memset(&conf.mac, 0, sizeof(conf.mac));
+ if (mac)
+ memcpy(&conf.mac, mac, ETH_ALEN);
+
+ memset(&conf.bssid, 0, sizeof(conf.bssid));
+ if (bssid)
+ memcpy(&conf.bssid, bssid, ETH_ALEN);
+
+ flags |= CONFIG_UPDATE_TYPE;
+ if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
+ flags |= CONFIG_UPDATE_MAC;
+ if (bssid || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
+ flags |= CONFIG_UPDATE_BSSID;
+
+ rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags);
+}
+
+void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ const unsigned int short_preamble)
+{
+ int retval;
+ int ack_timeout;
+ int ack_consume_time;
+
+ ack_timeout = PLCP + get_duration(ACK_SIZE, 10);
+ ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
+
+ if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME)
+ ack_timeout += SHORT_DIFS;
+ else
+ ack_timeout += DIFS;
+
+ if (short_preamble) {
+ ack_timeout += SHORT_PREAMBLE;
+ ack_consume_time += SHORT_PREAMBLE;
+ } else {
+ ack_timeout += PREAMBLE;
+ ack_consume_time += PREAMBLE;
+ }
+
+ retval = rt2x00dev->ops->lib->config_preamble(rt2x00dev,
+ short_preamble,
+ ack_timeout,
+ ack_consume_time);
+
+ spin_lock(&intf->lock);
+
+ if (retval) {
+ intf->delayed_flags |= DELAYED_CONFIG_PREAMBLE;
+ queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+ }
+
+ spin_unlock(&intf->lock);
}
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
@@ -113,7 +138,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
* 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);
+ rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA);
rt2x00lib_reset_link_tuner(rt2x00dev);
rt2x00dev->link.ant.active.rx = libconf.ant.rx;
@@ -127,7 +152,7 @@ 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_supported_band *band;
struct ieee80211_rate *rate;
struct antenna_setup *default_ant = &rt2x00dev->default_ant;
struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
@@ -147,9 +172,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
* Check which configuration options have been
* updated and should be send to the device.
*/
- if (rt2x00dev->rx_status.phymode != conf->phymode)
+ if (rt2x00dev->rx_status.band != conf->channel->band)
flags |= CONFIG_UPDATE_PHYMODE;
- if (rt2x00dev->rx_status.channel != conf->channel)
+ if (rt2x00dev->rx_status.freq != conf->channel->center_freq)
flags |= CONFIG_UPDATE_CHANNEL;
if (rt2x00dev->tx_power != conf->power_level)
flags |= CONFIG_UPDATE_TXPOWER;
@@ -204,33 +229,16 @@ config:
memset(&libconf, 0, sizeof(libconf));
if (flags & CONFIG_UPDATE_PHYMODE) {
- switch (conf->phymode) {
- case MODE_IEEE80211A:
- libconf.phymode = HWMODE_A;
- break;
- case MODE_IEEE80211B:
- libconf.phymode = HWMODE_B;
- break;
- case MODE_IEEE80211G:
- libconf.phymode = HWMODE_G;
- break;
- default:
- ERROR(rt2x00dev,
- "Attempt to configure unsupported mode (%d)"
- "Defaulting to 802.11b", conf->phymode);
- libconf.phymode = HWMODE_B;
- }
-
- mode = &rt2x00dev->hwmodes[libconf.phymode];
- rate = &mode->rates[mode->num_rates - 1];
-
- libconf.basic_rates =
- DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK;
+ band = &rt2x00dev->bands[conf->channel->band];
+ rate = &band->bitrates[band->n_bitrates - 1];
+
+ libconf.band = conf->channel->band;
+ libconf.basic_rates = rt2x00_get_rate(rate->hw_value)->ratemask;
}
if (flags & CONFIG_UPDATE_CHANNEL) {
memcpy(&libconf.rf,
- &rt2x00dev->spec.channels[conf->channel_val],
+ &rt2x00dev->spec.channels[conf->channel->hw_value],
sizeof(libconf.rf));
}
@@ -266,7 +274,7 @@ config:
/*
* Start configuration.
*/
- rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf);
+ rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags);
/*
* Some configuration changes affect the link quality
@@ -276,12 +284,11 @@ config:
rt2x00lib_reset_link_tuner(rt2x00dev);
if (flags & CONFIG_UPDATE_PHYMODE) {
- rt2x00dev->curr_hwmode = libconf.phymode;
- rt2x00dev->rx_status.phymode = conf->phymode;
+ rt2x00dev->curr_band = conf->channel->band;
+ rt2x00dev->rx_status.band = conf->channel->band;
}
- rt2x00dev->rx_status.freq = conf->freq;
- rt2x00dev->rx_status.channel = conf->channel;
+ rt2x00dev->rx_status.freq = conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level;
if (flags & CONFIG_UPDATE_ANTENNA) {