aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorNishant Sarmukadam <nishants@marvell.com>2011-03-17 14:58:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-03-30 14:15:14 -0400
commit170335432ad36584a6d24fc1fd903024d221ef55 (patch)
treeb940ac56cb95b6aeff039ccc5f04b9198af522cc /drivers/net/wireless/mwl8k.c
parent3aefc37ee789188f0d4488cae04ff618f4c4ddf6 (diff)
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: Nishant Sarmukadam <nishants@marvell.com> Signed-off-by: Brian Cavagnolo <brian@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b90178da5a27..5473f4ca0ca0 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -291,6 +291,7 @@ struct mwl8k_vif {
291struct mwl8k_sta { 291struct mwl8k_sta {
292 /* Index into station database. Returned by UPDATE_STADB. */ 292 /* Index into station database. Returned by UPDATE_STADB. */
293 u8 peer_id; 293 u8 peer_id;
294 u8 is_ampdu_allowed;
294}; 295};
295#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) 296#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
296 297
@@ -1517,6 +1518,27 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1517 MWL8K_TXD_STATUS_OK_RETRY | \ 1518 MWL8K_TXD_STATUS_OK_RETRY | \
1518 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1519 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1519 1520
1521/* The firmware will fill in the rate information
1522 * for each packet that gets queued in the hardware
1523 * in this structure
1524 */
1525
1526struct rateinfo {
1527 __le16 format:1;
1528 __le16 short_gi:1;
1529 __le16 band_width:1;
1530 __le16 rate_id_mcs:6;
1531 __le16 adv_coding:2;
1532 __le16 antenna:2;
1533 __le16 act_sub_chan:2;
1534 __le16 preamble_type:1;
1535 __le16 power_id:4;
1536 __le16 antenna2:1;
1537 __le16 reserved:1;
1538 __le16 tx_bf_frame:1;
1539 __le16 green_field:1;
1540} __packed;
1541
1520static int 1542static int
1521mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) 1543mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1522{ 1544{
@@ -1533,6 +1555,11 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1533 struct sk_buff *skb; 1555 struct sk_buff *skb;
1534 struct ieee80211_tx_info *info; 1556 struct ieee80211_tx_info *info;
1535 u32 status; 1557 u32 status;
1558 struct ieee80211_sta *sta;
1559 struct mwl8k_sta *sta_info = NULL;
1560 u16 rate_info;
1561 struct rateinfo *rate;
1562 struct ieee80211_hdr *wh;
1536 1563
1537 tx = txq->head; 1564 tx = txq->head;
1538 tx_desc = txq->txd + tx; 1565 tx_desc = txq->txd + tx;
@@ -1561,11 +1588,34 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1561 1588
1562 mwl8k_remove_dma_header(skb, tx_desc->qos_control); 1589 mwl8k_remove_dma_header(skb, tx_desc->qos_control);
1563 1590
1591 wh = (struct ieee80211_hdr *) skb->data;
1592
1564 /* Mark descriptor as unused */ 1593 /* Mark descriptor as unused */
1565 tx_desc->pkt_phys_addr = 0; 1594 tx_desc->pkt_phys_addr = 0;
1566 tx_desc->pkt_len = 0; 1595 tx_desc->pkt_len = 0;
1567 1596
1568 info = IEEE80211_SKB_CB(skb); 1597 info = IEEE80211_SKB_CB(skb);
1598 if (ieee80211_is_data(wh->frame_control)) {
1599 sta = info->control.sta;
1600 if (sta) {
1601 sta_info = MWL8K_STA(sta);
1602 BUG_ON(sta_info == NULL);
1603 rate_info = le16_to_cpu(tx_desc->rate_info);
1604 rate = (struct rateinfo *)&rate_info;
1605 /* If rate is < 6.5 Mpbs for an ht station
1606 * do not form an ampdu. If the station is a
1607 * legacy station (format = 0), do not form an
1608 * ampdu
1609 */
1610 if (rate->rate_id_mcs < 1 ||
1611 rate->format == 0) {
1612 sta_info->is_ampdu_allowed = false;
1613 } else {
1614 sta_info->is_ampdu_allowed = true;
1615 }
1616 }
1617 }
1618
1569 ieee80211_tx_info_clear_status(info); 1619 ieee80211_tx_info_clear_status(info);
1570 1620
1571 /* Rate control is happening in the firmware. 1621 /* Rate control is happening in the firmware.
@@ -1784,9 +1834,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1784 * prevents sequence number mismatch at the recepient 1834 * prevents sequence number mismatch at the recepient
1785 * as described above. 1835 * as described above.
1786 */ 1836 */
1787 stream = mwl8k_add_stream(hw, sta, tid); 1837 if (MWL8K_STA(sta)->is_ampdu_allowed) {
1788 if (stream != NULL) 1838 stream = mwl8k_add_stream(hw, sta, tid);
1789 start_ba_session = true; 1839 if (stream != NULL)
1840 start_ba_session = true;
1841 }
1790 } 1842 }
1791 spin_unlock(&priv->stream_lock); 1843 spin_unlock(&priv->stream_lock);
1792 } 1844 }
@@ -4719,6 +4771,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
4719 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); 4771 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
4720 if (ret >= 0) { 4772 if (ret >= 0) {
4721 MWL8K_STA(sta)->peer_id = ret; 4773 MWL8K_STA(sta)->peer_id = ret;
4774 if (sta->ht_cap.ht_supported)
4775 MWL8K_STA(sta)->is_ampdu_allowed = true;
4722 ret = 0; 4776 ret = 0;
4723 } 4777 }
4724 4778