Skip to content

Commit

Permalink
iwlwifi: manage QoS by mac stack
Browse files Browse the repository at this point in the history
We activate/deactivate QoS and setup default queue parameters in iwlwifi
driver. Mac stack do the same, so we do not need repeat that work here.
Stack also will tell when disable QoS, this will fix driver when working
with older APs, that do not have QoS implemented.

Patch make "force = true" in iwl_active_qos() assuming we always want
to do with QoS what mac stack wish.

Patch also remove unused qos_cap bits, do not initialize qos_active = 0,
as we have it initialized to zero by kzalloc.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Stanislaw Gruszka authored and John W. Linville committed Mar 31, 2010
1 parent e1b3ec1 commit e61146e
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 171 deletions.
15 changes: 0 additions & 15 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2531,7 +2531,6 @@ void iwl_post_associate(struct iwl_priv *priv)
{
struct ieee80211_conf *conf = NULL;
int ret = 0;
unsigned long flags;

if (priv->iw_mode == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
Expand Down Expand Up @@ -2612,10 +2611,6 @@ void iwl_post_associate(struct iwl_priv *priv)
break;
}

spin_lock_irqsave(&priv->lock, flags);
iwl_activate_qos(priv, 0);
spin_unlock_irqrestore(&priv->lock, flags);

/* the chain noise calibration will enabled PM upon completion
* If chain noise has already been run, then we need to enable
* power management here */
Expand Down Expand Up @@ -2792,7 +2787,6 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwl_config_ap(struct iwl_priv *priv)
{
int ret = 0;
unsigned long flags;

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
Expand Down Expand Up @@ -2844,10 +2838,6 @@ void iwl_config_ap(struct iwl_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv);
iwl_reset_qos(priv);
spin_lock_irqsave(&priv->lock, flags);
iwl_activate_qos(priv, 1);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_add_bcast_station(priv);
}
iwl_send_beacon_cmd(priv);
Expand Down Expand Up @@ -3382,11 +3372,6 @@ static int iwl_init_drv(struct iwl_priv *priv)

iwl_init_scan_params(priv);

iwl_reset_qos(priv);

priv->qos_data.qos_active = 0;
priv->qos_data.qos_cap.val = 0;

/* Set the tx_power_user_lmt to the lowest power level
* this value will get overwritten by channel max power avg
* from eeprom */
Expand Down
142 changes: 16 additions & 126 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,136 +223,28 @@ EXPORT_SYMBOL(iwl_hw_detect);
/*
* QoS support
*/
void iwl_activate_qos(struct iwl_priv *priv, u8 force)
static void iwl_update_qos(struct iwl_priv *priv)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

priv->qos_data.def_qos_parm.qos_flags = 0;

if (priv->qos_data.qos_cap.q_AP.queue_request &&
!priv->qos_data.qos_cap.q_AP.txop_request)
priv->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_TXOP_TYPE_MSK;
if (priv->qos_data.qos_active)
priv->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;

if (priv->current_ht_config.is_ht)
priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;

if (force || iwl_is_associated(priv)) {
IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
priv->qos_data.qos_active,
priv->qos_data.def_qos_parm.qos_flags);
IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
priv->qos_data.qos_active,
priv->qos_data.def_qos_parm.qos_flags);

iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
sizeof(struct iwl_qosparam_cmd),
&priv->qos_data.def_qos_parm, NULL);
}
iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
sizeof(struct iwl_qosparam_cmd),
&priv->qos_data.def_qos_parm, NULL);
}
EXPORT_SYMBOL(iwl_activate_qos);

/*
* AC CWmin CW max AIFSN TXOP Limit TXOP Limit
* (802.11b) (802.11a/g)
* AC_BK 15 1023 7 0 0
* AC_BE 15 1023 3 0 0
* AC_VI 7 15 2 6.016ms 3.008ms
* AC_VO 3 7 2 3.264ms 1.504ms
*/
void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
u16 cw_max = 1023;
u8 aifs = 2;
bool is_legacy = false;
unsigned long flags;
int i;

spin_lock_irqsave(&priv->lock, flags);
/* QoS always active in AP and ADHOC mode
* In STA mode wait for association
*/
if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
priv->iw_mode == NL80211_IFTYPE_AP)
priv->qos_data.qos_active = 1;
else
priv->qos_data.qos_active = 0;

/* check for legacy mode */
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
(priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
(priv->iw_mode == NL80211_IFTYPE_STATION &&
(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
cw_min = 31;
is_legacy = 1;
}

if (priv->qos_data.qos_active)
aifs = 3;

/* AC_BE */
priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;

if (priv->qos_data.qos_active) {
/* AC_BK */
i = 1;
priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;

/* AC_VI */
i = 2;
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16((cw_min + 1) / 2 - 1);
priv->qos_data.def_qos_parm.ac[i].cw_max =
cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
if (is_legacy)
priv->qos_data.def_qos_parm.ac[i].edca_txop =
cpu_to_le16(6016);
else
priv->qos_data.def_qos_parm.ac[i].edca_txop =
cpu_to_le16(3008);
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;

/* AC_VO */
i = 3;
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16((cw_min + 1) / 4 - 1);
priv->qos_data.def_qos_parm.ac[i].cw_max =
cpu_to_le16((cw_min + 1) / 2 - 1);
priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
if (is_legacy)
priv->qos_data.def_qos_parm.ac[i].edca_txop =
cpu_to_le16(3264);
else
priv->qos_data.def_qos_parm.ac[i].edca_txop =
cpu_to_le16(1504);
} else {
for (i = 1; i < 4; i++) {
priv->qos_data.def_qos_parm.ac[i].cw_min =
cpu_to_le16(cw_min);
priv->qos_data.def_qos_parm.ac[i].cw_max =
cpu_to_le16(cw_max);
priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
}
}
IWL_DEBUG_QOS(priv, "set QoS to default \n");

spin_unlock_irqrestore(&priv->lock, flags);
}
EXPORT_SYMBOL(iwl_reset_qos);

#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
Expand Down Expand Up @@ -1894,12 +1786,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
cpu_to_le16((params->txop * 32));

priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
priv->qos_data.qos_active = 1;

if (priv->iw_mode == NL80211_IFTYPE_AP)
iwl_activate_qos(priv, 1);
else if (priv->assoc_id && iwl_is_associated(priv))
iwl_activate_qos(priv, 0);

spin_unlock_irqrestore(&priv->lock, flags);

Expand Down Expand Up @@ -2170,11 +2056,8 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);

iwl_reset_qos(priv);

priv->cfg->ops->lib->post_associate(priv);


return 0;
}
EXPORT_SYMBOL(iwl_mac_beacon_update);
Expand Down Expand Up @@ -2396,6 +2279,15 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_set_tx_power(priv, conf->power_level, false);
}

if (changed & IEEE80211_CONF_CHANGE_QOS) {
bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS);

spin_lock_irqsave(&priv->lock, flags);
priv->qos_data.qos_active = qos_active;
iwl_update_qos(priv);
spin_unlock_irqrestore(&priv->lock, flags);
}

if (!iwl_is_ready(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
goto out;
Expand Down Expand Up @@ -2430,8 +2322,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
spin_unlock_irqrestore(&priv->lock, flags);

iwl_reset_qos(priv);

spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,7 @@ struct iwl_cfg {
struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
void iwl_hw_detect(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_activate_qos(struct iwl_priv *priv, u8 force);
void iwl_activate_qos(struct iwl_priv *priv);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
Expand Down
21 changes: 0 additions & 21 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,30 +476,9 @@ struct iwl_ht_config {
u8 non_GF_STA_present;
};

union iwl_qos_capabity {
struct {
u8 edca_count:4; /* bit 0-3 */
u8 q_ack:1; /* bit 4 */
u8 queue_request:1; /* bit 5 */
u8 txop_request:1; /* bit 6 */
u8 reserved:1; /* bit 7 */
} q_AP;
struct {
u8 acvo_APSD:1; /* bit 0 */
u8 acvi_APSD:1; /* bit 1 */
u8 ac_bk_APSD:1; /* bit 2 */
u8 ac_be_APSD:1; /* bit 3 */
u8 q_ack:1; /* bit 4 */
u8 max_len:2; /* bit 5-6 */
u8 more_data_ack:1; /* bit 7 */
} q_STA;
u8 val;
};

/* QoS structures */
struct iwl_qos_info {
int qos_active;
union iwl_qos_capabity qos_cap;
struct iwl_qosparam_cmd def_qos_parm;
};

Expand Down
7 changes: 0 additions & 7 deletions drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -3140,8 +3140,6 @@ void iwl3945_post_associate(struct iwl_priv *priv)
break;
}

iwl_activate_qos(priv, 0);

/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
Expand Down Expand Up @@ -3889,11 +3887,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->iw_mode = NL80211_IFTYPE_STATION;
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;

iwl_reset_qos(priv);

priv->qos_data.qos_active = 0;
priv->qos_data.qos_cap.val = 0;

priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;

if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
Expand Down

0 comments on commit e61146e

Please sign in to comment.