Commit e4ea1c40 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville

rt2x00: Optimize configuration handling

Implement latest changed from mac80211 configuration
handling to optmize configuration handling in rt2x00.

 * Remove set_retry_limit callback function, handled
   through config()
 * Move config_antenna to its own callback function,
   it isn't handled by mac80211 anymore
 * Use IEEE80211_CONF_CHANGED_* flags and remove manual
   checks
 * Removed deprecated short slot setting through config()
   and put it in config_erp() through which mac80211 now
   configures it
 * Remove config_phymode() and move contents to config_erp()
   since it only managed the basic rates which is now
   determined by mac80211 through config_erp().
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3f64b435
...@@ -396,12 +396,74 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -396,12 +396,74 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
rt2x00pci_register_write(rt2x00dev, CSR18, reg);
rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
rt2x00pci_register_write(rt2x00dev, CSR19, reg);
} }
static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,
const int basic_rate_mask) struct antenna_setup *ant)
{ {
rt2x00pci_register_write(rt2x00dev, ARCSR1, basic_rate_mask); u8 r1;
u8 r4;
/*
* We should never come here because rt2x00lib is supposed
* to catch this and send us the correct antenna explicitely.
*/
BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
ant->tx == ANTENNA_SW_DIVERSITY);
rt2400pci_bbp_read(rt2x00dev, 4, &r4);
rt2400pci_bbp_read(rt2x00dev, 1, &r1);
/*
* Configure the TX antenna.
*/
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_B:
default:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
break;
}
/*
* Configure the RX antenna.
*/
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_B:
default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
}
rt2400pci_bbp_write(rt2x00dev, 4, r4);
rt2400pci_bbp_write(rt2x00dev, 1, r1);
} }
static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev,
...@@ -460,56 +522,17 @@ static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower) ...@@ -460,56 +522,17 @@ static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
rt2400pci_bbp_write(rt2x00dev, 3, TXPOWER_TO_DEV(txpower)); rt2400pci_bbp_write(rt2x00dev, 3, TXPOWER_TO_DEV(txpower));
} }
static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant) struct rt2x00lib_conf *libconf)
{ {
u8 r1; u32 reg;
u8 r4;
/*
* We should never come here because rt2x00lib is supposed
* to catch this and send us the correct antenna explicitely.
*/
BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
ant->tx == ANTENNA_SW_DIVERSITY);
rt2400pci_bbp_read(rt2x00dev, 4, &r4);
rt2400pci_bbp_read(rt2x00dev, 1, &r1);
/*
* Configure the TX antenna.
*/
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_B:
default:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
break;
}
/*
* Configure the RX antenna.
*/
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_B:
default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
}
rt2400pci_bbp_write(rt2x00dev, 4, r4); rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2400pci_bbp_write(rt2x00dev, 1, r1); rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
libconf->conf->long_frame_max_tx_count);
rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
libconf->conf->short_frame_max_tx_count);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
} }
static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
...@@ -517,20 +540,6 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, ...@@ -517,20 +540,6 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
{ {
u32 reg; u32 reg;
rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2x00_set_field32(&reg, CSR11_SLOT_TIME, libconf->slot_time);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
rt2x00_set_field32(&reg, CSR18_SIFS, libconf->sifs);
rt2x00_set_field32(&reg, CSR18_PIFS, libconf->pifs);
rt2x00pci_register_write(rt2x00dev, CSR18, reg);
rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
rt2x00_set_field32(&reg, CSR19_DIFS, libconf->difs);
rt2x00_set_field32(&reg, CSR19_EIFS, libconf->eifs);
rt2x00pci_register_write(rt2x00dev, CSR19, reg);
rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg); rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1); rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
...@@ -548,16 +557,14 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, ...@@ -548,16 +557,14 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf, struct rt2x00lib_conf *libconf,
const unsigned int flags) const unsigned int flags)
{ {
if (flags & CONFIG_UPDATE_PHYMODE) if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates);
if (flags & CONFIG_UPDATE_CHANNEL)
rt2400pci_config_channel(rt2x00dev, &libconf->rf); rt2400pci_config_channel(rt2x00dev, &libconf->rf);
if (flags & CONFIG_UPDATE_TXPOWER) if (flags & IEEE80211_CONF_CHANGE_POWER)
rt2400pci_config_txpower(rt2x00dev, rt2400pci_config_txpower(rt2x00dev,
libconf->conf->power_level); libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA) if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2400pci_config_antenna(rt2x00dev, &libconf->ant); rt2400pci_config_retry_limit(rt2x00dev, libconf);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt2400pci_config_duration(rt2x00dev, libconf); rt2400pci_config_duration(rt2x00dev, libconf);
} }
...@@ -1502,20 +1509,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1502,20 +1509,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * IEEE80211 stack callback functions.
*/ */
static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u32 reg;
rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2x00_set_field32(&reg, CSR11_LONG_RETRY, long_retry);
rt2x00_set_field32(&reg, CSR11_SHORT_RETRY, short_retry);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
return 0;
}
static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue, static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params) const struct ieee80211_tx_queue_params *params)
{ {
...@@ -1601,8 +1594,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { ...@@ -1601,8 +1594,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.config_filter = rt2400pci_config_filter, .config_filter = rt2400pci_config_filter,
.config_intf = rt2400pci_config_intf, .config_intf = rt2400pci_config_intf,
.config_erp = rt2400pci_config_erp, .config_erp = rt2400pci_config_erp,
.config_ant = rt2400pci_config_ant,
.config = rt2400pci_config, .config = rt2400pci_config,
.set_retry_limit = rt2400pci_set_retry_limit,
}; };
static const struct data_queue_desc rt2400pci_queue_rx = { static const struct data_queue_desc rt2400pci_queue_rx = {
......
...@@ -402,12 +402,94 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -402,12 +402,94 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
rt2x00pci_register_write(rt2x00dev, CSR18, reg);
rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
rt2x00pci_register_write(rt2x00dev, CSR19, reg);
} }
static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
const int basic_rate_mask) struct antenna_setup *ant)
{ {
rt2x00pci_register_write(rt2x00dev, ARCSR1, basic_rate_mask); u32 reg;
u8 r14;
u8 r2;
/*
* We should never come here because rt2x00lib is supposed
* to catch this and send us the correct antenna explicitely.
*/
BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
ant->tx == ANTENNA_SW_DIVERSITY);
rt2x00pci_register_read(rt2x00dev, BBPCSR1, &reg);
rt2500pci_bbp_read(rt2x00dev, 14, &r14);
rt2500pci_bbp_read(rt2x00dev, 2, &r2);
/*
* Configure the TX antenna.
*/
switch (ant->tx) {
case ANTENNA_A:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
break;
case ANTENNA_B:
default:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
break;
}
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_A:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
break;
case ANTENNA_B:
default:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
break;
}
/*
* RT2525E and RT5222 need to flip TX I/Q
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2525E) ||
rt2x00_rf(&rt2x00dev->chip, RF5222)) {
rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
/*
* RT2525E does not need RX I/Q Flip.
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2525E))
rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
} else {
rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 0);
}
rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg);
rt2500pci_bbp_write(rt2x00dev, 14, r14);
rt2500pci_bbp_write(rt2x00dev, 2, r2);
} }
static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
...@@ -489,76 +571,17 @@ static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev, ...@@ -489,76 +571,17 @@ static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev,
rt2500pci_rf_write(rt2x00dev, 3, rf3); rt2500pci_rf_write(rt2x00dev, 3, rf3);
} }
static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant) struct rt2x00lib_conf *libconf)
{ {
u32 reg; u32 reg;
u8 r14;
u8 r2;
/* rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
* We should never come here because rt2x00lib is supposed rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
* to catch this and send us the correct antenna explicitely. libconf->conf->long_frame_max_tx_count);
*/ rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || libconf->conf->short_frame_max_tx_count);
ant->tx == ANTENNA_SW_DIVERSITY); rt2x00pci_register_write(rt2x00dev, CSR11, reg);
rt2x00pci_register_read(rt2x00dev, BBPCSR1, &reg);
rt2500pci_bbp_read(rt2x00dev, 14, &r14);
rt2500pci_bbp_read(rt2x00dev, 2, &r2);
/*
* Configure the TX antenna.
*/
switch (ant->tx) {
case ANTENNA_A:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
break;
case ANTENNA_B:
default:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
break;
}
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_A:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
break;
case ANTENNA_B:
default:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
break;
}
/*
* RT2525E and RT5222 need to flip TX I/Q
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2525E) ||
rt2x00_rf(&rt2x00dev->chip, RF5222)) {
rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
/*
* RT2525E does not need RX I/Q Flip.
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2525E))
rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
} else {
rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 0);
}
rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg);
rt2500pci_bbp_write(rt2x00dev, 14, r14);
rt2500pci_bbp_write(rt2x00dev, 2, r2);
} }
static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
...@@ -566,20 +589,6 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, ...@@ -566,20 +589,6 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
{ {
u32 reg; u32 reg;
rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2x00_set_field32(&reg, CSR11_SLOT_TIME, libconf->slot_time);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
rt2x00_set_field32(&reg, CSR18_SIFS, libconf->sifs);
rt2x00_set_field32(&reg, CSR18_PIFS, libconf->pifs);
rt2x00pci_register_write(rt2x00dev, CSR18, reg);
rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
rt2x00_set_field32(&reg, CSR19_DIFS, libconf->difs);
rt2x00_set_field32(&reg, CSR19_EIFS, libconf->eifs);
rt2x00pci_register_write(rt2x00dev, CSR19, reg);
rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg); rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1); rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
...@@ -597,17 +606,16 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, ...@@ -597,17 +606,16 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf, struct rt2x00lib_conf *libconf,
const unsigned int flags) const unsigned int flags)
{ {
if (flags & CONFIG_UPDATE_PHYMODE) if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates);
if (flags & CONFIG_UPDATE_CHANNEL)
rt2500pci_config_channel(rt2x00dev, &libconf->rf, rt2500pci_config_channel(rt2x00dev, &libconf->rf,
libconf->conf->power_level); libconf->conf->power_level);
if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
!(flags & IEEE80211_CONF_CHANGE_CHANNEL))
rt2500pci_config_txpower(rt2x00dev, rt2500pci_config_txpower(rt2x00dev,
libconf->conf->power_level); libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA) if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2500pci_config_antenna(rt2x00dev, &libconf->ant); rt2500pci_config_retry_limit(rt2x00dev, libconf);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt2500pci_config_duration(rt2x00dev, libconf); rt2500pci_config_duration(rt2x00dev, libconf);
} }
...@@ -1827,20 +1835,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1827,20 +1835,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * IEEE80211 stack callback functions.
*/ */
static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u32 reg;
rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
rt2x00_set_field32(&reg, CSR11_LONG_RETRY, long_retry);
rt2x00_set_field32(&reg, CSR11_SHORT_RETRY, short_retry);
rt2x00pci_register_write(rt2x00dev, CSR11, reg);
return 0;
}
static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw)
{ {
struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_dev *rt2x00dev = hw->priv;
...@@ -1901,8 +1895,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { ...@@ -1901,8 +1895,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.config_filter = rt2500pci_config_filter, .config_filter = rt2500pci_config_filter,
.config_intf = rt2500pci_config_intf, .config_intf = rt2500pci_config_intf,
.config_erp = rt2500pci_config_erp, .config_erp = rt2500pci_config_erp,
.config_ant = rt2500pci_config_ant,
.config = rt2500pci_config, .config = rt2500pci_config,
.set_retry_limit = rt2500pci_set_retry_limit,
}; };
static const struct data_queue_desc rt2500pci_queue_rx = { static const struct data_queue_desc rt2500pci_queue_rx = {
......
...@@ -423,57 +423,16 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -423,57 +423,16 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE, rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
!!erp->short_preamble); !!erp->short_preamble);
rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
}
static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev,
const int basic_rate_mask)
{
rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask);
}
static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
/*
* Set TXpower.
*/
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
/*
* For RT2525E we should first set the channel to half band higher.
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
static const u32 vals[] = {
0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2,
0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba,
0x000008ba, 0x000008be, 0x000008b7, 0x00000902,
0x00000902, 0x00000906
};
rt2500usb_rf_write(rt2x00dev, 2, vals[rf->channel - 1]); rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates);
if (rf->rf4)
rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
}
rt2500usb_rf_write(rt2x00dev, 1, rf->rf1); rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
rt2500usb_rf_write(rt2x00dev, 2, rf->rf2); rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
rt2500usb_rf_write(rt2x00dev, 3, rf->rf3); rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
if (rf->rf4)
rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
}
static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
const int txpower)
{
u32 rf3;
rt2x00_rf_read(rt2x00dev, 3, &rf3);
rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2500usb_rf_write(rt2x00dev, 3, rf3);
} }
static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant) struct antenna_setup *ant)
{ {
u8 r2; u8 r2;
u8 r14; u8 r14;
...@@ -555,15 +514,52 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -555,15 +514,52 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write(rt2x00dev, PHY_CSR6, csr6); rt2500usb_register_write(rt2x00dev, PHY_CSR6, csr6);
} }
static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
/*
* Set TXpower.
*/
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
/*
* For RT2525E we should first set the channel to half band higher.
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
static const u32 vals[] = {
0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2,
0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba,
0x000008ba, 0x000008be, 0x000008b7, 0x00000902,
0x00000902, 0x00000906
};
rt2500usb_rf_write(rt2x00dev, 2, vals[rf->channel - 1]);
if (rf->rf4)
rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
}
rt2500usb_rf_write(rt2x00dev, 1, rf->rf1);
rt2500usb_rf_write(rt2x00dev, 2, rf->rf2);
rt2500usb_rf_write(rt2x00dev, 3, rf->rf3);
if (rf->rf4)
rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
}
static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
const int txpower)
{
u32 rf3;
rt2x00_rf_read(rt2x00dev, 3, &rf3);
rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2500usb_rf_write(rt2x00dev, 3, rf3);
}
static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf) struct rt2x00lib_conf *libconf)
{ {
u16 reg; u16 reg;
rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time);
rt2500usb_register_write(rt2x00dev, MAC_CSR11, libconf->sifs);
rt2500usb_register_write(rt2x00dev, MAC_CSR12, libconf->eifs);
rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg); rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL, rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL,
libconf->conf->beacon_int * 4); libconf->conf->beacon_int * 4);
...@@ -574,17 +570,14 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, ...@@ -574,17 +570,14 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf, struct rt2x00lib_conf *libconf,
const unsigned int flags) const unsigned int flags)
{ {
if (flags & CONFIG_UPDATE_PHYMODE) if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt2500usb_config_phymode(rt2x00dev, libconf->basic_rates);
if (flags & CONFIG_UPDATE_CHANNEL)
rt2500usb_config_channel(rt2x00dev, &libconf->rf, rt2500usb_config_channel(rt2x00dev, &libconf->rf,
libconf->conf->power_level); libconf->conf->power_level);
if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
!(flags & IEEE80211_CONF_CHANGE_CHANNEL))
rt2500usb_config_txpower(rt2x00dev, rt2500usb_config_txpower(rt2x00dev,
libconf->conf->power_level); libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA) if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt2500usb_config_antenna(rt2x00dev, &libconf->ant);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
rt2500usb_config_duration(rt2x00dev, libconf); rt2500usb_config_duration(rt2x00dev, libconf);
} }
...@@ -1794,6 +1787,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { ...@@ -1794,6 +1787,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.config_filter = rt2500usb_config_filter, .config_filter = rt2500usb_config_filter,
.config_intf = rt2500usb_config_intf, .config_intf = rt2500usb_config_intf,
.config_erp = rt2500usb_config_erp, .config_erp = rt2500usb_config_erp,
.config_ant = rt2500usb_config_ant,
.config = rt2500usb_config, .config = rt2500usb_config,
}; };
......
...@@ -433,18 +433,6 @@ struct rt2x00lib_conf { ...@@ -433,18 +433,6 @@ struct rt2x00lib_conf {
struct rf_channel rf; struct rf_channel rf;
struct channel_info channel; struct channel_info channel;
struct antenna_setup ant;
enum ieee80211_band band;
u32 basic_rates;
u32 slot_time;
short sifs;
short pifs;
short difs;
short eifs;
}; };
/* /*
...@@ -456,6 +444,15 @@ struct rt2x00lib_erp { ...@@ -456,6 +444,15 @@ struct rt2x00lib_erp {
int ack_timeout; int ack_timeout;
int ack_consume_time; int ack_consume_time;
u64 basic_rates;
int slot_time;
short sifs;
short pifs;
short difs;
short eifs;
}; };
/* /*
...@@ -589,19 +586,11 @@ struct rt2x00lib_ops { ...@@ -589,19 +586,11 @@ struct rt2x00lib_ops {
void (*config_erp) (struct rt2x00_dev *rt2x00dev, void (*config_erp) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp); struct rt2x00lib_erp *erp);
void (*config_ant) (struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant);
void (*config) (struct rt2x00_dev *rt2x00dev, void (*config) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf, struct rt2x00lib_conf *libconf,
const unsigned int flags); const unsigned int changed_flags);
#define CONFIG_UPDATE_PHYMODE ( 1 << 1 )
#define CONFIG_UPDATE_CHANNEL ( 1 << 2 )
#define CONFIG_UPDATE_TXPOWER ( 1 << 3 )
#define CONFIG_UPDATE_ANTENNA ( 1 << 4 )
#define CONFIG_UPDATE_SLOT_TIME ( 1 << 5 )
#define CONFIG_UPDATE_BEACON_INT ( 1 << 6 )
#define CONFIG_UPDATE_ALL 0xffff
int (*set_retry_limit) (struct ieee80211_hw *hw,
u32 short_limit, u32 long_limit);
}; };
/* /*
......
...@@ -86,13 +86,14 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -86,13 +86,14 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
erp.short_preamble = bss_conf->use_short_preamble; erp.short_preamble = bss_conf->use_short_preamble;
erp.cts_protection = bss_conf->use_cts_prot; erp.cts_protection = bss_conf->use_cts_prot;
erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10); erp.slot_time = bss_conf->use_short_slot ? SHORT_SLOT_TIME : SLOT_TIME;
erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); erp.sifs = SIFS;
erp.pifs = bss_conf->use_short_slot ? SHORT_PIFS : PIFS;
erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10);
erp.ack_timeout += SHORT_DIFS; erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
else
erp.ack_timeout += DIFS;
if (bss_conf->use_short_preamble) { if (bss_conf->use_short_preamble) {
erp.ack_timeout += SHORT_PREAMBLE; erp.ack_timeout += SHORT_PREAMBLE;
...@@ -102,16 +103,18 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -102,16 +103,18 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
erp.ack_consume_time += PREAMBLE; erp.ack_consume_time += PREAMBLE;
} }
erp.basic_rates = bss_conf->basic_rates;
rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
} }
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
enum antenna rx, enum antenna tx) enum antenna rx, enum antenna tx)
{ {
struct rt2x00lib_conf libconf; struct antenna_setup ant;
libconf.ant.rx = rx; ant.rx = rx;
libconf.ant.tx = tx; ant.tx = tx;
if (rx == rt2x00dev->link.ant.active.rx && if (rx == rt2x00dev->link.ant.active.rx &&
tx == rt2x00dev->link.ant.active.tx) tx == rt2x00dev->link.ant.active.tx)
...@@ -129,111 +132,28 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -129,111 +132,28 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
* The latter is required since we need to recalibrate the * The latter is required since we need to recalibrate the
* noise-sensitivity ratio for the new setup. * noise-sensitivity ratio for the new setup.
*/ */
rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant);
rt2x00lib_reset_link_tuner(rt2x00dev); rt2x00lib_reset_link_tuner(rt2x00dev);
rt2x00_reset_link_ant_rssi(&rt2x00dev->link); rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
rt2x00dev->link.ant.active.rx = libconf.ant.rx; memcpy(&rt2x00dev->link.ant.active, &ant, sizeof(ant));
rt2x00dev->link.ant.active.tx = libconf.ant.tx;
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
} }
static u32 rt2x00lib_get_basic_rates(struct ieee80211_supported_band *band)
{
const struct rt2x00_rate *rate;
unsigned int i;
u32 mask = 0;
for (i = 0; i < band->n_bitrates; i++) {
rate = rt2x00_get_rate(band->bitrates[i].hw_value);
if (rate->flags & DEV_RATE_BASIC)
mask |= rate->ratemask;
}
return mask;
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config) struct ieee80211_conf *conf,
unsigned int ieee80211_flags)
{ {
struct rt2x00lib_conf libconf; struct rt2x00lib_conf libconf;
struct ieee80211_supported_band *band;
struct antenna_setup *default_ant = &rt2x00dev->default_ant;
struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
int flags = 0;
int short_slot_time;
/*
* In some situations we want to force all configurations
* to be reloaded (When resuming for instance).
*/
if (force_config) {
flags = CONFIG_UPDATE_ALL;
goto config;
}
/*
* Check which configuration options have been
* updated and should be send to the device.
*/
if (rt2x00dev->rx_status.band != conf->channel->band)
flags |= CONFIG_UPDATE_PHYMODE;
if (rt2x00dev->rx_status.freq != conf->channel->center_freq)
flags |= CONFIG_UPDATE_CHANNEL;
if (rt2x00dev->tx_power != conf->power_level)
flags |= CONFIG_UPDATE_TXPOWER;
/*
* 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 (default_ant->rx != ANTENNA_SW_DIVERSITY &&
default_ant->rx != active_ant->rx)
flags |= CONFIG_UPDATE_ANTENNA;
else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
flags |= CONFIG_UPDATE_ANTENNA;
if (default_ant->tx != ANTENNA_SW_DIVERSITY &&
default_ant->tx != active_ant->tx)
flags |= CONFIG_UPDATE_ANTENNA;
else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
flags |= CONFIG_UPDATE_ANTENNA;
/*
* The following configuration options are never
* stored anywhere and will always be updated.
*/
flags |= CONFIG_UPDATE_SLOT_TIME;
flags |= CONFIG_UPDATE_BEACON_INT;
/*
* We have determined what options should be updated,
* now precalculate device configuration values depending
* on what configuration options need to be updated.
*/
config:
memset(&libconf, 0, sizeof(libconf)); memset(&libconf, 0, sizeof(libconf));
if (flags & CONFIG_UPDATE_PHYMODE) { libconf.conf = conf;
band = &rt2x00dev->bands[conf->channel->band];
libconf.band = conf->channel->band;
libconf.basic_rates = rt2x00lib_get_basic_rates(band);
}
if (flags & CONFIG_UPDATE_CHANNEL) { if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
memcpy(&libconf.rf, memcpy(&libconf.rf,
&rt2x00dev->spec.channels[conf->channel->hw_value], &rt2x00dev->spec.channels[conf->channel->hw_value],
sizeof(libconf.rf)); sizeof(libconf.rf));
...@@ -243,57 +163,21 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, ...@@ -243,57 +163,21 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
sizeof(libconf.channel)); sizeof(libconf.channel));
} }
if (flags & CONFIG_UPDATE_ANTENNA) {
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;
else
libconf.ant.rx = active_ant->rx;
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;
else
libconf.ant.tx = active_ant->tx;
}
if (flags & CONFIG_UPDATE_SLOT_TIME) {
short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME;
libconf.slot_time =
short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME;
libconf.sifs = SIFS;
libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS;
libconf.difs = short_slot_time ? SHORT_DIFS : DIFS;
libconf.eifs = short_slot_time ? SHORT_EIFS : EIFS;
}
libconf.conf = conf;
/* /*
* Start configuration. * Start configuration.
*/ */
rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags);
/* /*
* Some configuration changes affect the link quality * Some configuration changes affect the link quality
* which means we need to reset the link tuner. * which means we need to reset the link tuner.
*/ */
if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA)) if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt2x00lib_reset_link_tuner(rt2x00dev); rt2x00lib_reset_link_tuner(rt2x00dev);
if (flags & CONFIG_UPDATE_PHYMODE) { rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->rx_status.band = conf->channel->band;
}
rt2x00dev->rx_status.freq = conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level; rt2x00dev->tx_power = conf->power_level;
if (flags & CONFIG_UPDATE_ANTENNA) { rt2x00dev->rx_status.band = conf->channel->band;
rt2x00dev->link.ant.active.rx = libconf.ant.rx; rt2x00dev->rx_status.freq = conf->channel->center_freq;
rt2x00dev->link.ant.active.tx = libconf.ant.tx;
}
} }
...@@ -96,7 +96,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -96,7 +96,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
enum antenna rx, enum antenna tx); enum antenna rx, enum antenna tx);
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config); struct ieee80211_conf *conf,
const unsigned int changed_flags);
/** /**
* DOC: Queue handlers * DOC: Queue handlers
......
...@@ -349,15 +349,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) ...@@ -349,15 +349,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
return 0; return 0;
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
rt2x00dev->ops->lib->set_retry_limit(hw,
conf->short_frame_max_tx_count,
conf->long_frame_max_tx_count);
}
changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
if (!changed)
return 0;
/* /*
* Only change device state when the radio is enabled. It does not * Only change device state when the radio is enabled. It does not
* matter what parameters we have configured when the radio is disabled * matter what parameters we have configured when the radio is disabled
...@@ -379,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) ...@@ -379,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
* When we've just turned on the radio, we want to reprogram * When we've just turned on the radio, we want to reprogram
* everything to ensure a consistent state * everything to ensure a consistent state
*/ */
rt2x00lib_config(rt2x00dev, conf, !radio_on); rt2x00lib_config(rt2x00dev, conf, changed);
/* Turn RX back on */ /* Turn RX back on */
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
......
...@@ -643,95 +643,18 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -643,95 +643,18 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE, rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble); !!erp->short_preamble);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
}
static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
u16 eeprom;
short lna_gain = 0;
if (libconf->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
} else {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
}
rt2x00dev->lna_gain = lna_gain;
}
static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev,
const int basic_rate_mask)
{
rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, basic_rate_mask);
}
static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
u8 r3;
u8 r94;
u8 smart;
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF2527));
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
rt61pci_bbp_write(rt2x00dev, 3, r3);
r94 = 6;
if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
r94 += txpower - MAX_TXPOWER;
else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
r94 += txpower;
rt61pci_bbp_write(rt2x00dev, 94, r94);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
udelay(200);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
udelay(200);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
msleep(1);
}
static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
const int txpower)
{
struct rf_channel rf;
rt2x00_rf_read(rt2x00dev, 1, &rf.rf1); rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
rt2x00_rf_read(rt2x00dev, 2, &rf.rf2); rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
rt2x00_rf_read(rt2x00dev, 3, &rf.rf3); rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
rt61pci_config_channel(rt2x00dev, &rf, txpower); rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
} }
static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
...@@ -906,8 +829,8 @@ static const struct antenna_sel antenna_sel_bg[] = { ...@@ -906,8 +829,8 @@ static const struct antenna_sel antenna_sel_bg[] = {
{ 98, { 0x48, 0x48 } }, { 98, { 0x48, 0x48 } },
}; };
static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant) struct antenna_setup *ant)
{ {
const struct antenna_sel *sel; const struct antenna_sel *sel;
unsigned int lna; unsigned int lna;
...@@ -954,20 +877,105 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -954,20 +877,105 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
} }
} }
static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
u16 eeprom;
short lna_gain = 0;
if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
} else {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
}
rt2x00dev->lna_gain = lna_gain;
}
static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
u8 r3;
u8 r94;
u8 smart;
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF2527));
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
rt61pci_bbp_write(rt2x00dev, 3, r3);
r94 = 6;
if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
r94 += txpower - MAX_TXPOWER;
else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
r94 += txpower;
rt61pci_bbp_write(rt2x00dev, 94, r94);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
udelay(200);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
udelay(200);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
msleep(1);
}
static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
const int txpower)
{
struct rf_channel rf;
rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
rt61pci_config_channel(rt2x00dev, &rf, txpower);
}
static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf) struct rt2x00lib_conf *libconf)
{ {
u32 reg; u32 reg;
rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg); rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, libconf->slot_time); rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); libconf->conf->long_frame_max_tx_count);
rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
libconf->conf->short_frame_max_tx_count);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
}
rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg); static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, MAC_CSR8_SIFS, libconf->sifs); struct rt2x00lib_conf *libconf)
rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); {
rt2x00_set_field32(&reg, MAC_CSR8_EIFS, libconf->eifs); u32 reg;
rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg); rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
...@@ -990,16 +998,15 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, ...@@ -990,16 +998,15 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
/* Always recalculate LNA gain before changing configuration */ /* Always recalculate LNA gain before changing configuration */
rt61pci_config_lna_gain(rt2x00dev, libconf); rt61pci_config_lna_gain(rt2x00dev, libconf);
if (flags & CONFIG_UPDATE_PHYMODE) if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt61pci_config_phymode(rt2x00dev, libconf->basic_rates);
if (flags & CONFIG_UPDATE_CHANNEL)
rt61pci_config_channel(rt2x00dev, &libconf->rf, rt61pci_config_channel(rt2x00dev, &libconf->rf,
libconf->conf->power_level); libconf->conf->power_level);
if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
!(flags & IEEE80211_CONF_CHANGE_CHANNEL))
rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level); rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA) if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt61pci_config_antenna(rt2x00dev, &libconf->ant); rt61pci_config_retry_limit(rt2x00dev, libconf);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt61pci_config_duration(rt2x00dev, libconf); rt61pci_config_duration(rt2x00dev, libconf);
} }
...@@ -2628,20 +2635,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -2628,20 +2635,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * IEEE80211 stack callback functions.
*/ */
static int rt61pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry);
rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
return 0;
}
static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params) const struct ieee80211_tx_queue_params *params)
{ {
...@@ -2755,8 +2748,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { ...@@ -2755,8 +2748,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.config_filter = rt61pci_config_filter, .config_filter = rt61pci_config_filter,
.config_intf = rt61pci_config_intf, .config_intf = rt61pci_config_intf,
.config_erp = rt61pci_config_erp, .config_erp = rt61pci_config_erp,
.config_ant = rt61pci_config_ant,
.config = rt61pci_config, .config = rt61pci_config,
.set_retry_limit = rt61pci_set_retry_limit,
}; };
static const struct data_queue_desc rt61pci_queue_rx = { static const struct data_queue_desc rt61pci_queue_rx = {
......
...@@ -669,87 +669,18 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -669,87 +669,18 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE, rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble); !!erp->short_preamble);
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
}
static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
u16 eeprom;
short lna_gain = 0;
if (libconf->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
} else {
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
}
rt2x00dev->lna_gain = lna_gain;
}
static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
const int basic_rate_mask)
{
rt73usb_register_write(rt2x00dev, TXRX_CSR5, basic_rate_mask);
}
static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
u8 r3;
u8 r94;
u8 smart;
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF2527));
rt73usb_bbp_read(rt2x00dev, 3, &r3);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
rt73usb_bbp_write(rt2x00dev, 3, r3);
r94 = 6;
if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
r94 += txpower - MAX_TXPOWER;
else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
r94 += txpower;
rt73usb_bbp_write(rt2x00dev, 94, r94);
rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
rt73usb_rf_write(rt2x00dev, 1, rf->rf1); rt73usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
udelay(10);
}
static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
const int txpower)
{
struct rf_channel rf;
rt2x00_rf_read(rt2x00dev, 1, &rf.rf1); rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
rt2x00_rf_read(rt2x00dev, 2, &rf.rf2); rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
rt2x00_rf_read(rt2x00dev, 3, &rf.rf3); rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
rt73usb_config_channel(rt2x00dev, &rf, txpower); rt73usb_register_read(rt2x00dev, MAC_CSR8, &reg);
rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
rt73usb_register_write(rt2x00dev, MAC_CSR8, reg);
} }
static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
...@@ -869,8 +800,8 @@ static const struct antenna_sel antenna_sel_bg[] = { ...@@ -869,8 +800,8 @@ static const struct antenna_sel antenna_sel_bg[] = {
{ 98, { 0x48, 0x48 } }, { 98, { 0x48, 0x48 } },
}; };
static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant) struct antenna_setup *ant)
{ {
const struct antenna_sel *sel; const struct antenna_sel *sel;
unsigned int lna; unsigned int lna;
...@@ -912,20 +843,98 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -912,20 +843,98 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
rt73usb_config_antenna_2x(rt2x00dev, ant); rt73usb_config_antenna_2x(rt2x00dev, ant);
} }
static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf) struct rt2x00lib_conf *libconf)
{
u16 eeprom;
short lna_gain = 0;
if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
} else {
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
}
rt2x00dev->lna_gain = lna_gain;
}
static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
u8 r3;
u8 r94;
u8 smart;
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF2527));
rt73usb_bbp_read(rt2x00dev, 3, &r3);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
rt73usb_bbp_write(rt2x00dev, 3, r3);
r94 = 6;
if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
r94 += txpower - MAX_TXPOWER;
else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
r94 += txpower;
rt73usb_bbp_write(rt2x00dev, 94, r94);
rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
udelay(10);
}
static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
const int txpower)
{
struct rf_channel rf;
rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
rt73usb_config_channel(rt2x00dev, &rf, txpower);
}
static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{ {
u32 reg; u32 reg;
rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg); rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, libconf->slot_time); rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); libconf->conf->long_frame_max_tx_count);
rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
libconf->conf->short_frame_max_tx_count);
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
}
rt73usb_register_read(rt2x00dev, MAC_CSR8, &reg); static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, MAC_CSR8_SIFS, libconf->sifs); struct rt2x00lib_conf *libconf)
rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); {
rt2x00_set_field32(&reg, MAC_CSR8_EIFS, libconf->eifs); u32 reg;
rt73usb_register_write(rt2x00dev, MAC_CSR8, reg);
rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg); rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
...@@ -948,16 +957,15 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, ...@@ -948,16 +957,15 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
/* Always recalculate LNA gain before changing configuration */ /* Always recalculate LNA gain before changing configuration */
rt73usb_config_lna_gain(rt2x00dev, libconf); rt73usb_config_lna_gain(rt2x00dev, libconf);
if (flags & CONFIG_UPDATE_PHYMODE) if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt73usb_config_phymode(rt2x00dev, libconf->basic_rates);
if (flags & CONFIG_UPDATE_CHANNEL)
rt73usb_config_channel(rt2x00dev, &libconf->rf, rt73usb_config_channel(rt2x00dev, &libconf->rf,
libconf->conf->power_level); libconf->conf->power_level);
if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
!(flags & IEEE80211_CONF_CHANGE_CHANNEL))
rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level); rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
if (flags & CONFIG_UPDATE_ANTENNA) if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt73usb_config_antenna(rt2x00dev, &libconf->ant); rt73usb_config_retry_limit(rt2x00dev, libconf);
if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt73usb_config_duration(rt2x00dev, libconf); rt73usb_config_duration(rt2x00dev, libconf);
} }
...@@ -2209,20 +2217,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -2209,20 +2217,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * IEEE80211 stack callback functions.
*/ */
static int rt73usb_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u32 reg;
rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry);
rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry);
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
return 0;
}
static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params) const struct ieee80211_tx_queue_params *params)
{ {
...@@ -2345,8 +2339,8 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { ...@@ -2345,8 +2339,8 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.config_filter = rt73usb_config_filter, .config_filter = rt73usb_config_filter,
.config_intf = rt73usb_config_intf, .config_intf = rt73usb_config_intf,
.config_erp = rt73usb_config_erp, .config_erp = rt73usb_config_erp,
.config_ant = rt73usb_config_ant,
.config = rt73usb_config, .config = rt73usb_config,
.set_retry_limit = rt73usb_set_retry_limit,
}; };
static const struct data_queue_desc rt73usb_queue_rx = { static const struct data_queue_desc rt73usb_queue_rx = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment