Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 246868
b: refs/heads/master
c: 8e86a54
h: refs/heads/master
v: v3
  • Loading branch information
Sujith Manoharan authored and John W. Linville committed Apr 13, 2011
1 parent aebeb7d commit 0c006bd
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 28 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: 3deff76095c4ac4252e27c537db3041f619c23a2
refs/heads/master: 8e86a54715c4102a8ed697939de9ebd9715dc59c
13 changes: 10 additions & 3 deletions trunk/drivers/net/wireless/ath/ath9k/htc.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,16 @@ struct ath9k_htc_rx {
spinlock_t rxbuflock;
};

struct ath9k_htc_tx {
bool tx_queues_stop;
spinlock_t tx_lock;
#define ATH9K_HTC_TX_RESERVE 10
#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE)

#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0)

struct ath9k_htc_tx {
u8 flags;
int queued_cnt;
struct sk_buff_head tx_queue;
spinlock_t tx_lock;
};

struct ath9k_htc_tx_ctl {
Expand Down Expand Up @@ -532,6 +537,8 @@ int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
int get_hw_qnum(u16 queue, int *hwq_map);
int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
struct ath9k_tx_queue_info *qinfo);
void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv);
void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv);

int ath9k_rx_init(struct ath9k_htc_priv *priv);
void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
ath_dbg(common, ATH_DBG_FATAL,
"Failed to send CAB frame\n");
dev_kfree_skb_any(skb);
} else {
spin_lock_bh(&priv->tx.tx_lock);
priv->tx.queued_cnt++;
spin_unlock_bh(&priv->tx.tx_lock);
}
next:
skb = ieee80211_get_buffered_bc(priv->hw, vif);
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
/* Start TX */
htc_start(priv->htc);
spin_lock_bh(&priv->tx.tx_lock);
priv->tx.tx_queues_stop = false;
priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
spin_unlock_bh(&priv->tx.tx_lock);
ieee80211_wake_queues(hw);

Expand Down
21 changes: 8 additions & 13 deletions trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
struct ath9k_htc_priv *priv = hw->priv;
struct ath_common *common = ath9k_hw_common(priv->ah);
int padpos, padsize, ret;

hdr = (struct ieee80211_hdr *) skb->data;
Expand All @@ -841,28 +842,22 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
padpos = ath9k_cmn_padpos(hdr->frame_control);
padsize = padpos & 3;
if (padsize && skb->len > padpos) {
if (skb_headroom(skb) < padsize)
if (skb_headroom(skb) < padsize) {
ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n");
goto fail_tx;
}
skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, padpos);
}

ret = ath9k_htc_tx_start(priv, skb, false);
if (ret != 0) {
if (ret == -ENOMEM) {
ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
"Stopping TX queues\n");
ieee80211_stop_queues(hw);
spin_lock_bh(&priv->tx.tx_lock);
priv->tx.tx_queues_stop = true;
spin_unlock_bh(&priv->tx.tx_lock);
} else {
ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
"Tx failed\n");
}
ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n");
goto fail_tx;
}

ath9k_htc_check_stop_queues(priv);

return;

fail_tx:
Expand Down Expand Up @@ -924,7 +919,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
htc_start(priv->htc);

spin_lock_bh(&priv->tx.tx_lock);
priv->tx.tx_queues_stop = false;
priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
spin_unlock_bh(&priv->tx.tx_lock);

ieee80211_wake_queues(hw);
Expand Down
39 changes: 29 additions & 10 deletions trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ int get_hw_qnum(u16 queue, int *hwq_map)
}
}

void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv)
{
spin_lock_bh(&priv->tx.tx_lock);
priv->tx.queued_cnt++;
if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) &&
!(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP;
ieee80211_stop_queues(priv->hw);
}
spin_unlock_bh(&priv->tx.tx_lock);
}

void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)
{
spin_lock_bh(&priv->tx.tx_lock);
if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) &&
(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
ieee80211_wake_queues(priv->hw);
}
spin_unlock_bh(&priv->tx.tx_lock);
}

int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
struct ath9k_tx_queue_info *qinfo)
{
Expand Down Expand Up @@ -302,21 +325,17 @@ void ath9k_tx_tasklet(unsigned long data)
rcu_read_unlock();

send_mac80211:
spin_lock_bh(&priv->tx.tx_lock);
if (WARN_ON(--priv->tx.queued_cnt < 0))
priv->tx.queued_cnt = 0;
spin_unlock_bh(&priv->tx.tx_lock);

/* Send status to mac80211 */
ieee80211_tx_status(priv->hw, skb);
}

/* Wake TX queues if needed */
spin_lock_bh(&priv->tx.tx_lock);
if (priv->tx.tx_queues_stop) {
priv->tx.tx_queues_stop = false;
spin_unlock_bh(&priv->tx.tx_lock);
ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
"Waking up TX queues\n");
ieee80211_wake_queues(priv->hw);
return;
}
spin_unlock_bh(&priv->tx.tx_lock);
ath9k_htc_check_wake_queues(priv);
}

void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
Expand Down

0 comments on commit 0c006bd

Please sign in to comment.