Commit 17033543 authored by Nishant Sarmukadam's avatar Nishant Sarmukadam Committed by John W. Linville

mwl8k: Check outgoing rate for a station to decide if ampdu can be created

If the outgoing packet rate to a particular HT station is <=6.5
Mbps, do not attempt to create an ampdu. Also, if the outgoing
rate is legacy rate, do not create an ampdu.
Signed-off-by: default avatarNishant Sarmukadam <nishants@marvell.com>
Signed-off-by: default avatarBrian Cavagnolo <brian@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3aefc37e
...@@ -291,6 +291,7 @@ struct mwl8k_vif { ...@@ -291,6 +291,7 @@ struct mwl8k_vif {
struct mwl8k_sta { struct mwl8k_sta {
/* Index into station database. Returned by UPDATE_STADB. */ /* Index into station database. Returned by UPDATE_STADB. */
u8 peer_id; u8 peer_id;
u8 is_ampdu_allowed;
}; };
#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
...@@ -1517,6 +1518,27 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) ...@@ -1517,6 +1518,27 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
MWL8K_TXD_STATUS_OK_RETRY | \ MWL8K_TXD_STATUS_OK_RETRY | \
MWL8K_TXD_STATUS_OK_MORE_RETRY)) MWL8K_TXD_STATUS_OK_MORE_RETRY))
/* The firmware will fill in the rate information
* for each packet that gets queued in the hardware
* in this structure
*/
struct rateinfo {
__le16 format:1;
__le16 short_gi:1;
__le16 band_width:1;
__le16 rate_id_mcs:6;
__le16 adv_coding:2;
__le16 antenna:2;
__le16 act_sub_chan:2;
__le16 preamble_type:1;
__le16 power_id:4;
__le16 antenna2:1;
__le16 reserved:1;
__le16 tx_bf_frame:1;
__le16 green_field:1;
} __packed;
static int static int
mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
{ {
...@@ -1533,6 +1555,11 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) ...@@ -1533,6 +1555,11 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
u32 status; u32 status;
struct ieee80211_sta *sta;
struct mwl8k_sta *sta_info = NULL;
u16 rate_info;
struct rateinfo *rate;
struct ieee80211_hdr *wh;
tx = txq->head; tx = txq->head;
tx_desc = txq->txd + tx; tx_desc = txq->txd + tx;
...@@ -1561,11 +1588,34 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) ...@@ -1561,11 +1588,34 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
mwl8k_remove_dma_header(skb, tx_desc->qos_control); mwl8k_remove_dma_header(skb, tx_desc->qos_control);
wh = (struct ieee80211_hdr *) skb->data;
/* Mark descriptor as unused */ /* Mark descriptor as unused */
tx_desc->pkt_phys_addr = 0; tx_desc->pkt_phys_addr = 0;
tx_desc->pkt_len = 0; tx_desc->pkt_len = 0;
info = IEEE80211_SKB_CB(skb); info = IEEE80211_SKB_CB(skb);
if (ieee80211_is_data(wh->frame_control)) {
sta = info->control.sta;
if (sta) {
sta_info = MWL8K_STA(sta);
BUG_ON(sta_info == NULL);
rate_info = le16_to_cpu(tx_desc->rate_info);
rate = (struct rateinfo *)&rate_info;
/* If rate is < 6.5 Mpbs for an ht station
* do not form an ampdu. If the station is a
* legacy station (format = 0), do not form an
* ampdu
*/
if (rate->rate_id_mcs < 1 ||
rate->format == 0) {
sta_info->is_ampdu_allowed = false;
} else {
sta_info->is_ampdu_allowed = true;
}
}
}
ieee80211_tx_info_clear_status(info); ieee80211_tx_info_clear_status(info);
/* Rate control is happening in the firmware. /* Rate control is happening in the firmware.
...@@ -1784,10 +1834,12 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) ...@@ -1784,10 +1834,12 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
* prevents sequence number mismatch at the recepient * prevents sequence number mismatch at the recepient
* as described above. * as described above.
*/ */
if (MWL8K_STA(sta)->is_ampdu_allowed) {
stream = mwl8k_add_stream(hw, sta, tid); stream = mwl8k_add_stream(hw, sta, tid);
if (stream != NULL) if (stream != NULL)
start_ba_session = true; start_ba_session = true;
} }
}
spin_unlock(&priv->stream_lock); spin_unlock(&priv->stream_lock);
} }
...@@ -4719,6 +4771,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw, ...@@ -4719,6 +4771,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
if (ret >= 0) { if (ret >= 0) {
MWL8K_STA(sta)->peer_id = ret; MWL8K_STA(sta)->peer_id = ret;
if (sta->ht_cap.ht_supported)
MWL8K_STA(sta)->is_ampdu_allowed = true;
ret = 0; ret = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment