Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 136210
b: refs/heads/master
c: e4e72fb
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Mar 28, 2009
1 parent cbf3c77 commit e56f14a
Show file tree
Hide file tree
Showing 18 changed files with 85 additions and 170 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cd8ffc800ce18e558335c4946b2217864fc16045
refs/heads/master: e4e72fb4de93e3d4047a4ee3f08778422e17ed0d
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-3945.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
ieee80211_wake_queue(priv->hw, txq_id);
iwl_wake_queue(priv, txq_id);
}

/**
Expand Down
7 changes: 3 additions & 4 deletions trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -2178,10 +2178,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
if (agg->state == IWL_AGG_OFF)
ieee80211_wake_queue(priv->hw, txq_id);
iwl_wake_queue(priv, txq_id);
else
ieee80211_wake_queue(priv->hw,
txq->swq_id);
iwl_wake_queue(priv, txq->swq_id);
}
}
} else {
Expand All @@ -2205,7 +2204,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,

if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
ieee80211_wake_queue(priv->hw, txq_id);
iwl_wake_queue(priv, txq_id);
}

if (qc && likely(sta_id != IWL_INVALID_STATION))
Expand Down
7 changes: 3 additions & 4 deletions trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -1295,10 +1295,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
if (agg->state == IWL_AGG_OFF)
ieee80211_wake_queue(priv->hw, txq_id);
iwl_wake_queue(priv, txq_id);
else
ieee80211_wake_queue(priv->hw,
txq->swq_id);
iwl_wake_queue(priv, txq->swq_id);
}
}
} else {
Expand All @@ -1324,7 +1323,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,

if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
ieee80211_wake_queue(priv->hw, txq_id);
iwl_wake_queue(priv, txq_id);
}

if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
Expand Down
3 changes: 0 additions & 3 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1309,9 +1309,6 @@ int iwl_setup_mac(struct iwl_priv *priv)

/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
/* queues to support 11n aggregation */
if (priv->cfg->sku & IWL_SKU_N)
hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;

hw->conf.beacon_int = 100;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,12 @@ struct iwl_priv {
u8 key_mapping_key;
unsigned long ucode_key_table;

/* queue refcounts */
#define IWL_MAX_HW_QUEUES 32
unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
/* for each AC */
atomic_t queue_stop_count[4];

/* Indication if ieee80211_ops->open has been called */
u8 is_open;

Expand Down
52 changes: 52 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,56 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
return (desc->v_addr != NULL) ? 0 : -ENOMEM;
}

/*
* we have 8 bits used like this:
*
* 7 6 5 4 3 2 1 0
* | | | | | | | |
* | | | | | | +-+-------- AC queue (0-3)
* | | | | | |
* | +-+-+-+-+------------ HW A-MPDU queue
* |
* +---------------------- indicates agg queue
*/
static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
{
BUG_ON(ac > 3); /* only have 2 bits */
BUG_ON(hwq > 31); /* only have 5 bits */

return 0x80 | (hwq << 2) | ac;
}

static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
{
u8 ac = queue;
u8 hwq = queue;

if (queue & 0x80) {
ac = queue & 3;
hwq = (queue >> 2) & 0x1f;
}

if (test_and_clear_bit(hwq, priv->queue_stopped))
if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(priv->hw, ac);
}

static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
{
u8 ac = queue;
u8 hwq = queue;

if (queue & 0x80) {
ac = queue & 3;
hwq = (queue >> 2) & 0x1f;
}

if (!test_and_set_bit(hwq, priv->queue_stopped))
if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
ieee80211_stop_queue(priv->hw, ac);
}

#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue

#endif /* __iwl_helpers_h__ */
8 changes: 5 additions & 3 deletions trunk/drivers/net/wireless/iwlwifi/iwl-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr->seq_ctrl |= cpu_to_le16(seq_number);
seq_number += 0x10;
/* aggregation is on for this <sta,tid> */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
}
priv->stations[sta_id].tid[tid].tfds_in_queue++;
}

Expand Down Expand Up @@ -895,7 +897,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
} else {
ieee80211_stop_queue(priv->hw, txq->swq_id);
iwl_stop_queue(priv, txq->swq_id);
}
}

Expand Down Expand Up @@ -1433,7 +1435,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
priv->mac80211_registered &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
ieee80211_wake_queue(priv->hw, txq->swq_id);
iwl_wake_queue(priv, txq->swq_id);

iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->lock, flags);
}

ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
iwl_stop_queue(priv, skb_get_queue_mapping(skb));
}

return 0;
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,6 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT);
hw->ampdu_queues = 1;

hw->flags = IEEE80211_HW_MFP_CAPABLE;

Expand Down
14 changes: 2 additions & 12 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,9 @@ struct ieee80211_ht_bss_info {
* enum ieee80211_max_queues - maximum number of queues
*
* @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
* @IEEE80211_MAX_AMPDU_QUEUES: Maximum number of queues usable
* for A-MPDU operation.
*/
enum ieee80211_max_queues {
IEEE80211_MAX_QUEUES = 4,
IEEE80211_MAX_AMPDU_QUEUES = 16,
};

/**
Expand Down Expand Up @@ -952,12 +949,6 @@ enum ieee80211_hw_flags {
* data packets. WMM/QoS requires at least four, these
* queues need to have configurable access parameters.
*
* @ampdu_queues: number of available hardware transmit queues
* for A-MPDU packets, these have no access parameters
* because they're used only for A-MPDU frames. Note that
* mac80211 will not currently use any of the regular queues
* for aggregation.
*
* @rate_control_algorithm: rate control algorithm for this hardware.
* If unset (NULL), the default algorithm will be used. Must be
* set before calling ieee80211_register_hw().
Expand All @@ -982,7 +973,6 @@ struct ieee80211_hw {
int vif_data_size;
int sta_data_size;
u16 queues;
u16 ampdu_queues;
u16 max_listen_interval;
s8 max_signal;
u8 max_rates;
Expand Down Expand Up @@ -1372,8 +1362,8 @@ enum ieee80211_ampdu_mlme_action {
* @get_tx_stats: Get statistics of the current TX queue status. This is used
* to get number of currently queued packets (queue length), maximum queue
* size (limit), and total number of packets sent using each TX queue
* (count). The 'stats' pointer points to an array that has hw->queues +
* hw->ampdu_queues items.
* (count). The 'stats' pointer points to an array that has hw->queues
* items.
*
* @get_tsf: Get the current TSF timer value from firmware/hardware. Currently,
* this is only used for IBSS mode BSSID merging and debugging. Is not a
Expand Down
44 changes: 3 additions & 41 deletions trunk/net/mac80211/agg-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,

state = &sta->ampdu_mlme.tid_state_tx[tid];

if (local->hw.ampdu_queues) {
/*
* Pretend the driver woke the queue, just in case
* it disabled it before the session was stopped.
*/
ieee80211_wake_queue(
&local->hw, local->hw.queues + sta->tid_to_tx_q[tid]);
}
*state = HT_AGG_STATE_REQ_STOP_BA_MSK |
(initiator << HT_AGG_STATE_INITIATOR_SHIFT);

Expand Down Expand Up @@ -206,7 +198,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
struct sta_info *sta;
struct ieee80211_sub_if_data *sdata;
u8 *state;
int i, qn = -1, ret = 0;
int ret = 0;
u16 start_seq_num;

if (WARN_ON(!local->ops->ampdu_action))
Expand Down Expand Up @@ -275,29 +267,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
goto err_unlock_sta;
}

if (hw->ampdu_queues) {
spin_lock(&local->queue_stop_reason_lock);
/* reserve a new queue for this session */
for (i = 0; i < local->hw.ampdu_queues; i++) {
if (local->ampdu_ac_queue[i] < 0) {
qn = i;
local->ampdu_ac_queue[qn] =
ieee80211_ac_from_tid(tid);
break;
}
}
spin_unlock(&local->queue_stop_reason_lock);

if (qn < 0) {
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "BA request denied - "
"queue unavailable for tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
ret = -ENOSPC;
goto err_unlock_sta;
}
}

/*
* While we're asking the driver about the aggregation,
* stop the AC queue so that we don't have to worry
Expand All @@ -319,7 +288,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
tid);
#endif
ret = -ENOMEM;
goto err_return_queue;
goto err_wake_queue;
}

skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending);
Expand Down Expand Up @@ -348,7 +317,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
*state = HT_AGG_STATE_IDLE;
goto err_free;
}
sta->tid_to_tx_q[tid] = qn;

/* Driver vetoed or OKed, but we can take packets again now */
ieee80211_wake_queue_by_reason(
Expand Down Expand Up @@ -380,13 +348,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
err_free:
kfree(sta->ampdu_mlme.tid_tx[tid]);
sta->ampdu_mlme.tid_tx[tid] = NULL;
err_return_queue:
if (qn >= 0) {
/* give queue back to pool */
spin_lock(&local->queue_stop_reason_lock);
local->ampdu_ac_queue[qn] = -1;
spin_unlock(&local->queue_stop_reason_lock);
}
err_wake_queue:
ieee80211_wake_queue_by_reason(
&local->hw, ieee80211_ac_from_tid(tid),
IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
Expand Down
7 changes: 1 addition & 6 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,12 +594,7 @@ struct ieee80211_local {

const struct ieee80211_ops *ops;

/* AC queue corresponding to each AMPDU queue */
s8 ampdu_ac_queue[IEEE80211_MAX_AMPDU_QUEUES];
unsigned int amdpu_ac_stop_refcnt[IEEE80211_MAX_AMPDU_QUEUES];

unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES +
IEEE80211_MAX_AMPDU_QUEUES];
unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
/* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
spinlock_t queue_stop_reason_lock;

Expand Down
9 changes: 0 additions & 9 deletions trunk/net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,11 +774,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
setup_timer(&local->dynamic_ps_timer,
ieee80211_dynamic_ps_timer, (unsigned long) local);

for (i = 0; i < IEEE80211_MAX_AMPDU_QUEUES; i++)
local->ampdu_ac_queue[i] = -1;
/* using an s8 won't work with more than that */
BUILD_BUG_ON(IEEE80211_MAX_AMPDU_QUEUES > 127);

sta_info_init(local);

for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
Expand Down Expand Up @@ -874,10 +869,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
*/
if (hw->queues > IEEE80211_MAX_QUEUES)
hw->queues = IEEE80211_MAX_QUEUES;
if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
if (hw->queues < 4)
hw->ampdu_queues = 0;

mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
"wmaster%d", ieee80211_master_setup,
Expand Down
12 changes: 0 additions & 12 deletions trunk/net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,6 @@ void sta_info_destroy(struct sta_info *sta)
if (tid_rx)
tid_rx->shutdown = true;

/*
* The stop callback cannot find this station any more, but
* it didn't complete its work -- start the queue if necessary
*/
if (sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_INITIATOR_MSK &&
sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_REQ_STOP_BA_MSK &&
local->hw.ampdu_queues)
ieee80211_wake_queue_by_reason(&local->hw,
local->hw.queues + sta->tid_to_tx_q[i],
IEEE80211_QUEUE_STOP_REASON_AGGREGATION);

spin_unlock_bh(&sta->lock);

/*
Expand Down Expand Up @@ -292,7 +281,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
* enable session_timer's data differentiation. refer to
* sta_rx_agg_session_timer_expired for useage */
sta->timer_to_tid[i] = i;
sta->tid_to_tx_q[i] = -1;
/* rx */
sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
sta->ampdu_mlme.tid_rx[i] = NULL;
Expand Down
2 changes: 0 additions & 2 deletions trunk/net/mac80211/sta_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ struct sta_ampdu_mlme {
* @tid_seq: per-TID sequence numbers for sending to this STA
* @ampdu_mlme: A-MPDU state machine state
* @timer_to_tid: identity mapping to ID timers
* @tid_to_tx_q: map tid to tx queue (invalid == negative values)
* @llid: Local link ID
* @plid: Peer link ID
* @reason: Cancel reason on PLINK_HOLDING state
Expand Down Expand Up @@ -281,7 +280,6 @@ struct sta_info {
*/
struct sta_ampdu_mlme ampdu_mlme;
u8 timer_to_tid[STA_TID_NUM];
s8 tid_to_tx_q[STA_TID_NUM];

#ifdef CONFIG_MAC80211_MESH
/*
Expand Down
Loading

0 comments on commit e56f14a

Please sign in to comment.