aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c111
1 files changed, 70 insertions, 41 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 28ebaec80be6..9f5ecef297e5 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -74,6 +74,14 @@ MODULE_PARM_DESC(ap_mode_default,
74#define MWL8K_A2H_INT_RX_READY (1 << 1) 74#define MWL8K_A2H_INT_RX_READY (1 << 1)
75#define MWL8K_A2H_INT_TX_DONE (1 << 0) 75#define MWL8K_A2H_INT_TX_DONE (1 << 0)
76 76
77/* HW micro second timer register
78 * located at offset 0xA600. This
79 * will be used to timestamp tx
80 * packets.
81 */
82
83#define MWL8K_HW_TIMER_REGISTER 0x0000a600
84
77#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \ 85#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
78 MWL8K_A2H_INT_CHNL_SWITCHED | \ 86 MWL8K_A2H_INT_CHNL_SWITCHED | \
79 MWL8K_A2H_INT_QUEUE_EMPTY | \ 87 MWL8K_A2H_INT_QUEUE_EMPTY | \
@@ -773,8 +781,10 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
773 skb_pull(skb, sizeof(*tr) - hdrlen); 781 skb_pull(skb, sizeof(*tr) - hdrlen);
774} 782}
775 783
784#define REDUCED_TX_HEADROOM 8
785
776static void 786static void
777mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) 787mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb, int tail_pad)
778{ 788{
779 struct ieee80211_hdr *wh; 789 struct ieee80211_hdr *wh;
780 int hdrlen; 790 int hdrlen;
@@ -790,6 +800,22 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
790 wh = (struct ieee80211_hdr *)skb->data; 800 wh = (struct ieee80211_hdr *)skb->data;
791 801
792 hdrlen = ieee80211_hdrlen(wh->frame_control); 802 hdrlen = ieee80211_hdrlen(wh->frame_control);
803
804 /*
805 * Check if skb_resize is required because of
806 * tx_headroom adjustment.
807 */
808 if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts)
809 + REDUCED_TX_HEADROOM))) {
810 if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) {
811
812 wiphy_err(priv->hw->wiphy,
813 "Failed to reallocate TX buffer\n");
814 return;
815 }
816 skb->truesize += REDUCED_TX_HEADROOM;
817 }
818
793 reqd_hdrlen = sizeof(*tr); 819 reqd_hdrlen = sizeof(*tr);
794 820
795 if (hdrlen != reqd_hdrlen) 821 if (hdrlen != reqd_hdrlen)
@@ -812,7 +838,8 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
812 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); 838 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
813} 839}
814 840
815static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) 841static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
842 struct sk_buff *skb)
816{ 843{
817 struct ieee80211_hdr *wh; 844 struct ieee80211_hdr *wh;
818 struct ieee80211_tx_info *tx_info; 845 struct ieee80211_tx_info *tx_info;
@@ -853,7 +880,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
853 break; 880 break;
854 } 881 }
855 } 882 }
856 mwl8k_add_dma_header(skb, data_pad); 883 mwl8k_add_dma_header(priv, skb, data_pad);
857} 884}
858 885
859/* 886/*
@@ -1554,24 +1581,11 @@ static int mwl8k_tid_queue_mapping(u8 tid)
1554 1581
1555/* The firmware will fill in the rate information 1582/* The firmware will fill in the rate information
1556 * for each packet that gets queued in the hardware 1583 * for each packet that gets queued in the hardware
1557 * in this structure 1584 * and these macros will interpret that info.
1558 */ 1585 */
1559 1586
1560struct rateinfo { 1587#define RI_FORMAT(a) (a & 0x0001)
1561 __le16 format:1; 1588#define RI_RATE_ID_MCS(a) ((a & 0x01f8) >> 3)
1562 __le16 short_gi:1;
1563 __le16 band_width:1;
1564 __le16 rate_id_mcs:6;
1565 __le16 adv_coding:2;
1566 __le16 antenna:2;
1567 __le16 act_sub_chan:2;
1568 __le16 preamble_type:1;
1569 __le16 power_id:4;
1570 __le16 antenna2:1;
1571 __le16 reserved:1;
1572 __le16 tx_bf_frame:1;
1573 __le16 green_field:1;
1574} __packed;
1575 1589
1576static int 1590static int
1577mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) 1591mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
@@ -1592,7 +1606,6 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1592 struct ieee80211_sta *sta; 1606 struct ieee80211_sta *sta;
1593 struct mwl8k_sta *sta_info = NULL; 1607 struct mwl8k_sta *sta_info = NULL;
1594 u16 rate_info; 1608 u16 rate_info;
1595 struct rateinfo *rate;
1596 struct ieee80211_hdr *wh; 1609 struct ieee80211_hdr *wh;
1597 1610
1598 tx = txq->head; 1611 tx = txq->head;
@@ -1635,14 +1648,13 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1635 sta_info = MWL8K_STA(sta); 1648 sta_info = MWL8K_STA(sta);
1636 BUG_ON(sta_info == NULL); 1649 BUG_ON(sta_info == NULL);
1637 rate_info = le16_to_cpu(tx_desc->rate_info); 1650 rate_info = le16_to_cpu(tx_desc->rate_info);
1638 rate = (struct rateinfo *)&rate_info;
1639 /* If rate is < 6.5 Mpbs for an ht station 1651 /* If rate is < 6.5 Mpbs for an ht station
1640 * do not form an ampdu. If the station is a 1652 * do not form an ampdu. If the station is a
1641 * legacy station (format = 0), do not form an 1653 * legacy station (format = 0), do not form an
1642 * ampdu 1654 * ampdu
1643 */ 1655 */
1644 if (rate->rate_id_mcs < 1 || 1656 if (RI_RATE_ID_MCS(rate_info) < 1 ||
1645 rate->format == 0) { 1657 RI_FORMAT(rate_info) == 0) {
1646 sta_info->is_ampdu_allowed = false; 1658 sta_info->is_ampdu_allowed = false;
1647 } else { 1659 } else {
1648 sta_info->is_ampdu_allowed = true; 1660 sta_info->is_ampdu_allowed = true;
@@ -1666,10 +1678,6 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1666 processed++; 1678 processed++;
1667 } 1679 }
1668 1680
1669 if (index < MWL8K_TX_WMM_QUEUES && processed && priv->radio_on &&
1670 !mutex_is_locked(&priv->fw_mutex))
1671 ieee80211_wake_queue(hw, index);
1672
1673 return processed; 1681 return processed;
1674} 1682}
1675 1683
@@ -1814,6 +1822,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1814 u8 tid = 0; 1822 u8 tid = 0;
1815 struct mwl8k_ampdu_stream *stream = NULL; 1823 struct mwl8k_ampdu_stream *stream = NULL;
1816 bool start_ba_session = false; 1824 bool start_ba_session = false;
1825 bool mgmtframe = false;
1817 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1826 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1818 1827
1819 wh = (struct ieee80211_hdr *)skb->data; 1828 wh = (struct ieee80211_hdr *)skb->data;
@@ -1822,10 +1831,13 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1822 else 1831 else
1823 qos = 0; 1832 qos = 0;
1824 1833
1834 if (ieee80211_is_mgmt(wh->frame_control))
1835 mgmtframe = true;
1836
1825 if (priv->ap_fw) 1837 if (priv->ap_fw)
1826 mwl8k_encapsulate_tx_frame(skb); 1838 mwl8k_encapsulate_tx_frame(priv, skb);
1827 else 1839 else
1828 mwl8k_add_dma_header(skb, 0); 1840 mwl8k_add_dma_header(priv, skb, 0);
1829 1841
1830 wh = &((struct mwl8k_dma_data *)skb->data)->wh; 1842 wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1831 1843
@@ -1951,14 +1963,26 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1951 1963
1952 txq = priv->txq + index; 1964 txq = priv->txq + index;
1953 1965
1954 if (index >= MWL8K_TX_WMM_QUEUES && txq->len >= MWL8K_TX_DESCS) { 1966 /* Mgmt frames that go out frequently are probe
1955 /* This is the case in which the tx packet is destined for an 1967 * responses. Other mgmt frames got out relatively
1956 * AMPDU queue and that AMPDU queue is full. Because we don't 1968 * infrequently. Hence reserve 2 buffers so that
1957 * start and stop the AMPDU queues, we must drop these packets. 1969 * other mgmt frames do not get dropped due to an
1958 */ 1970 * already queued probe response in one of the
1959 dev_kfree_skb(skb); 1971 * reserved buffers.
1960 spin_unlock_bh(&priv->tx_lock); 1972 */
1961 return; 1973
1974 if (txq->len >= MWL8K_TX_DESCS - 2) {
1975 if (mgmtframe == false ||
1976 txq->len == MWL8K_TX_DESCS) {
1977 if (start_ba_session) {
1978 spin_lock(&priv->stream_lock);
1979 mwl8k_remove_stream(hw, stream);
1980 spin_unlock(&priv->stream_lock);
1981 }
1982 spin_unlock_bh(&priv->tx_lock);
1983 dev_kfree_skb(skb);
1984 return;
1985 }
1962 } 1986 }
1963 1987
1964 BUG_ON(txq->skb[txq->tail] != NULL); 1988 BUG_ON(txq->skb[txq->tail] != NULL);
@@ -1975,6 +1999,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1975 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; 1999 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
1976 else 2000 else
1977 tx->peer_id = 0; 2001 tx->peer_id = 0;
2002
2003 if (priv->ap_fw)
2004 tx->timestamp = cpu_to_le32(ioread32(priv->regs +
2005 MWL8K_HW_TIMER_REGISTER));
2006
1978 wmb(); 2007 wmb();
1979 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 2008 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1980 2009
@@ -1985,9 +2014,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1985 if (txq->tail == MWL8K_TX_DESCS) 2014 if (txq->tail == MWL8K_TX_DESCS)
1986 txq->tail = 0; 2015 txq->tail = 0;
1987 2016
1988 if (txq->head == txq->tail && index < MWL8K_TX_WMM_QUEUES)
1989 ieee80211_stop_queue(hw, index);
1990
1991 mwl8k_tx_start(priv); 2017 mwl8k_tx_start(priv);
1992 2018
1993 spin_unlock_bh(&priv->tx_lock); 2019 spin_unlock_bh(&priv->tx_lock);
@@ -2482,7 +2508,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
2482 2508
2483 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | 2509 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
2484 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | 2510 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
2485 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON); 2511 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON |
2512 MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY);
2486 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 2513 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
2487 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 2514 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
2488 2515
@@ -5466,6 +5493,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5466 hw->extra_tx_headroom = 5493 hw->extra_tx_headroom =
5467 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); 5494 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
5468 5495
5496 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0;
5497
5469 hw->channel_change_time = 10; 5498 hw->channel_change_time = 10;
5470 5499
5471 hw->queues = MWL8K_TX_WMM_QUEUES; 5500 hw->queues = MWL8K_TX_WMM_QUEUES;