mwl8k: Queue ADDBA requests in respective data queues

Queue ADDBA requests in respective data queues to avoid ADDBA
requests and the the related data packets (to the same ra/tid)
queued in the hardware to be sent out asynchronously.

Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Brian Cavagnolo <brian@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Nishant Sarmukadam 2011-03-17 11:58:49 -07:00 committed by John W. Linville
parent 170335432a
commit a0e7c6cfe2

View File

@ -1518,6 +1518,33 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
MWL8K_TXD_STATUS_OK_RETRY | \
MWL8K_TXD_STATUS_OK_MORE_RETRY))
static int mwl8k_tid_queue_mapping(u8 tid)
{
BUG_ON(tid > 7);
switch (tid) {
case 0:
case 3:
return IEEE80211_AC_BE;
break;
case 1:
case 2:
return IEEE80211_AC_BK;
break;
case 4:
case 5:
return IEEE80211_AC_VI;
break;
case 6:
case 7:
return IEEE80211_AC_VO;
break;
default:
return -1;
break;
}
}
/* The firmware will fill in the rate information
* for each packet that gets queued in the hardware
* in this structure
@ -1745,6 +1772,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
u8 tid = 0;
struct mwl8k_ampdu_stream *stream = NULL;
bool start_ba_session = false;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
wh = (struct ieee80211_hdr *)skb->data;
if (ieee80211_is_data_qos(wh->frame_control))
@ -1788,6 +1816,24 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
}
/* Queue ADDBA request in the respective data queue. While setting up
* the ampdu stream, mac80211 queues further packets for that
* particular ra/tid pair. However, packets piled up in the hardware
* for that ra/tid pair will still go out. ADDBA request and the
* related data packets going out from different queues asynchronously
* will cause a shift in the receiver window which might result in
* ampdu packets getting dropped at the receiver after the stream has
* been setup.
*/
if (unlikely(ieee80211_is_action(wh->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
priv->ap_fw)) {
u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
index = mwl8k_tid_queue_mapping(tid);
}
txpriority = index;
if (ieee80211_is_data_qos(wh->frame_control) &&