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.c818
1 files changed, 755 insertions, 63 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index c1ceb4b23971..28ebaec80be6 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -63,6 +63,7 @@ MODULE_PARM_DESC(ap_mode_default,
63#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38 63#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
64#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c 64#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
65#define MWL8K_A2H_INT_DUMMY (1 << 20) 65#define MWL8K_A2H_INT_DUMMY (1 << 20)
66#define MWL8K_A2H_INT_BA_WATCHDOG (1 << 14)
66#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11) 67#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
67#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10) 68#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
68#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7) 69#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
@@ -82,10 +83,14 @@ MODULE_PARM_DESC(ap_mode_default,
82 MWL8K_A2H_INT_MAC_EVENT | \ 83 MWL8K_A2H_INT_MAC_EVENT | \
83 MWL8K_A2H_INT_OPC_DONE | \ 84 MWL8K_A2H_INT_OPC_DONE | \
84 MWL8K_A2H_INT_RX_READY | \ 85 MWL8K_A2H_INT_RX_READY | \
85 MWL8K_A2H_INT_TX_DONE) 86 MWL8K_A2H_INT_TX_DONE | \
87 MWL8K_A2H_INT_BA_WATCHDOG)
86 88
87#define MWL8K_RX_QUEUES 1 89#define MWL8K_RX_QUEUES 1
88#define MWL8K_TX_QUEUES 4 90#define MWL8K_TX_WMM_QUEUES 4
91#define MWL8K_MAX_AMPDU_QUEUES 8
92#define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
93#define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
89 94
90struct rxd_ops { 95struct rxd_ops {
91 int rxd_size; 96 int rxd_size;
@@ -134,6 +139,21 @@ struct mwl8k_tx_queue {
134 struct sk_buff **skb; 139 struct sk_buff **skb;
135}; 140};
136 141
142enum {
143 AMPDU_NO_STREAM,
144 AMPDU_STREAM_NEW,
145 AMPDU_STREAM_IN_PROGRESS,
146 AMPDU_STREAM_ACTIVE,
147};
148
149struct mwl8k_ampdu_stream {
150 struct ieee80211_sta *sta;
151 u8 tid;
152 u8 state;
153 u8 idx;
154 u8 txq_idx; /* index of this stream in priv->txq */
155};
156
137struct mwl8k_priv { 157struct mwl8k_priv {
138 struct ieee80211_hw *hw; 158 struct ieee80211_hw *hw;
139 struct pci_dev *pdev; 159 struct pci_dev *pdev;
@@ -160,6 +180,12 @@ struct mwl8k_priv {
160 u32 ap_macids_supported; 180 u32 ap_macids_supported;
161 u32 sta_macids_supported; 181 u32 sta_macids_supported;
162 182
183 /* Ampdu stream information */
184 u8 num_ampdu_queues;
185 spinlock_t stream_lock;
186 struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
187 struct work_struct watchdog_ba_handle;
188
163 /* firmware access */ 189 /* firmware access */
164 struct mutex fw_mutex; 190 struct mutex fw_mutex;
165 struct task_struct *fw_mutex_owner; 191 struct task_struct *fw_mutex_owner;
@@ -191,7 +217,8 @@ struct mwl8k_priv {
191 int pending_tx_pkts; 217 int pending_tx_pkts;
192 218
193 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 219 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
194 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 220 struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
221 u32 txq_offset[MWL8K_MAX_TX_QUEUES];
195 222
196 bool radio_on; 223 bool radio_on;
197 bool radio_short_preamble; 224 bool radio_short_preamble;
@@ -224,7 +251,7 @@ struct mwl8k_priv {
224 * preserve the queue configurations so they can be restored if/when 251 * preserve the queue configurations so they can be restored if/when
225 * the firmware image is swapped. 252 * the firmware image is swapped.
226 */ 253 */
227 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES]; 254 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
228 255
229 /* async firmware loading state */ 256 /* async firmware loading state */
230 unsigned fw_state; 257 unsigned fw_state;
@@ -262,9 +289,17 @@ struct mwl8k_vif {
262#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 289#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
263#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) 290#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
264 291
292struct tx_traffic_info {
293 u32 start_time;
294 u32 pkts;
295};
296
297#define MWL8K_MAX_TID 8
265struct mwl8k_sta { 298struct mwl8k_sta {
266 /* Index into station database. Returned by UPDATE_STADB. */ 299 /* Index into station database. Returned by UPDATE_STADB. */
267 u8 peer_id; 300 u8 peer_id;
301 u8 is_ampdu_allowed;
302 struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
268}; 303};
269#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) 304#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
270 305
@@ -352,10 +387,12 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
352#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 387#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
353#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */ 388#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
354#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 389#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
390#define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205
355#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ 391#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
356#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ 392#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
357#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ 393#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
358#define MWL8K_CMD_UPDATE_STADB 0x1123 394#define MWL8K_CMD_UPDATE_STADB 0x1123
395#define MWL8K_CMD_BASTREAM 0x1125
359 396
360static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) 397static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
361{ 398{
@@ -395,6 +432,8 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
395 MWL8K_CMDNAME(SET_NEW_STN); 432 MWL8K_CMDNAME(SET_NEW_STN);
396 MWL8K_CMDNAME(UPDATE_ENCRYPTION); 433 MWL8K_CMDNAME(UPDATE_ENCRYPTION);
397 MWL8K_CMDNAME(UPDATE_STADB); 434 MWL8K_CMDNAME(UPDATE_STADB);
435 MWL8K_CMDNAME(BASTREAM);
436 MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
398 default: 437 default:
399 snprintf(buf, bufsize, "0x%x", cmd); 438 snprintf(buf, bufsize, "0x%x", cmd);
400 } 439 }
@@ -669,7 +708,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
669 "helper image\n", pci_name(priv->pdev)); 708 "helper image\n", pci_name(priv->pdev));
670 return rc; 709 return rc;
671 } 710 }
672 msleep(5); 711 msleep(20);
673 712
674 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); 713 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
675 } else { 714 } else {
@@ -791,8 +830,8 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
791 /* 830 /*
792 * Make sure the packet header is in the DMA header format (4-address 831 * Make sure the packet header is in the DMA header format (4-address
793 * without QoS), the necessary crypto padding between the header and the 832 * without QoS), the necessary crypto padding between the header and the
794 * payload has already been provided by mac80211, but it doesn't add tail 833 * payload has already been provided by mac80211, but it doesn't add
795 * padding when HW crypto is enabled. 834 * tail padding when HW crypto is enabled.
796 * 835 *
797 * We have the following trailer padding requirements: 836 * We have the following trailer padding requirements:
798 * - WEP: 4 trailer bytes (ICV) 837 * - WEP: 4 trailer bytes (ICV)
@@ -1127,6 +1166,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
1127 struct mwl8k_rx_queue *rxq = priv->rxq + index; 1166 struct mwl8k_rx_queue *rxq = priv->rxq + index;
1128 int i; 1167 int i;
1129 1168
1169 if (rxq->rxd == NULL)
1170 return;
1171
1130 for (i = 0; i < MWL8K_RX_DESCS; i++) { 1172 for (i = 0; i < MWL8K_RX_DESCS; i++) {
1131 if (rxq->buf[i].skb != NULL) { 1173 if (rxq->buf[i].skb != NULL) {
1132 pci_unmap_single(priv->pdev, 1174 pci_unmap_single(priv->pdev,
@@ -1319,7 +1361,7 @@ struct mwl8k_tx_desc {
1319 __le16 pkt_len; 1361 __le16 pkt_len;
1320 __u8 dest_MAC_addr[ETH_ALEN]; 1362 __u8 dest_MAC_addr[ETH_ALEN];
1321 __le32 next_txd_phys_addr; 1363 __le32 next_txd_phys_addr;
1322 __le32 reserved; 1364 __le32 timestamp;
1323 __le16 rate_info; 1365 __le16 rate_info;
1324 __u8 peer_id; 1366 __u8 peer_id;
1325 __u8 tx_frag_cnt; 1367 __u8 tx_frag_cnt;
@@ -1383,7 +1425,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1383 struct mwl8k_priv *priv = hw->priv; 1425 struct mwl8k_priv *priv = hw->priv;
1384 int i; 1426 int i;
1385 1427
1386 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 1428 for (i = 0; i < mwl8k_tx_queues(priv); i++) {
1387 struct mwl8k_tx_queue *txq = priv->txq + i; 1429 struct mwl8k_tx_queue *txq = priv->txq + i;
1388 int fw_owned = 0; 1430 int fw_owned = 0;
1389 int drv_owned = 0; 1431 int drv_owned = 0;
@@ -1452,9 +1494,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1452 1494
1453 if (timeout) { 1495 if (timeout) {
1454 WARN_ON(priv->pending_tx_pkts); 1496 WARN_ON(priv->pending_tx_pkts);
1455 if (retry) { 1497 if (retry)
1456 wiphy_notice(hw->wiphy, "tx rings drained\n"); 1498 wiphy_notice(hw->wiphy, "tx rings drained\n");
1457 }
1458 break; 1499 break;
1459 } 1500 }
1460 1501
@@ -1484,6 +1525,54 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1484 MWL8K_TXD_STATUS_OK_RETRY | \ 1525 MWL8K_TXD_STATUS_OK_RETRY | \
1485 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1526 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1486 1527
1528static int mwl8k_tid_queue_mapping(u8 tid)
1529{
1530 BUG_ON(tid > 7);
1531
1532 switch (tid) {
1533 case 0:
1534 case 3:
1535 return IEEE80211_AC_BE;
1536 break;
1537 case 1:
1538 case 2:
1539 return IEEE80211_AC_BK;
1540 break;
1541 case 4:
1542 case 5:
1543 return IEEE80211_AC_VI;
1544 break;
1545 case 6:
1546 case 7:
1547 return IEEE80211_AC_VO;
1548 break;
1549 default:
1550 return -1;
1551 break;
1552 }
1553}
1554
1555/* The firmware will fill in the rate information
1556 * for each packet that gets queued in the hardware
1557 * in this structure
1558 */
1559
1560struct rateinfo {
1561 __le16 format:1;
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
1487static int 1576static int
1488mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) 1577mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1489{ 1578{
@@ -1500,6 +1589,11 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1500 struct sk_buff *skb; 1589 struct sk_buff *skb;
1501 struct ieee80211_tx_info *info; 1590 struct ieee80211_tx_info *info;
1502 u32 status; 1591 u32 status;
1592 struct ieee80211_sta *sta;
1593 struct mwl8k_sta *sta_info = NULL;
1594 u16 rate_info;
1595 struct rateinfo *rate;
1596 struct ieee80211_hdr *wh;
1503 1597
1504 tx = txq->head; 1598 tx = txq->head;
1505 tx_desc = txq->txd + tx; 1599 tx_desc = txq->txd + tx;
@@ -1528,18 +1622,41 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1528 1622
1529 mwl8k_remove_dma_header(skb, tx_desc->qos_control); 1623 mwl8k_remove_dma_header(skb, tx_desc->qos_control);
1530 1624
1625 wh = (struct ieee80211_hdr *) skb->data;
1626
1531 /* Mark descriptor as unused */ 1627 /* Mark descriptor as unused */
1532 tx_desc->pkt_phys_addr = 0; 1628 tx_desc->pkt_phys_addr = 0;
1533 tx_desc->pkt_len = 0; 1629 tx_desc->pkt_len = 0;
1534 1630
1535 info = IEEE80211_SKB_CB(skb); 1631 info = IEEE80211_SKB_CB(skb);
1632 if (ieee80211_is_data(wh->frame_control)) {
1633 sta = info->control.sta;
1634 if (sta) {
1635 sta_info = MWL8K_STA(sta);
1636 BUG_ON(sta_info == NULL);
1637 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
1640 * do not form an ampdu. If the station is a
1641 * legacy station (format = 0), do not form an
1642 * ampdu
1643 */
1644 if (rate->rate_id_mcs < 1 ||
1645 rate->format == 0) {
1646 sta_info->is_ampdu_allowed = false;
1647 } else {
1648 sta_info->is_ampdu_allowed = true;
1649 }
1650 }
1651 }
1652
1536 ieee80211_tx_info_clear_status(info); 1653 ieee80211_tx_info_clear_status(info);
1537 1654
1538 /* Rate control is happening in the firmware. 1655 /* Rate control is happening in the firmware.
1539 * Ensure no tx rate is being reported. 1656 * Ensure no tx rate is being reported.
1540 */ 1657 */
1541 info->status.rates[0].idx = -1; 1658 info->status.rates[0].idx = -1;
1542 info->status.rates[0].count = 1; 1659 info->status.rates[0].count = 1;
1543 1660
1544 if (MWL8K_TXD_SUCCESS(status)) 1661 if (MWL8K_TXD_SUCCESS(status))
1545 info->flags |= IEEE80211_TX_STAT_ACK; 1662 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1549,7 +1666,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1549 processed++; 1666 processed++;
1550 } 1667 }
1551 1668
1552 if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) 1669 if (index < MWL8K_TX_WMM_QUEUES && processed && priv->radio_on &&
1670 !mutex_is_locked(&priv->fw_mutex))
1553 ieee80211_wake_queue(hw, index); 1671 ieee80211_wake_queue(hw, index);
1554 1672
1555 return processed; 1673 return processed;
@@ -1561,6 +1679,9 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1561 struct mwl8k_priv *priv = hw->priv; 1679 struct mwl8k_priv *priv = hw->priv;
1562 struct mwl8k_tx_queue *txq = priv->txq + index; 1680 struct mwl8k_tx_queue *txq = priv->txq + index;
1563 1681
1682 if (txq->txd == NULL)
1683 return;
1684
1564 mwl8k_txq_reclaim(hw, index, INT_MAX, 1); 1685 mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1565 1686
1566 kfree(txq->skb); 1687 kfree(txq->skb);
@@ -1572,12 +1693,116 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1572 txq->txd = NULL; 1693 txq->txd = NULL;
1573} 1694}
1574 1695
1696/* caller must hold priv->stream_lock when calling the stream functions */
1697static struct mwl8k_ampdu_stream *
1698mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
1699{
1700 struct mwl8k_ampdu_stream *stream;
1701 struct mwl8k_priv *priv = hw->priv;
1702 int i;
1703
1704 for (i = 0; i < priv->num_ampdu_queues; i++) {
1705 stream = &priv->ampdu[i];
1706 if (stream->state == AMPDU_NO_STREAM) {
1707 stream->sta = sta;
1708 stream->state = AMPDU_STREAM_NEW;
1709 stream->tid = tid;
1710 stream->idx = i;
1711 stream->txq_idx = MWL8K_TX_WMM_QUEUES + i;
1712 wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
1713 sta->addr, tid);
1714 return stream;
1715 }
1716 }
1717 return NULL;
1718}
1719
1720static int
1721mwl8k_start_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
1722{
1723 int ret;
1724
1725 /* if the stream has already been started, don't start it again */
1726 if (stream->state != AMPDU_STREAM_NEW)
1727 return 0;
1728 ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0);
1729 if (ret)
1730 wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: "
1731 "%d\n", stream->sta->addr, stream->tid, ret);
1732 else
1733 wiphy_debug(hw->wiphy, "Started stream for %pM %d\n",
1734 stream->sta->addr, stream->tid);
1735 return ret;
1736}
1737
1738static void
1739mwl8k_remove_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
1740{
1741 wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr,
1742 stream->tid);
1743 memset(stream, 0, sizeof(*stream));
1744}
1745
1746static struct mwl8k_ampdu_stream *
1747mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
1748{
1749 struct mwl8k_priv *priv = hw->priv;
1750 int i;
1751
1752 for (i = 0 ; i < priv->num_ampdu_queues; i++) {
1753 struct mwl8k_ampdu_stream *stream;
1754 stream = &priv->ampdu[i];
1755 if (stream->state == AMPDU_NO_STREAM)
1756 continue;
1757 if (!memcmp(stream->sta->addr, addr, ETH_ALEN) &&
1758 stream->tid == tid)
1759 return stream;
1760 }
1761 return NULL;
1762}
1763
1764#define MWL8K_AMPDU_PACKET_THRESHOLD 64
1765static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid)
1766{
1767 struct mwl8k_sta *sta_info = MWL8K_STA(sta);
1768 struct tx_traffic_info *tx_stats;
1769
1770 BUG_ON(tid >= MWL8K_MAX_TID);
1771 tx_stats = &sta_info->tx_stats[tid];
1772
1773 return sta_info->is_ampdu_allowed &&
1774 tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD;
1775}
1776
1777static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
1778{
1779 struct mwl8k_sta *sta_info = MWL8K_STA(sta);
1780 struct tx_traffic_info *tx_stats;
1781
1782 BUG_ON(tid >= MWL8K_MAX_TID);
1783 tx_stats = &sta_info->tx_stats[tid];
1784
1785 if (tx_stats->start_time == 0)
1786 tx_stats->start_time = jiffies;
1787
1788 /* reset the packet count after each second elapses. If the number of
1789 * packets ever exceeds the ampdu_min_traffic threshold, we will allow
1790 * an ampdu stream to be started.
1791 */
1792 if (jiffies - tx_stats->start_time > HZ) {
1793 tx_stats->pkts = 0;
1794 tx_stats->start_time = 0;
1795 } else
1796 tx_stats->pkts++;
1797}
1798
1575static void 1799static void
1576mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) 1800mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1577{ 1801{
1578 struct mwl8k_priv *priv = hw->priv; 1802 struct mwl8k_priv *priv = hw->priv;
1579 struct ieee80211_tx_info *tx_info; 1803 struct ieee80211_tx_info *tx_info;
1580 struct mwl8k_vif *mwl8k_vif; 1804 struct mwl8k_vif *mwl8k_vif;
1805 struct ieee80211_sta *sta;
1581 struct ieee80211_hdr *wh; 1806 struct ieee80211_hdr *wh;
1582 struct mwl8k_tx_queue *txq; 1807 struct mwl8k_tx_queue *txq;
1583 struct mwl8k_tx_desc *tx; 1808 struct mwl8k_tx_desc *tx;
@@ -1585,6 +1810,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1585 u32 txstatus; 1810 u32 txstatus;
1586 u8 txdatarate; 1811 u8 txdatarate;
1587 u16 qos; 1812 u16 qos;
1813 int txpriority;
1814 u8 tid = 0;
1815 struct mwl8k_ampdu_stream *stream = NULL;
1816 bool start_ba_session = false;
1817 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1588 1818
1589 wh = (struct ieee80211_hdr *)skb->data; 1819 wh = (struct ieee80211_hdr *)skb->data;
1590 if (ieee80211_is_data_qos(wh->frame_control)) 1820 if (ieee80211_is_data_qos(wh->frame_control))
@@ -1600,6 +1830,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1600 wh = &((struct mwl8k_dma_data *)skb->data)->wh; 1830 wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1601 1831
1602 tx_info = IEEE80211_SKB_CB(skb); 1832 tx_info = IEEE80211_SKB_CB(skb);
1833 sta = tx_info->control.sta;
1603 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1834 mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1604 1835
1605 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1836 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -1627,12 +1858,91 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1627 qos |= MWL8K_QOS_ACK_POLICY_NORMAL; 1858 qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
1628 } 1859 }
1629 1860
1861 /* Queue ADDBA request in the respective data queue. While setting up
1862 * the ampdu stream, mac80211 queues further packets for that
1863 * particular ra/tid pair. However, packets piled up in the hardware
1864 * for that ra/tid pair will still go out. ADDBA request and the
1865 * related data packets going out from different queues asynchronously
1866 * will cause a shift in the receiver window which might result in
1867 * ampdu packets getting dropped at the receiver after the stream has
1868 * been setup.
1869 */
1870 if (unlikely(ieee80211_is_action(wh->frame_control) &&
1871 mgmt->u.action.category == WLAN_CATEGORY_BACK &&
1872 mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
1873 priv->ap_fw)) {
1874 u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
1875 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1876 index = mwl8k_tid_queue_mapping(tid);
1877 }
1878
1879 txpriority = index;
1880
1881 if (ieee80211_is_data_qos(wh->frame_control) &&
1882 skb->protocol != cpu_to_be16(ETH_P_PAE) &&
1883 sta->ht_cap.ht_supported && priv->ap_fw) {
1884 tid = qos & 0xf;
1885 mwl8k_tx_count_packet(sta, tid);
1886 spin_lock(&priv->stream_lock);
1887 stream = mwl8k_lookup_stream(hw, sta->addr, tid);
1888 if (stream != NULL) {
1889 if (stream->state == AMPDU_STREAM_ACTIVE) {
1890 txpriority = stream->txq_idx;
1891 index = stream->txq_idx;
1892 } else if (stream->state == AMPDU_STREAM_NEW) {
1893 /* We get here if the driver sends us packets
1894 * after we've initiated a stream, but before
1895 * our ampdu_action routine has been called
1896 * with IEEE80211_AMPDU_TX_START to get the SSN
1897 * for the ADDBA request. So this packet can
1898 * go out with no risk of sequence number
1899 * mismatch. No special handling is required.
1900 */
1901 } else {
1902 /* Drop packets that would go out after the
1903 * ADDBA request was sent but before the ADDBA
1904 * response is received. If we don't do this,
1905 * the recipient would probably receive it
1906 * after the ADDBA request with SSN 0. This
1907 * will cause the recipient's BA receive window
1908 * to shift, which would cause the subsequent
1909 * packets in the BA stream to be discarded.
1910 * mac80211 queues our packets for us in this
1911 * case, so this is really just a safety check.
1912 */
1913 wiphy_warn(hw->wiphy,
1914 "Cannot send packet while ADDBA "
1915 "dialog is underway.\n");
1916 spin_unlock(&priv->stream_lock);
1917 dev_kfree_skb(skb);
1918 return;
1919 }
1920 } else {
1921 /* Defer calling mwl8k_start_stream so that the current
1922 * skb can go out before the ADDBA request. This
1923 * prevents sequence number mismatch at the recepient
1924 * as described above.
1925 */
1926 if (mwl8k_ampdu_allowed(sta, tid)) {
1927 stream = mwl8k_add_stream(hw, sta, tid);
1928 if (stream != NULL)
1929 start_ba_session = true;
1930 }
1931 }
1932 spin_unlock(&priv->stream_lock);
1933 }
1934
1630 dma = pci_map_single(priv->pdev, skb->data, 1935 dma = pci_map_single(priv->pdev, skb->data,
1631 skb->len, PCI_DMA_TODEVICE); 1936 skb->len, PCI_DMA_TODEVICE);
1632 1937
1633 if (pci_dma_mapping_error(priv->pdev, dma)) { 1938 if (pci_dma_mapping_error(priv->pdev, dma)) {
1634 wiphy_debug(hw->wiphy, 1939 wiphy_debug(hw->wiphy,
1635 "failed to dma map skb, dropping TX frame.\n"); 1940 "failed to dma map skb, dropping TX frame.\n");
1941 if (start_ba_session) {
1942 spin_lock(&priv->stream_lock);
1943 mwl8k_remove_stream(hw, stream);
1944 spin_unlock(&priv->stream_lock);
1945 }
1636 dev_kfree_skb(skb); 1946 dev_kfree_skb(skb);
1637 return; 1947 return;
1638 } 1948 }
@@ -1641,12 +1951,22 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1641 1951
1642 txq = priv->txq + index; 1952 txq = priv->txq + index;
1643 1953
1954 if (index >= MWL8K_TX_WMM_QUEUES && txq->len >= MWL8K_TX_DESCS) {
1955 /* This is the case in which the tx packet is destined for an
1956 * AMPDU queue and that AMPDU queue is full. Because we don't
1957 * start and stop the AMPDU queues, we must drop these packets.
1958 */
1959 dev_kfree_skb(skb);
1960 spin_unlock_bh(&priv->tx_lock);
1961 return;
1962 }
1963
1644 BUG_ON(txq->skb[txq->tail] != NULL); 1964 BUG_ON(txq->skb[txq->tail] != NULL);
1645 txq->skb[txq->tail] = skb; 1965 txq->skb[txq->tail] = skb;
1646 1966
1647 tx = txq->txd + txq->tail; 1967 tx = txq->txd + txq->tail;
1648 tx->data_rate = txdatarate; 1968 tx->data_rate = txdatarate;
1649 tx->tx_priority = index; 1969 tx->tx_priority = txpriority;
1650 tx->qos_control = cpu_to_le16(qos); 1970 tx->qos_control = cpu_to_le16(qos);
1651 tx->pkt_phys_addr = cpu_to_le32(dma); 1971 tx->pkt_phys_addr = cpu_to_le32(dma);
1652 tx->pkt_len = cpu_to_le16(skb->len); 1972 tx->pkt_len = cpu_to_le16(skb->len);
@@ -1665,12 +1985,20 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1665 if (txq->tail == MWL8K_TX_DESCS) 1985 if (txq->tail == MWL8K_TX_DESCS)
1666 txq->tail = 0; 1986 txq->tail = 0;
1667 1987
1668 if (txq->head == txq->tail) 1988 if (txq->head == txq->tail && index < MWL8K_TX_WMM_QUEUES)
1669 ieee80211_stop_queue(hw, index); 1989 ieee80211_stop_queue(hw, index);
1670 1990
1671 mwl8k_tx_start(priv); 1991 mwl8k_tx_start(priv);
1672 1992
1673 spin_unlock_bh(&priv->tx_lock); 1993 spin_unlock_bh(&priv->tx_lock);
1994
1995 /* Initiate the ampdu session here */
1996 if (start_ba_session) {
1997 spin_lock(&priv->stream_lock);
1998 if (mwl8k_start_stream(hw, stream))
1999 mwl8k_remove_stream(hw, stream);
2000 spin_unlock(&priv->stream_lock);
2001 }
1674} 2002}
1675 2003
1676 2004
@@ -1868,7 +2196,7 @@ struct mwl8k_cmd_get_hw_spec_sta {
1868 __u8 mcs_bitmap[16]; 2196 __u8 mcs_bitmap[16];
1869 __le32 rx_queue_ptr; 2197 __le32 rx_queue_ptr;
1870 __le32 num_tx_queues; 2198 __le32 num_tx_queues;
1871 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 2199 __le32 tx_queue_ptrs[MWL8K_TX_WMM_QUEUES];
1872 __le32 caps2; 2200 __le32 caps2;
1873 __le32 num_tx_desc_per_queue; 2201 __le32 num_tx_desc_per_queue;
1874 __le32 total_rxd; 2202 __le32 total_rxd;
@@ -1974,8 +2302,8 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1974 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); 2302 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1975 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 2303 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1976 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); 2304 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1977 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 2305 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
1978 for (i = 0; i < MWL8K_TX_QUEUES; i++) 2306 for (i = 0; i < mwl8k_tx_queues(priv); i++)
1979 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); 2307 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1980 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 2308 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1981 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 2309 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
@@ -2017,13 +2345,16 @@ struct mwl8k_cmd_get_hw_spec_ap {
2017 __le32 wcbbase2; 2345 __le32 wcbbase2;
2018 __le32 wcbbase3; 2346 __le32 wcbbase3;
2019 __le32 fw_api_version; 2347 __le32 fw_api_version;
2348 __le32 caps;
2349 __le32 num_of_ampdu_queues;
2350 __le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES];
2020} __packed; 2351} __packed;
2021 2352
2022static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) 2353static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2023{ 2354{
2024 struct mwl8k_priv *priv = hw->priv; 2355 struct mwl8k_priv *priv = hw->priv;
2025 struct mwl8k_cmd_get_hw_spec_ap *cmd; 2356 struct mwl8k_cmd_get_hw_spec_ap *cmd;
2026 int rc; 2357 int rc, i;
2027 u32 api_version; 2358 u32 api_version;
2028 2359
2029 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2360 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2055,27 +2386,31 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2055 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 2386 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
2056 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 2387 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
2057 priv->hw_rev = cmd->hw_rev; 2388 priv->hw_rev = cmd->hw_rev;
2058 mwl8k_setup_2ghz_band(hw); 2389 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
2059 priv->ap_macids_supported = 0x000000ff; 2390 priv->ap_macids_supported = 0x000000ff;
2060 priv->sta_macids_supported = 0x00000000; 2391 priv->sta_macids_supported = 0x00000000;
2061 2392 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
2062 off = le32_to_cpu(cmd->wcbbase0) & 0xffff; 2393 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
2063 iowrite32(priv->txq[0].txd_dma, priv->sram + off); 2394 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
2064 2395 " but we only support %d.\n",
2396 priv->num_ampdu_queues,
2397 MWL8K_MAX_AMPDU_QUEUES);
2398 priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES;
2399 }
2065 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; 2400 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
2066 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2401 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2067 2402
2068 off = le32_to_cpu(cmd->rxrdptr) & 0xffff; 2403 off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
2069 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2404 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2070 2405
2071 off = le32_to_cpu(cmd->wcbbase1) & 0xffff; 2406 priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff;
2072 iowrite32(priv->txq[1].txd_dma, priv->sram + off); 2407 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
2073 2408 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
2074 off = le32_to_cpu(cmd->wcbbase2) & 0xffff; 2409 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
2075 iowrite32(priv->txq[2].txd_dma, priv->sram + off);
2076 2410
2077 off = le32_to_cpu(cmd->wcbbase3) & 0xffff; 2411 for (i = 0; i < priv->num_ampdu_queues; i++)
2078 iowrite32(priv->txq[3].txd_dma, priv->sram + off); 2412 priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] =
2413 le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff;
2079 } 2414 }
2080 2415
2081done: 2416done:
@@ -2098,12 +2433,20 @@ struct mwl8k_cmd_set_hw_spec {
2098 __le32 caps; 2433 __le32 caps;
2099 __le32 rx_queue_ptr; 2434 __le32 rx_queue_ptr;
2100 __le32 num_tx_queues; 2435 __le32 num_tx_queues;
2101 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 2436 __le32 tx_queue_ptrs[MWL8K_MAX_TX_QUEUES];
2102 __le32 flags; 2437 __le32 flags;
2103 __le32 num_tx_desc_per_queue; 2438 __le32 num_tx_desc_per_queue;
2104 __le32 total_rxd; 2439 __le32 total_rxd;
2105} __packed; 2440} __packed;
2106 2441
2442/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause
2443 * packets to expire 500 ms after the timestamp in the tx descriptor. That is,
2444 * the packets that are queued for more than 500ms, will be dropped in the
2445 * hardware. This helps minimizing the issues caused due to head-of-line
2446 * blocking where a slow client can hog the bandwidth and affect traffic to a
2447 * faster client.
2448 */
2449#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400
2107#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 2450#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
2108#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 2451#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
2109#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 2452#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
@@ -2124,7 +2467,7 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
2124 2467
2125 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 2468 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
2126 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); 2469 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
2127 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 2470 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
2128 2471
2129 /* 2472 /*
2130 * Mac80211 stack has Q0 as highest priority and Q3 as lowest in 2473 * Mac80211 stack has Q0 as highest priority and Q3 as lowest in
@@ -2132,8 +2475,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
2132 * in that order. Map Q3 of mac80211 to Q0 of firmware so that the 2475 * in that order. Map Q3 of mac80211 to Q0 of firmware so that the
2133 * priority is interpreted the right way in firmware. 2476 * priority is interpreted the right way in firmware.
2134 */ 2477 */
2135 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 2478 for (i = 0; i < mwl8k_tx_queues(priv); i++) {
2136 int j = MWL8K_TX_QUEUES - 1 - i; 2479 int j = mwl8k_tx_queues(priv) - 1 - i;
2137 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma); 2480 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma);
2138 } 2481 }
2139 2482
@@ -2356,7 +2699,7 @@ struct mwl8k_cmd_tx_power {
2356 __le16 bw; 2699 __le16 bw;
2357 __le16 sub_ch; 2700 __le16 sub_ch;
2358 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; 2701 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
2359} __attribute__((packed)); 2702} __packed;
2360 2703
2361static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, 2704static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
2362 struct ieee80211_conf *conf, 2705 struct ieee80211_conf *conf,
@@ -3123,6 +3466,65 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
3123} 3466}
3124 3467
3125/* 3468/*
3469 * CMD_GET_WATCHDOG_BITMAP.
3470 */
3471struct mwl8k_cmd_get_watchdog_bitmap {
3472 struct mwl8k_cmd_pkt header;
3473 u8 bitmap;
3474} __packed;
3475
3476static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
3477{
3478 struct mwl8k_cmd_get_watchdog_bitmap *cmd;
3479 int rc;
3480
3481 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3482 if (cmd == NULL)
3483 return -ENOMEM;
3484
3485 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP);
3486 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3487
3488 rc = mwl8k_post_cmd(hw, &cmd->header);
3489 if (!rc)
3490 *bitmap = cmd->bitmap;
3491
3492 kfree(cmd);
3493
3494 return rc;
3495}
3496
3497#define INVALID_BA 0xAA
3498static void mwl8k_watchdog_ba_events(struct work_struct *work)
3499{
3500 int rc;
3501 u8 bitmap = 0, stream_index;
3502 struct mwl8k_ampdu_stream *streams;
3503 struct mwl8k_priv *priv =
3504 container_of(work, struct mwl8k_priv, watchdog_ba_handle);
3505
3506 rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap);
3507 if (rc)
3508 return;
3509
3510 if (bitmap == INVALID_BA)
3511 return;
3512
3513 /* the bitmap is the hw queue number. Map it to the ampdu queue. */
3514 stream_index = bitmap - MWL8K_TX_WMM_QUEUES;
3515
3516 BUG_ON(stream_index >= priv->num_ampdu_queues);
3517
3518 streams = &priv->ampdu[stream_index];
3519
3520 if (streams->state == AMPDU_STREAM_ACTIVE)
3521 ieee80211_stop_tx_ba_session(streams->sta, streams->tid);
3522
3523 return;
3524}
3525
3526
3527/*
3126 * CMD_BSS_START. 3528 * CMD_BSS_START.
3127 */ 3529 */
3128struct mwl8k_cmd_bss_start { 3530struct mwl8k_cmd_bss_start {
@@ -3151,6 +3553,152 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3151} 3553}
3152 3554
3153/* 3555/*
3556 * CMD_BASTREAM.
3557 */
3558
3559/*
3560 * UPSTREAM is tx direction
3561 */
3562#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00
3563#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01
3564
3565enum ba_stream_action_type {
3566 MWL8K_BA_CREATE,
3567 MWL8K_BA_UPDATE,
3568 MWL8K_BA_DESTROY,
3569 MWL8K_BA_FLUSH,
3570 MWL8K_BA_CHECK,
3571};
3572
3573
3574struct mwl8k_create_ba_stream {
3575 __le32 flags;
3576 __le32 idle_thrs;
3577 __le32 bar_thrs;
3578 __le32 window_size;
3579 u8 peer_mac_addr[6];
3580 u8 dialog_token;
3581 u8 tid;
3582 u8 queue_id;
3583 u8 param_info;
3584 __le32 ba_context;
3585 u8 reset_seq_no_flag;
3586 __le16 curr_seq_no;
3587 u8 sta_src_mac_addr[6];
3588} __packed;
3589
3590struct mwl8k_destroy_ba_stream {
3591 __le32 flags;
3592 __le32 ba_context;
3593} __packed;
3594
3595struct mwl8k_cmd_bastream {
3596 struct mwl8k_cmd_pkt header;
3597 __le32 action;
3598 union {
3599 struct mwl8k_create_ba_stream create_params;
3600 struct mwl8k_destroy_ba_stream destroy_params;
3601 };
3602} __packed;
3603
3604static int
3605mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
3606{
3607 struct mwl8k_cmd_bastream *cmd;
3608 int rc;
3609
3610 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3611 if (cmd == NULL)
3612 return -ENOMEM;
3613
3614 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
3615 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3616
3617 cmd->action = cpu_to_le32(MWL8K_BA_CHECK);
3618
3619 cmd->create_params.queue_id = stream->idx;
3620 memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr,
3621 ETH_ALEN);
3622 cmd->create_params.tid = stream->tid;
3623
3624 cmd->create_params.flags =
3625 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
3626 cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
3627
3628 rc = mwl8k_post_cmd(hw, &cmd->header);
3629
3630 kfree(cmd);
3631
3632 return rc;
3633}
3634
3635static int
3636mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
3637 u8 buf_size)
3638{
3639 struct mwl8k_cmd_bastream *cmd;
3640 int rc;
3641
3642 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3643 if (cmd == NULL)
3644 return -ENOMEM;
3645
3646
3647 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
3648 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3649
3650 cmd->action = cpu_to_le32(MWL8K_BA_CREATE);
3651
3652 cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size);
3653 cmd->create_params.window_size = cpu_to_le32((u32)buf_size);
3654 cmd->create_params.queue_id = stream->idx;
3655
3656 memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN);
3657 cmd->create_params.tid = stream->tid;
3658 cmd->create_params.curr_seq_no = cpu_to_le16(0);
3659 cmd->create_params.reset_seq_no_flag = 1;
3660
3661 cmd->create_params.param_info =
3662 (stream->sta->ht_cap.ampdu_factor &
3663 IEEE80211_HT_AMPDU_PARM_FACTOR) |
3664 ((stream->sta->ht_cap.ampdu_density << 2) &
3665 IEEE80211_HT_AMPDU_PARM_DENSITY);
3666
3667 cmd->create_params.flags =
3668 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
3669 BASTREAM_FLAG_DIRECTION_UPSTREAM);
3670
3671 rc = mwl8k_post_cmd(hw, &cmd->header);
3672
3673 wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
3674 stream->sta->addr, stream->tid);
3675 kfree(cmd);
3676
3677 return rc;
3678}
3679
3680static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
3681 struct mwl8k_ampdu_stream *stream)
3682{
3683 struct mwl8k_cmd_bastream *cmd;
3684
3685 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3686 if (cmd == NULL)
3687 return;
3688
3689 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
3690 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3691 cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
3692
3693 cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
3694 mwl8k_post_cmd(hw, &cmd->header);
3695
3696 wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
3697
3698 kfree(cmd);
3699}
3700
3701/*
3154 * CMD_SET_NEW_STN. 3702 * CMD_SET_NEW_STN.
3155 */ 3703 */
3156struct mwl8k_cmd_set_new_stn { 3704struct mwl8k_cmd_set_new_stn {
@@ -3274,7 +3822,7 @@ struct mwl8k_cmd_update_encryption {
3274 __u8 mac_addr[6]; 3822 __u8 mac_addr[6];
3275 __u8 encr_type; 3823 __u8 encr_type;
3276 3824
3277} __attribute__((packed)); 3825} __packed;
3278 3826
3279struct mwl8k_cmd_set_key { 3827struct mwl8k_cmd_set_key {
3280 struct mwl8k_cmd_pkt header; 3828 struct mwl8k_cmd_pkt header;
@@ -3294,7 +3842,7 @@ struct mwl8k_cmd_set_key {
3294 __le16 tkip_tsc_low; 3842 __le16 tkip_tsc_low;
3295 __le32 tkip_tsc_high; 3843 __le32 tkip_tsc_high;
3296 __u8 mac_addr[6]; 3844 __u8 mac_addr[6];
3297} __attribute__((packed)); 3845} __packed;
3298 3846
3299enum { 3847enum {
3300 MWL8K_ENCR_ENABLE, 3848 MWL8K_ENCR_ENABLE,
@@ -3671,6 +4219,11 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
3671 tasklet_schedule(&priv->poll_rx_task); 4219 tasklet_schedule(&priv->poll_rx_task);
3672 } 4220 }
3673 4221
4222 if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
4223 status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
4224 ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
4225 }
4226
3674 if (status) 4227 if (status)
3675 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 4228 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3676 4229
@@ -3699,7 +4252,7 @@ static void mwl8k_tx_poll(unsigned long data)
3699 4252
3700 spin_lock_bh(&priv->tx_lock); 4253 spin_lock_bh(&priv->tx_lock);
3701 4254
3702 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4255 for (i = 0; i < mwl8k_tx_queues(priv); i++)
3703 limit -= mwl8k_txq_reclaim(hw, i, limit, 0); 4256 limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
3704 4257
3705 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { 4258 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
@@ -3774,6 +4327,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
3774 4327
3775 /* Enable interrupts */ 4328 /* Enable interrupts */
3776 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4329 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4330 iowrite32(MWL8K_A2H_EVENTS,
4331 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
3777 4332
3778 rc = mwl8k_fw_lock(hw); 4333 rc = mwl8k_fw_lock(hw);
3779 if (!rc) { 4334 if (!rc) {
@@ -3829,6 +4384,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
3829 4384
3830 /* Stop finalize join worker */ 4385 /* Stop finalize join worker */
3831 cancel_work_sync(&priv->finalize_join_worker); 4386 cancel_work_sync(&priv->finalize_join_worker);
4387 cancel_work_sync(&priv->watchdog_ba_handle);
3832 if (priv->beacon_skb != NULL) 4388 if (priv->beacon_skb != NULL)
3833 dev_kfree_skb(priv->beacon_skb); 4389 dev_kfree_skb(priv->beacon_skb);
3834 4390
@@ -3837,7 +4393,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
3837 tasklet_disable(&priv->poll_rx_task); 4393 tasklet_disable(&priv->poll_rx_task);
3838 4394
3839 /* Return all skbs to mac80211 */ 4395 /* Return all skbs to mac80211 */
3840 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4396 for (i = 0; i < mwl8k_tx_queues(priv); i++)
3841 mwl8k_txq_reclaim(hw, i, INT_MAX, 1); 4397 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
3842} 4398}
3843 4399
@@ -3958,9 +4514,12 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
3958 conf->power_level = 18; 4514 conf->power_level = 18;
3959 4515
3960 if (priv->ap_fw) { 4516 if (priv->ap_fw) {
3961 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); 4517
3962 if (rc) 4518 if (conf->flags & IEEE80211_CONF_CHANGE_POWER) {
3963 goto out; 4519 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
4520 if (rc)
4521 goto out;
4522 }
3964 4523
3965 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3); 4524 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
3966 if (rc) 4525 if (rc)
@@ -3987,7 +4546,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3987 struct ieee80211_bss_conf *info, u32 changed) 4546 struct ieee80211_bss_conf *info, u32 changed)
3988{ 4547{
3989 struct mwl8k_priv *priv = hw->priv; 4548 struct mwl8k_priv *priv = hw->priv;
3990 u32 ap_legacy_rates; 4549 u32 ap_legacy_rates = 0;
3991 u8 ap_mcs_rates[16]; 4550 u8 ap_mcs_rates[16];
3992 int rc; 4551 int rc;
3993 4552
@@ -4312,6 +4871,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
4312 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); 4871 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
4313 if (ret >= 0) { 4872 if (ret >= 0) {
4314 MWL8K_STA(sta)->peer_id = ret; 4873 MWL8K_STA(sta)->peer_id = ret;
4874 if (sta->ht_cap.ht_supported)
4875 MWL8K_STA(sta)->is_ampdu_allowed = true;
4315 ret = 0; 4876 ret = 0;
4316 } 4877 }
4317 4878
@@ -4335,14 +4896,14 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
4335 4896
4336 rc = mwl8k_fw_lock(hw); 4897 rc = mwl8k_fw_lock(hw);
4337 if (!rc) { 4898 if (!rc) {
4338 BUG_ON(queue > MWL8K_TX_QUEUES - 1); 4899 BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1);
4339 memcpy(&priv->wmm_params[queue], params, sizeof(*params)); 4900 memcpy(&priv->wmm_params[queue], params, sizeof(*params));
4340 4901
4341 if (!priv->wmm_enabled) 4902 if (!priv->wmm_enabled)
4342 rc = mwl8k_cmd_set_wmm_mode(hw, 1); 4903 rc = mwl8k_cmd_set_wmm_mode(hw, 1);
4343 4904
4344 if (!rc) { 4905 if (!rc) {
4345 int q = MWL8K_TX_QUEUES - 1 - queue; 4906 int q = MWL8K_TX_WMM_QUEUES - 1 - queue;
4346 rc = mwl8k_cmd_set_edca_params(hw, q, 4907 rc = mwl8k_cmd_set_edca_params(hw, q,
4347 params->cw_min, 4908 params->cw_min,
4348 params->cw_max, 4909 params->cw_max,
@@ -4378,21 +4939,118 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
4378 return 0; 4939 return 0;
4379} 4940}
4380 4941
4942#define MAX_AMPDU_ATTEMPTS 5
4943
4381static int 4944static int
4382mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4945mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4383 enum ieee80211_ampdu_mlme_action action, 4946 enum ieee80211_ampdu_mlme_action action,
4384 struct ieee80211_sta *sta, u16 tid, u16 *ssn, 4947 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
4385 u8 buf_size) 4948 u8 buf_size)
4386{ 4949{
4950
4951 int i, rc = 0;
4952 struct mwl8k_priv *priv = hw->priv;
4953 struct mwl8k_ampdu_stream *stream;
4954 u8 *addr = sta->addr;
4955
4956 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
4957 return -ENOTSUPP;
4958
4959 spin_lock(&priv->stream_lock);
4960 stream = mwl8k_lookup_stream(hw, addr, tid);
4961
4387 switch (action) { 4962 switch (action) {
4388 case IEEE80211_AMPDU_RX_START: 4963 case IEEE80211_AMPDU_RX_START:
4389 case IEEE80211_AMPDU_RX_STOP: 4964 case IEEE80211_AMPDU_RX_STOP:
4390 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 4965 break;
4391 return -ENOTSUPP; 4966 case IEEE80211_AMPDU_TX_START:
4392 return 0; 4967 /* By the time we get here the hw queues may contain outgoing
4968 * packets for this RA/TID that are not part of this BA
4969 * session. The hw will assign sequence numbers to these
4970 * packets as they go out. So if we query the hw for its next
4971 * sequence number and use that for the SSN here, it may end up
4972 * being wrong, which will lead to sequence number mismatch at
4973 * the recipient. To avoid this, we reset the sequence number
4974 * to O for the first MPDU in this BA stream.
4975 */
4976 *ssn = 0;
4977 if (stream == NULL) {
4978 /* This means that somebody outside this driver called
4979 * ieee80211_start_tx_ba_session. This is unexpected
4980 * because we do our own rate control. Just warn and
4981 * move on.
4982 */
4983 wiphy_warn(hw->wiphy, "Unexpected call to %s. "
4984 "Proceeding anyway.\n", __func__);
4985 stream = mwl8k_add_stream(hw, sta, tid);
4986 }
4987 if (stream == NULL) {
4988 wiphy_debug(hw->wiphy, "no free AMPDU streams\n");
4989 rc = -EBUSY;
4990 break;
4991 }
4992 stream->state = AMPDU_STREAM_IN_PROGRESS;
4993
4994 /* Release the lock before we do the time consuming stuff */
4995 spin_unlock(&priv->stream_lock);
4996 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
4997 rc = mwl8k_check_ba(hw, stream);
4998
4999 if (!rc)
5000 break;
5001 /*
5002 * HW queues take time to be flushed, give them
5003 * sufficient time
5004 */
5005
5006 msleep(1000);
5007 }
5008 spin_lock(&priv->stream_lock);
5009 if (rc) {
5010 wiphy_err(hw->wiphy, "Stream for tid %d busy after %d"
5011 " attempts\n", tid, MAX_AMPDU_ATTEMPTS);
5012 mwl8k_remove_stream(hw, stream);
5013 rc = -EBUSY;
5014 break;
5015 }
5016 ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
5017 break;
5018 case IEEE80211_AMPDU_TX_STOP:
5019 if (stream == NULL)
5020 break;
5021 if (stream->state == AMPDU_STREAM_ACTIVE) {
5022 spin_unlock(&priv->stream_lock);
5023 mwl8k_destroy_ba(hw, stream);
5024 spin_lock(&priv->stream_lock);
5025 }
5026 mwl8k_remove_stream(hw, stream);
5027 ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
5028 break;
5029 case IEEE80211_AMPDU_TX_OPERATIONAL:
5030 BUG_ON(stream == NULL);
5031 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
5032 spin_unlock(&priv->stream_lock);
5033 rc = mwl8k_create_ba(hw, stream, buf_size);
5034 spin_lock(&priv->stream_lock);
5035 if (!rc)
5036 stream->state = AMPDU_STREAM_ACTIVE;
5037 else {
5038 spin_unlock(&priv->stream_lock);
5039 mwl8k_destroy_ba(hw, stream);
5040 spin_lock(&priv->stream_lock);
5041 wiphy_debug(hw->wiphy,
5042 "Failed adding stream for sta %pM tid %d\n",
5043 addr, tid);
5044 mwl8k_remove_stream(hw, stream);
5045 }
5046 break;
5047
4393 default: 5048 default:
4394 return -ENOTSUPP; 5049 rc = -ENOTSUPP;
4395 } 5050 }
5051
5052 spin_unlock(&priv->stream_lock);
5053 return rc;
4396} 5054}
4397 5055
4398static const struct ieee80211_ops mwl8k_ops = { 5056static const struct ieee80211_ops mwl8k_ops = {
@@ -4441,7 +5099,7 @@ enum {
4441 MWL8366, 5099 MWL8366,
4442}; 5100};
4443 5101
4444#define MWL8K_8366_AP_FW_API 1 5102#define MWL8K_8366_AP_FW_API 2
4445#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" 5103#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
4446#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) 5104#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
4447 5105
@@ -4607,6 +5265,23 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
4607 return rc; 5265 return rc;
4608} 5266}
4609 5267
5268static int mwl8k_init_txqs(struct ieee80211_hw *hw)
5269{
5270 struct mwl8k_priv *priv = hw->priv;
5271 int rc = 0;
5272 int i;
5273
5274 for (i = 0; i < mwl8k_tx_queues(priv); i++) {
5275 rc = mwl8k_txq_init(hw, i);
5276 if (rc)
5277 break;
5278 if (priv->ap_fw)
5279 iowrite32(priv->txq[i].txd_dma,
5280 priv->sram + priv->txq_offset[i]);
5281 }
5282 return rc;
5283}
5284
4610/* initialize hw after successfully loading a firmware image */ 5285/* initialize hw after successfully loading a firmware image */
4611static int mwl8k_probe_hw(struct ieee80211_hw *hw) 5286static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4612{ 5287{
@@ -4634,17 +5309,26 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4634 goto err_stop_firmware; 5309 goto err_stop_firmware;
4635 rxq_refill(hw, 0, INT_MAX); 5310 rxq_refill(hw, 0, INT_MAX);
4636 5311
4637 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 5312 /* For the sta firmware, we need to know the dma addresses of tx queues
4638 rc = mwl8k_txq_init(hw, i); 5313 * before sending MWL8K_CMD_GET_HW_SPEC. So we must initialize them
5314 * prior to issuing this command. But for the AP case, we learn the
5315 * total number of queues from the result CMD_GET_HW_SPEC, so for this
5316 * case we must initialize the tx queues after.
5317 */
5318 priv->num_ampdu_queues = 0;
5319 if (!priv->ap_fw) {
5320 rc = mwl8k_init_txqs(hw);
4639 if (rc) 5321 if (rc)
4640 goto err_free_queues; 5322 goto err_free_queues;
4641 } 5323 }
4642 5324
4643 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 5325 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
4644 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 5326 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4645 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY, 5327 iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
5328 MWL8K_A2H_INT_BA_WATCHDOG,
4646 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 5329 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
4647 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 5330 iowrite32(MWL8K_A2H_INT_OPC_DONE,
5331 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
4648 5332
4649 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, 5333 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
4650 IRQF_SHARED, MWL8K_NAME, hw); 5334 IRQF_SHARED, MWL8K_NAME, hw);
@@ -4653,6 +5337,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4653 goto err_free_queues; 5337 goto err_free_queues;
4654 } 5338 }
4655 5339
5340 memset(priv->ampdu, 0, sizeof(priv->ampdu));
5341
4656 /* 5342 /*
4657 * Temporarily enable interrupts. Initial firmware host 5343 * Temporarily enable interrupts. Initial firmware host
4658 * commands use interrupts and avoid polling. Disable 5344 * commands use interrupts and avoid polling. Disable
@@ -4664,6 +5350,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4664 if (priv->ap_fw) { 5350 if (priv->ap_fw) {
4665 rc = mwl8k_cmd_get_hw_spec_ap(hw); 5351 rc = mwl8k_cmd_get_hw_spec_ap(hw);
4666 if (!rc) 5352 if (!rc)
5353 rc = mwl8k_init_txqs(hw);
5354 if (!rc)
4667 rc = mwl8k_cmd_set_hw_spec(hw); 5355 rc = mwl8k_cmd_set_hw_spec(hw);
4668 } else { 5356 } else {
4669 rc = mwl8k_cmd_get_hw_spec_sta(hw); 5357 rc = mwl8k_cmd_get_hw_spec_sta(hw);
@@ -4705,7 +5393,7 @@ err_free_irq:
4705 free_irq(priv->pdev->irq, hw); 5393 free_irq(priv->pdev->irq, hw);
4706 5394
4707err_free_queues: 5395err_free_queues:
4708 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5396 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4709 mwl8k_txq_deinit(hw, i); 5397 mwl8k_txq_deinit(hw, i);
4710 mwl8k_rxq_deinit(hw, 0); 5398 mwl8k_rxq_deinit(hw, 0);
4711 5399
@@ -4727,7 +5415,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
4727 mwl8k_stop(hw); 5415 mwl8k_stop(hw);
4728 mwl8k_rxq_deinit(hw, 0); 5416 mwl8k_rxq_deinit(hw, 0);
4729 5417
4730 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5418 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4731 mwl8k_txq_deinit(hw, i); 5419 mwl8k_txq_deinit(hw, i);
4732 5420
4733 rc = mwl8k_init_firmware(hw, fw_image, false); 5421 rc = mwl8k_init_firmware(hw, fw_image, false);
@@ -4746,7 +5434,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
4746 if (rc) 5434 if (rc)
4747 goto fail; 5435 goto fail;
4748 5436
4749 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 5437 for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) {
4750 rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]); 5438 rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
4751 if (rc) 5439 if (rc)
4752 goto fail; 5440 goto fail;
@@ -4780,7 +5468,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4780 5468
4781 hw->channel_change_time = 10; 5469 hw->channel_change_time = 10;
4782 5470
4783 hw->queues = MWL8K_TX_QUEUES; 5471 hw->queues = MWL8K_TX_WMM_QUEUES;
4784 5472
4785 /* Set rssi values to dBm */ 5473 /* Set rssi values to dBm */
4786 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; 5474 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
@@ -4796,6 +5484,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4796 5484
4797 /* Finalize join worker */ 5485 /* Finalize join worker */
4798 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 5486 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
5487 /* Handle watchdog ba events */
5488 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);
4799 5489
4800 /* TX reclaim and RX tasklets. */ 5490 /* TX reclaim and RX tasklets. */
4801 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); 5491 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
@@ -4815,6 +5505,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4815 5505
4816 spin_lock_init(&priv->tx_lock); 5506 spin_lock_init(&priv->tx_lock);
4817 5507
5508 spin_lock_init(&priv->stream_lock);
5509
4818 priv->tx_wait = NULL; 5510 priv->tx_wait = NULL;
4819 5511
4820 rc = mwl8k_probe_hw(hw); 5512 rc = mwl8k_probe_hw(hw);
@@ -4836,7 +5528,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4836 return 0; 5528 return 0;
4837 5529
4838err_unprobe_hw: 5530err_unprobe_hw:
4839 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5531 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4840 mwl8k_txq_deinit(hw, i); 5532 mwl8k_txq_deinit(hw, i);
4841 mwl8k_rxq_deinit(hw, 0); 5533 mwl8k_rxq_deinit(hw, 0);
4842 5534
@@ -4995,10 +5687,10 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
4995 mwl8k_hw_reset(priv); 5687 mwl8k_hw_reset(priv);
4996 5688
4997 /* Return all skbs to mac80211 */ 5689 /* Return all skbs to mac80211 */
4998 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5690 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4999 mwl8k_txq_reclaim(hw, i, INT_MAX, 1); 5691 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
5000 5692
5001 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5693 for (i = 0; i < mwl8k_tx_queues(priv); i++)
5002 mwl8k_txq_deinit(hw, i); 5694 mwl8k_txq_deinit(hw, i);
5003 5695
5004 mwl8k_rxq_deinit(hw, 0); 5696 mwl8k_rxq_deinit(hw, 0);