aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-05-29 04:35:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-03 15:00:24 -0400
commitf20217d9d57584b6c7fcfef8c4183f10ee45fddd (patch)
tree352bc4f0b1de22a1cbed0fb98457fef0172f16f3 /drivers
parente532fa0e3ce3feda1f1eb14aa31caae503cd9bda (diff)
iwlwifi: move 4965 tx response into iwl-4965.c
This patch moves 4965 tx repsone into iwl-4965.c. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c247
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c246
2 files changed, 247 insertions, 246 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 3bb6ac588aaf..98f3df0210d7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -3477,6 +3477,251 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
3477 3477
3478 return (u16)sizeof(struct iwl4965_addsta_cmd); 3478 return (u16)sizeof(struct iwl4965_addsta_cmd);
3479} 3479}
3480
3481#ifdef CONFIG_IWL4965_HT
3482static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
3483{
3484 __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
3485 tx_resp->frame_count);
3486 return le32_to_cpu(*scd_ssn) & MAX_SN;
3487
3488}
3489
3490/**
3491 * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue
3492 */
3493static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
3494 struct iwl_ht_agg *agg,
3495 struct iwl4965_tx_resp_agg *tx_resp,
3496 u16 start_idx)
3497{
3498 u16 status;
3499 struct agg_tx_status *frame_status = &tx_resp->status;
3500 struct ieee80211_tx_info *info = NULL;
3501 struct ieee80211_hdr *hdr = NULL;
3502 int i, sh;
3503 int txq_id, idx;
3504 u16 seq;
3505
3506 if (agg->wait_for_ba)
3507 IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
3508
3509 agg->frame_count = tx_resp->frame_count;
3510 agg->start_idx = start_idx;
3511 agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
3512 agg->bitmap = 0;
3513
3514 /* # frames attempted by Tx command */
3515 if (agg->frame_count == 1) {
3516 /* Only one frame was attempted; no block-ack will arrive */
3517 status = le16_to_cpu(frame_status[0].status);
3518 seq = le16_to_cpu(frame_status[0].sequence);
3519 idx = SEQ_TO_INDEX(seq);
3520 txq_id = SEQ_TO_QUEUE(seq);
3521
3522 /* FIXME: code repetition */
3523 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
3524 agg->frame_count, agg->start_idx, idx);
3525
3526 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
3527 info->status.retry_count = tx_resp->failure_frame;
3528 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
3529 info->flags |= iwl_is_tx_success(status)?
3530 IEEE80211_TX_STAT_ACK : 0;
3531 iwl4965_hwrate_to_tx_control(priv,
3532 le32_to_cpu(tx_resp->rate_n_flags),
3533 info);
3534 /* FIXME: code repetition end */
3535
3536 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
3537 status & 0xff, tx_resp->failure_frame);
3538 IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
3539 iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
3540
3541 agg->wait_for_ba = 0;
3542 } else {
3543 /* Two or more frames were attempted; expect block-ack */
3544 u64 bitmap = 0;
3545 int start = agg->start_idx;
3546
3547 /* Construct bit-map of pending frames within Tx window */
3548 for (i = 0; i < agg->frame_count; i++) {
3549 u16 sc;
3550 status = le16_to_cpu(frame_status[i].status);
3551 seq = le16_to_cpu(frame_status[i].sequence);
3552 idx = SEQ_TO_INDEX(seq);
3553 txq_id = SEQ_TO_QUEUE(seq);
3554
3555 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
3556 AGG_TX_STATE_ABORT_MSK))
3557 continue;
3558
3559 IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
3560 agg->frame_count, txq_id, idx);
3561
3562 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
3563
3564 sc = le16_to_cpu(hdr->seq_ctrl);
3565 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
3566 IWL_ERROR("BUG_ON idx doesn't match seq control"
3567 " idx=%d, seq_idx=%d, seq=%d\n",
3568 idx, SEQ_TO_SN(sc),
3569 hdr->seq_ctrl);
3570 return -1;
3571 }
3572
3573 IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
3574 i, idx, SEQ_TO_SN(sc));
3575
3576 sh = idx - start;
3577 if (sh > 64) {
3578 sh = (start - idx) + 0xff;
3579 bitmap = bitmap << sh;
3580 sh = 0;
3581 start = idx;
3582 } else if (sh < -64)
3583 sh = 0xff - (start - idx);
3584 else if (sh < 0) {
3585 sh = start - idx;
3586 start = idx;
3587 bitmap = bitmap << sh;
3588 sh = 0;
3589 }
3590 bitmap |= (1 << sh);
3591 IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
3592 start, (u32)(bitmap & 0xFFFFFFFF));
3593 }
3594
3595 agg->bitmap = bitmap;
3596 agg->start_idx = start;
3597 agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
3598 IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
3599 agg->frame_count, agg->start_idx,
3600 (unsigned long long)agg->bitmap);
3601
3602 if (bitmap)
3603 agg->wait_for_ba = 1;
3604 }
3605 return 0;
3606}
3607#endif
3608
3609/**
3610 * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
3611 */
3612static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
3613 struct iwl_rx_mem_buffer *rxb)
3614{
3615 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
3616 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
3617 int txq_id = SEQ_TO_QUEUE(sequence);
3618 int index = SEQ_TO_INDEX(sequence);
3619 struct iwl_tx_queue *txq = &priv->txq[txq_id];
3620 struct ieee80211_tx_info *info;
3621 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
3622 u32 status = le32_to_cpu(tx_resp->status);
3623#ifdef CONFIG_IWL4965_HT
3624 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
3625 u16 fc;
3626 struct ieee80211_hdr *hdr;
3627 u8 *qc = NULL;
3628#endif
3629
3630 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
3631 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
3632 "is out of range [0-%d] %d %d\n", txq_id,
3633 index, txq->q.n_bd, txq->q.write_ptr,
3634 txq->q.read_ptr);
3635 return;
3636 }
3637
3638 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
3639 memset(&info->status, 0, sizeof(info->status));
3640
3641#ifdef CONFIG_IWL4965_HT
3642 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
3643 fc = le16_to_cpu(hdr->frame_control);
3644 if (ieee80211_is_qos_data(fc)) {
3645 qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
3646 tid = qc[0] & 0xf;
3647 }
3648
3649 sta_id = iwl_get_ra_sta_id(priv, hdr);
3650 if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
3651 IWL_ERROR("Station not known\n");
3652 return;
3653 }
3654
3655 if (txq->sched_retry) {
3656 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
3657 struct iwl_ht_agg *agg = NULL;
3658
3659 if (!qc)
3660 return;
3661
3662 agg = &priv->stations[sta_id].tid[tid].agg;
3663
3664 iwl4965_tx_status_reply_tx(priv, agg,
3665 (struct iwl4965_tx_resp_agg *)tx_resp, index);
3666
3667 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
3668 /* TODO: send BAR */
3669 }
3670
3671 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
3672 int freed, ampdu_q;
3673 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
3674 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
3675 "%d index %d\n", scd_ssn , index);
3676 freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
3677 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
3678
3679 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
3680 txq_id >= 0 && priv->mac80211_registered &&
3681 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
3682 /* calculate mac80211 ampdu sw queue to wake */
3683 ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +
3684 priv->hw->queues;
3685 if (agg->state == IWL_AGG_OFF)
3686 ieee80211_wake_queue(priv->hw, txq_id);
3687 else
3688 ieee80211_wake_queue(priv->hw, ampdu_q);
3689 }
3690 iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
3691 }
3692 } else {
3693#endif /* CONFIG_IWL4965_HT */
3694
3695 info->status.retry_count = tx_resp->failure_frame;
3696 info->flags |= iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
3697 iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
3698 info);
3699
3700 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
3701 "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),
3702 status, le32_to_cpu(tx_resp->rate_n_flags),
3703 tx_resp->failure_frame);
3704
3705 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
3706#ifdef CONFIG_IWL4965_HT
3707 if (index != -1) {
3708 int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
3709 if (tid != MAX_TID_COUNT)
3710 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
3711 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
3712 (txq_id >= 0) && priv->mac80211_registered)
3713 ieee80211_wake_queue(priv->hw, txq_id);
3714 if (tid != MAX_TID_COUNT)
3715 iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
3716 }
3717 }
3718#endif /* CONFIG_IWL4965_HT */
3719
3720 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
3721 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
3722}
3723
3724
3480/* Set up 4965-specific Rx frame reply handlers */ 3725/* Set up 4965-specific Rx frame reply handlers */
3481static void iwl4965_rx_handler_setup(struct iwl_priv *priv) 3726static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
3482{ 3727{
@@ -3487,6 +3732,8 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
3487 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy; 3732 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy;
3488 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl4965_rx_reply_rx; 3733 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl4965_rx_reply_rx;
3489 3734
3735 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
3736
3490#ifdef CONFIG_IWL4965_HT 3737#ifdef CONFIG_IWL4965_HT
3491 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; 3738 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;
3492#endif /* CONFIG_IWL4965_HT */ 3739#endif /* CONFIG_IWL4965_HT */
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 411fad32e95a..10d773413aa5 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1585,251 +1585,6 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1585 * Generic RX handler implementations 1585 * Generic RX handler implementations
1586 * 1586 *
1587 ******************************************************************************/ 1587 ******************************************************************************/
1588#ifdef CONFIG_IWL4965_HT
1589static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
1590{
1591 __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
1592 tx_resp->frame_count);
1593 return le32_to_cpu(*scd_ssn) & MAX_SN;
1594
1595}
1596
1597/**
1598 * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue
1599 */
1600static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
1601 struct iwl_ht_agg *agg,
1602 struct iwl4965_tx_resp_agg *tx_resp,
1603 u16 start_idx)
1604{
1605 u16 status;
1606 struct agg_tx_status *frame_status = &tx_resp->status;
1607 struct ieee80211_tx_info *info = NULL;
1608 struct ieee80211_hdr *hdr = NULL;
1609 int i, sh;
1610 int txq_id, idx;
1611 u16 seq;
1612
1613 if (agg->wait_for_ba)
1614 IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
1615
1616 agg->frame_count = tx_resp->frame_count;
1617 agg->start_idx = start_idx;
1618 agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
1619 agg->bitmap = 0;
1620
1621 /* # frames attempted by Tx command */
1622 if (agg->frame_count == 1) {
1623 /* Only one frame was attempted; no block-ack will arrive */
1624 status = le16_to_cpu(frame_status[0].status);
1625 seq = le16_to_cpu(frame_status[0].sequence);
1626 idx = SEQ_TO_INDEX(seq);
1627 txq_id = SEQ_TO_QUEUE(seq);
1628
1629 /* FIXME: code repetition */
1630 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
1631 agg->frame_count, agg->start_idx, idx);
1632
1633 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
1634 info->status.retry_count = tx_resp->failure_frame;
1635 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1636 info->flags |= iwl_is_tx_success(status)?
1637 IEEE80211_TX_STAT_ACK : 0;
1638 iwl4965_hwrate_to_tx_control(priv,
1639 le32_to_cpu(tx_resp->rate_n_flags),
1640 info);
1641 /* FIXME: code repetition end */
1642
1643 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
1644 status & 0xff, tx_resp->failure_frame);
1645 IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
1646 iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
1647
1648 agg->wait_for_ba = 0;
1649 } else {
1650 /* Two or more frames were attempted; expect block-ack */
1651 u64 bitmap = 0;
1652 int start = agg->start_idx;
1653
1654 /* Construct bit-map of pending frames within Tx window */
1655 for (i = 0; i < agg->frame_count; i++) {
1656 u16 sc;
1657 status = le16_to_cpu(frame_status[i].status);
1658 seq = le16_to_cpu(frame_status[i].sequence);
1659 idx = SEQ_TO_INDEX(seq);
1660 txq_id = SEQ_TO_QUEUE(seq);
1661
1662 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
1663 AGG_TX_STATE_ABORT_MSK))
1664 continue;
1665
1666 IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
1667 agg->frame_count, txq_id, idx);
1668
1669 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
1670
1671 sc = le16_to_cpu(hdr->seq_ctrl);
1672 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
1673 IWL_ERROR("BUG_ON idx doesn't match seq control"
1674 " idx=%d, seq_idx=%d, seq=%d\n",
1675 idx, SEQ_TO_SN(sc),
1676 hdr->seq_ctrl);
1677 return -1;
1678 }
1679
1680 IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
1681 i, idx, SEQ_TO_SN(sc));
1682
1683 sh = idx - start;
1684 if (sh > 64) {
1685 sh = (start - idx) + 0xff;
1686 bitmap = bitmap << sh;
1687 sh = 0;
1688 start = idx;
1689 } else if (sh < -64)
1690 sh = 0xff - (start - idx);
1691 else if (sh < 0) {
1692 sh = start - idx;
1693 start = idx;
1694 bitmap = bitmap << sh;
1695 sh = 0;
1696 }
1697 bitmap |= (1 << sh);
1698 IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
1699 start, (u32)(bitmap & 0xFFFFFFFF));
1700 }
1701
1702 agg->bitmap = bitmap;
1703 agg->start_idx = start;
1704 agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
1705 IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
1706 agg->frame_count, agg->start_idx,
1707 (unsigned long long)agg->bitmap);
1708
1709 if (bitmap)
1710 agg->wait_for_ba = 1;
1711 }
1712 return 0;
1713}
1714#endif
1715
1716/**
1717 * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
1718 */
1719static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
1720 struct iwl_rx_mem_buffer *rxb)
1721{
1722 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1723 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1724 int txq_id = SEQ_TO_QUEUE(sequence);
1725 int index = SEQ_TO_INDEX(sequence);
1726 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1727 struct ieee80211_tx_info *info;
1728 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
1729 u32 status = le32_to_cpu(tx_resp->status);
1730#ifdef CONFIG_IWL4965_HT
1731 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
1732 u16 fc;
1733 struct ieee80211_hdr *hdr;
1734 u8 *qc = NULL;
1735#endif
1736
1737 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
1738 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
1739 "is out of range [0-%d] %d %d\n", txq_id,
1740 index, txq->q.n_bd, txq->q.write_ptr,
1741 txq->q.read_ptr);
1742 return;
1743 }
1744
1745 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
1746 memset(&info->status, 0, sizeof(info->status));
1747
1748#ifdef CONFIG_IWL4965_HT
1749 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
1750 fc = le16_to_cpu(hdr->frame_control);
1751 if (ieee80211_is_qos_data(fc)) {
1752 qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
1753 tid = qc[0] & 0xf;
1754 }
1755
1756 sta_id = iwl_get_ra_sta_id(priv, hdr);
1757 if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
1758 IWL_ERROR("Station not known\n");
1759 return;
1760 }
1761
1762 if (txq->sched_retry) {
1763 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
1764 struct iwl_ht_agg *agg = NULL;
1765
1766 if (!qc)
1767 return;
1768
1769 agg = &priv->stations[sta_id].tid[tid].agg;
1770
1771 iwl4965_tx_status_reply_tx(priv, agg,
1772 (struct iwl4965_tx_resp_agg *)tx_resp, index);
1773
1774 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
1775 /* TODO: send BAR */
1776 }
1777
1778 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
1779 int freed, ampdu_q;
1780 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
1781 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
1782 "%d index %d\n", scd_ssn , index);
1783 freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
1784 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1785
1786 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
1787 txq_id >= 0 && priv->mac80211_registered &&
1788 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
1789 /* calculate mac80211 ampdu sw queue to wake */
1790 ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +
1791 priv->hw->queues;
1792 if (agg->state == IWL_AGG_OFF)
1793 ieee80211_wake_queue(priv->hw, txq_id);
1794 else
1795 ieee80211_wake_queue(priv->hw, ampdu_q);
1796 }
1797 iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
1798 }
1799 } else {
1800#endif /* CONFIG_IWL4965_HT */
1801
1802 info->status.retry_count = tx_resp->failure_frame;
1803 info->flags |=
1804 iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
1805 iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
1806 info);
1807
1808 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
1809 "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),
1810 status, le32_to_cpu(tx_resp->rate_n_flags),
1811 tx_resp->failure_frame);
1812
1813 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
1814#ifdef CONFIG_IWL4965_HT
1815 if (index != -1) {
1816 int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
1817 if (tid != MAX_TID_COUNT)
1818 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1819 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
1820 (txq_id >= 0) && priv->mac80211_registered)
1821 ieee80211_wake_queue(priv->hw, txq_id);
1822 if (tid != MAX_TID_COUNT)
1823 iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
1824 }
1825 }
1826#endif /* CONFIG_IWL4965_HT */
1827
1828 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
1829 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
1830}
1831
1832
1833static void iwl_rx_reply_alive(struct iwl_priv *priv, 1588static void iwl_rx_reply_alive(struct iwl_priv *priv,
1834 struct iwl_rx_mem_buffer *rxb) 1589 struct iwl_rx_mem_buffer *rxb)
1835{ 1590{
@@ -2198,7 +1953,6 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
2198 priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = 1953 priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
2199 iwl4965_rx_scan_complete_notif; 1954 iwl4965_rx_scan_complete_notif;
2200 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; 1955 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;
2201 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2202 1956
2203 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = 1957 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
2204 iwl_rx_missed_beacon_notif; 1958 iwl_rx_missed_beacon_notif;