Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 246871
b: refs/heads/master
c: 2c5d57f
h: refs/heads/master
i:
  246869: ac41422
  246867: aebeb7d
  246863: 76a965a
v: v3
  • Loading branch information
Sujith Manoharan authored and John W. Linville committed Apr 13, 2011
1 parent 18bd6cd commit 87df6bc
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 15 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: 729bd3ab460d3bb8236cc8f6fd0289201124112d
refs/heads/master: 2c5d57f004673a9c8658e20b1fa3f992b5a10f70
5 changes: 4 additions & 1 deletion trunk/drivers/net/wireless/ath/ath9k/htc.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ struct ath9k_htc_tx {
u8 flags;
int queued_cnt;
struct sk_buff_head tx_queue;
DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
spinlock_t tx_lock;
};

Expand Down Expand Up @@ -532,7 +533,7 @@ void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
int ath9k_tx_init(struct ath9k_htc_priv *priv);
void ath9k_tx_tasklet(unsigned long data);
int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
struct sk_buff *skb, bool is_cab);
struct sk_buff *skb, u8 slot, bool is_cab);
void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype);
int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
Expand All @@ -541,6 +542,8 @@ 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_htc_tx_get_slot(struct ath9k_htc_priv *priv);
void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);

int ath9k_rx_init(struct ath9k_htc_priv *priv);
void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
Expand Down
17 changes: 13 additions & 4 deletions trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif;
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
int padpos, padsize, ret;
int padpos, padsize, ret, tx_slot;

spin_lock_bh(&priv->beacon_lock);

Expand All @@ -321,11 +321,20 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
memmove(skb->data, skb->data + padsize, padpos);
}

ret = ath9k_htc_tx_start(priv, skb, true);
tx_slot = ath9k_htc_tx_get_slot(priv);
if (tx_slot != 0) {
ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n");
dev_kfree_skb_any(skb);
goto next;
}

ret = ath9k_htc_tx_start(priv, skb, tx_slot, true);
if (ret != 0) {
ath_dbg(common, ATH_DBG_FATAL,
"Failed to send CAB frame\n");
ath9k_htc_tx_clear_slot(priv, tx_slot);
dev_kfree_skb_any(skb);

ath_dbg(common, ATH_DBG_XMIT,
"Failed to send CAB frame\n");
} else {
spin_lock_bh(&priv->tx.tx_lock);
priv->tx.queued_cnt++;
Expand Down
14 changes: 11 additions & 3 deletions trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,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;
int padpos, padsize, ret, slot;

hdr = (struct ieee80211_hdr *) skb->data;

Expand All @@ -850,16 +850,24 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
memmove(skb->data, skb->data + padsize, padpos);
}

ret = ath9k_htc_tx_start(priv, skb, false);
slot = ath9k_htc_tx_get_slot(priv);
if (slot < 0) {
ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n");
goto fail_tx;
}

ret = ath9k_htc_tx_start(priv, skb, slot, false);
if (ret != 0) {
ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n");
goto fail_tx;
goto clear_slot;
}

ath9k_htc_check_stop_queues(priv);

return;

clear_slot:
ath9k_htc_tx_clear_slot(priv, slot);
fail_tx:
dev_kfree_skb_any(skb);
}
Expand Down
51 changes: 45 additions & 6 deletions trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,29 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)
spin_unlock_bh(&priv->tx.tx_lock);
}

int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv)
{
int slot;

spin_lock_bh(&priv->tx.tx_lock);
slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM);
if (slot >= MAX_TX_BUF_NUM) {
spin_unlock_bh(&priv->tx.tx_lock);
return -ENOBUFS;
}
__set_bit(slot, priv->tx.tx_slot);
spin_unlock_bh(&priv->tx.tx_lock);

return slot;
}

void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot)
{
spin_lock_bh(&priv->tx.tx_lock);
__clear_bit(slot, priv->tx.tx_slot);
spin_unlock_bh(&priv->tx.tx_lock);
}

static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
u16 qnum)
{
Expand Down Expand Up @@ -104,28 +127,38 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
return epid;
}

/*
* Removes the driver header and returns the TX slot number
*/
static inline int strip_drv_header(struct ath9k_htc_priv *priv,
struct sk_buff *skb)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_htc_tx_ctl *tx_ctl;
int slot;

tx_ctl = HTC_SKB_CB(skb);

if (tx_ctl->epid == priv->mgmt_ep) {
struct tx_mgmt_hdr *tx_mhdr =
(struct tx_mgmt_hdr *)skb->data;
slot = tx_mhdr->cookie;
skb_pull(skb, sizeof(struct tx_mgmt_hdr));
} else if ((tx_ctl->epid == priv->data_bk_ep) ||
(tx_ctl->epid == priv->data_be_ep) ||
(tx_ctl->epid == priv->data_vi_ep) ||
(tx_ctl->epid == priv->data_vo_ep) ||
(tx_ctl->epid == priv->cab_ep)) {
struct tx_frame_hdr *tx_fhdr =
(struct tx_frame_hdr *)skb->data;
slot = tx_fhdr->cookie;
skb_pull(skb, sizeof(struct tx_frame_hdr));
} else {
ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid);
return -EINVAL;
slot = -EINVAL;
}

return 0;
return slot;
}

int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
Expand Down Expand Up @@ -155,7 +188,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
}

int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
struct sk_buff *skb, bool is_cab)
struct sk_buff *skb,
u8 slot, bool is_cab)
{
struct ieee80211_hdr *hdr;
struct ieee80211_mgmt *mgmt;
Expand Down Expand Up @@ -212,6 +246,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,

tx_hdr.node_idx = sta_idx;
tx_hdr.vif_idx = vif_idx;
tx_hdr.cookie = slot;

if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
tx_ctl->type = ATH9K_HTC_AMPDU;
Expand Down Expand Up @@ -274,6 +309,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
mgmt_hdr.vif_idx = vif_idx;
mgmt_hdr.tidno = 0;
mgmt_hdr.flags = 0;
mgmt_hdr.cookie = slot;

mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
Expand Down Expand Up @@ -313,10 +349,12 @@ void ath9k_tx_tasklet(unsigned long data)
struct sk_buff *skb = NULL;
__le16 fc;
bool txok;
int slot;

while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) {

if (strip_drv_header(priv, skb) < 0) {
slot = strip_drv_header(priv, skb);
if (slot < 0) {
dev_kfree_skb_any(skb);
continue;
}
Expand Down Expand Up @@ -347,8 +385,7 @@ void ath9k_tx_tasklet(unsigned long data)
sta = ieee80211_find_sta(vif, hdr->addr1);
if (!sta) {
rcu_read_unlock();
ieee80211_tx_status(priv->hw, skb);
continue;
goto send_mac80211;
}

/* Check if we need to start aggregation */
Expand Down Expand Up @@ -380,6 +417,8 @@ void ath9k_tx_tasklet(unsigned long data)
priv->tx.queued_cnt = 0;
spin_unlock_bh(&priv->tx.tx_lock);

ath9k_htc_tx_clear_slot(priv, slot);

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

0 comments on commit 87df6bc

Please sign in to comment.