diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-commands.h | 79 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 41 |
6 files changed, 108 insertions, 54 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7424586a5edb..ae5efc376b91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -191,12 +191,12 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) | |||
191 | } | 191 | } |
192 | 192 | ||
193 | #ifdef CONFIG_IWLWIFI_DEBUG | 193 | #ifdef CONFIG_IWLWIFI_DEBUG |
194 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 194 | #define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x |
195 | 195 | ||
196 | static const char *iwl3945_get_tx_fail_reason(u32 status) | 196 | static const char *iwl3945_get_tx_fail_reason(u32 status) |
197 | { | 197 | { |
198 | switch (status & TX_STATUS_MSK) { | 198 | switch (status & TX_STATUS_MSK) { |
199 | case TX_STATUS_SUCCESS: | 199 | case TX_3945_STATUS_SUCCESS: |
200 | return "SUCCESS"; | 200 | return "SUCCESS"; |
201 | TX_STATUS_ENTRY(SHORT_LIMIT); | 201 | TX_STATUS_ENTRY(SHORT_LIMIT); |
202 | TX_STATUS_ENTRY(LONG_LIMIT); | 202 | TX_STATUS_ENTRY(LONG_LIMIT); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 0164c3f2109d..c710b26a1c86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2049,8 +2049,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2049 | 2049 | ||
2050 | iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); | 2050 | iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); |
2051 | 2051 | ||
2052 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 2052 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
2053 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); | ||
2054 | } | 2053 | } |
2055 | 2054 | ||
2056 | static int iwl4965_calc_rssi(struct iwl_priv *priv, | 2055 | static int iwl4965_calc_rssi(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 7f27a945c187..384b45c519f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -161,6 +161,14 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | void iwl_check_abort_status(struct iwl_priv *priv, | ||
165 | u8 frame_count, u32 status) | ||
166 | { | ||
167 | if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { | ||
168 | IWL_ERR(priv, "TODO: Implement Tx flush command!!!\n"); | ||
169 | } | ||
170 | } | ||
171 | |||
164 | static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | 172 | static void iwlagn_rx_reply_tx(struct iwl_priv *priv, |
165 | struct iwl_rx_mem_buffer *rxb) | 173 | struct iwl_rx_mem_buffer *rxb) |
166 | { | 174 | { |
@@ -246,8 +254,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
246 | 254 | ||
247 | iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); | 255 | iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); |
248 | 256 | ||
249 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 257 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
250 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); | ||
251 | } | 258 | } |
252 | 259 | ||
253 | void iwlagn_rx_handler_setup(struct iwl_priv *priv) | 260 | void iwlagn_rx_handler_setup(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5ad14055eda3..608060abe80c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -105,6 +105,8 @@ void iwlagn_init_alive_start(struct iwl_priv *priv); | |||
105 | int iwlagn_alive_notify(struct iwl_priv *priv); | 105 | int iwlagn_alive_notify(struct iwl_priv *priv); |
106 | 106 | ||
107 | /* lib */ | 107 | /* lib */ |
108 | void iwl_check_abort_status(struct iwl_priv *priv, | ||
109 | u8 frame_count, u32 status); | ||
108 | void iwlagn_rx_handler_setup(struct iwl_priv *priv); | 110 | void iwlagn_rx_handler_setup(struct iwl_priv *priv); |
109 | void iwlagn_setup_deferred_work(struct iwl_priv *priv); | 111 | void iwlagn_setup_deferred_work(struct iwl_priv *priv); |
110 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | 112 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); |
@@ -146,4 +148,26 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv); | |||
146 | int iwlagn_txq_ctx_reset(struct iwl_priv *priv); | 148 | int iwlagn_txq_ctx_reset(struct iwl_priv *priv); |
147 | void iwlagn_txq_ctx_stop(struct iwl_priv *priv); | 149 | void iwlagn_txq_ctx_stop(struct iwl_priv *priv); |
148 | 150 | ||
151 | static inline u32 iwl_tx_status_to_mac80211(u32 status) | ||
152 | { | ||
153 | status &= TX_STATUS_MSK; | ||
154 | |||
155 | switch (status) { | ||
156 | case TX_STATUS_SUCCESS: | ||
157 | case TX_STATUS_DIRECT_DONE: | ||
158 | return IEEE80211_TX_STAT_ACK; | ||
159 | case TX_STATUS_FAIL_DEST_PS: | ||
160 | return IEEE80211_TX_STAT_TX_FILTERED; | ||
161 | default: | ||
162 | return 0; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | static inline bool iwl_is_tx_success(u32 status) | ||
167 | { | ||
168 | status &= TX_STATUS_MSK; | ||
169 | return (status == TX_STATUS_SUCCESS) || | ||
170 | (status == TX_STATUS_DIRECT_DONE); | ||
171 | } | ||
172 | |||
149 | #endif /* __iwl_agn_h__ */ | 173 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 74d6887c7500..82a9378f72e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -1662,7 +1662,7 @@ struct iwl_tx_cmd { | |||
1662 | struct ieee80211_hdr hdr[0]; | 1662 | struct ieee80211_hdr hdr[0]; |
1663 | } __attribute__ ((packed)); | 1663 | } __attribute__ ((packed)); |
1664 | 1664 | ||
1665 | /* TX command response is sent after *all* transmission attempts. | 1665 | /* TX command response is sent after *3945* transmission attempts. |
1666 | * | 1666 | * |
1667 | * NOTES: | 1667 | * NOTES: |
1668 | * | 1668 | * |
@@ -1690,24 +1690,65 @@ struct iwl_tx_cmd { | |||
1690 | * control line. Receiving is still allowed in this case. | 1690 | * control line. Receiving is still allowed in this case. |
1691 | */ | 1691 | */ |
1692 | enum { | 1692 | enum { |
1693 | TX_3945_STATUS_SUCCESS = 0x01, | ||
1694 | TX_3945_STATUS_DIRECT_DONE = 0x02, | ||
1695 | TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82, | ||
1696 | TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83, | ||
1697 | TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84, | ||
1698 | TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85, | ||
1699 | TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86, | ||
1700 | TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87, | ||
1701 | TX_3945_STATUS_FAIL_DEST_PS = 0x88, | ||
1702 | TX_3945_STATUS_FAIL_ABORTED = 0x89, | ||
1703 | TX_3945_STATUS_FAIL_BT_RETRY = 0x8a, | ||
1704 | TX_3945_STATUS_FAIL_STA_INVALID = 0x8b, | ||
1705 | TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c, | ||
1706 | TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d, | ||
1707 | TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e, | ||
1708 | TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, | ||
1709 | TX_3945_STATUS_FAIL_TX_LOCKED = 0x90, | ||
1710 | TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, | ||
1711 | }; | ||
1712 | |||
1713 | /* | ||
1714 | * TX command response is sent after *agn* transmission attempts. | ||
1715 | * | ||
1716 | * both postpone and abort status are expected behavior from uCode. there is | ||
1717 | * no special operation required from driver; except for RFKILL_FLUSH, | ||
1718 | * which required tx flush host command to flush all the tx frames in queues | ||
1719 | */ | ||
1720 | enum { | ||
1693 | TX_STATUS_SUCCESS = 0x01, | 1721 | TX_STATUS_SUCCESS = 0x01, |
1694 | TX_STATUS_DIRECT_DONE = 0x02, | 1722 | TX_STATUS_DIRECT_DONE = 0x02, |
1723 | /* postpone TX */ | ||
1724 | TX_STATUS_POSTPONE_DELAY = 0x40, | ||
1725 | TX_STATUS_POSTPONE_FEW_BYTES = 0x41, | ||
1726 | TX_STATUS_POSTPONE_BT_PRIO = 0x42, | ||
1727 | TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43, | ||
1728 | TX_STATUS_POSTPONE_CALC_TTAK = 0x44, | ||
1729 | /* abort TX */ | ||
1730 | TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81, | ||
1695 | TX_STATUS_FAIL_SHORT_LIMIT = 0x82, | 1731 | TX_STATUS_FAIL_SHORT_LIMIT = 0x82, |
1696 | TX_STATUS_FAIL_LONG_LIMIT = 0x83, | 1732 | TX_STATUS_FAIL_LONG_LIMIT = 0x83, |
1697 | TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, | 1733 | TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, |
1698 | TX_STATUS_FAIL_MGMNT_ABORT = 0x85, | 1734 | TX_STATUS_FAIL_DRAIN_FLOW = 0x85, |
1699 | TX_STATUS_FAIL_NEXT_FRAG = 0x86, | 1735 | TX_STATUS_FAIL_RFKILL_FLUSH = 0x86, |
1700 | TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, | 1736 | TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, |
1701 | TX_STATUS_FAIL_DEST_PS = 0x88, | 1737 | TX_STATUS_FAIL_DEST_PS = 0x88, |
1702 | TX_STATUS_FAIL_ABORTED = 0x89, | 1738 | TX_STATUS_FAIL_HOST_ABORTED = 0x89, |
1703 | TX_STATUS_FAIL_BT_RETRY = 0x8a, | 1739 | TX_STATUS_FAIL_BT_RETRY = 0x8a, |
1704 | TX_STATUS_FAIL_STA_INVALID = 0x8b, | 1740 | TX_STATUS_FAIL_STA_INVALID = 0x8b, |
1705 | TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, | 1741 | TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, |
1706 | TX_STATUS_FAIL_TID_DISABLE = 0x8d, | 1742 | TX_STATUS_FAIL_TID_DISABLE = 0x8d, |
1707 | TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e, | 1743 | TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e, |
1708 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, | 1744 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, |
1709 | TX_STATUS_FAIL_TX_LOCKED = 0x90, | 1745 | /* uCode drop due to FW drop request */ |
1710 | TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, | 1746 | TX_STATUS_FAIL_FW_DROP = 0x90, |
1747 | /* | ||
1748 | * uCode drop due to station color mismatch | ||
1749 | * between tx command and station table | ||
1750 | */ | ||
1751 | TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP = 0x91, | ||
1711 | }; | 1752 | }; |
1712 | 1753 | ||
1713 | #define TX_PACKET_MODE_REGULAR 0x0000 | 1754 | #define TX_PACKET_MODE_REGULAR 0x0000 |
@@ -1729,30 +1770,6 @@ enum { | |||
1729 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ | 1770 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ |
1730 | }; | 1771 | }; |
1731 | 1772 | ||
1732 | static inline u32 iwl_tx_status_to_mac80211(u32 status) | ||
1733 | { | ||
1734 | status &= TX_STATUS_MSK; | ||
1735 | |||
1736 | switch (status) { | ||
1737 | case TX_STATUS_SUCCESS: | ||
1738 | case TX_STATUS_DIRECT_DONE: | ||
1739 | return IEEE80211_TX_STAT_ACK; | ||
1740 | case TX_STATUS_FAIL_DEST_PS: | ||
1741 | return IEEE80211_TX_STAT_TX_FILTERED; | ||
1742 | default: | ||
1743 | return 0; | ||
1744 | } | ||
1745 | } | ||
1746 | |||
1747 | static inline bool iwl_is_tx_success(u32 status) | ||
1748 | { | ||
1749 | status &= TX_STATUS_MSK; | ||
1750 | return (status == TX_STATUS_SUCCESS) || | ||
1751 | (status == TX_STATUS_DIRECT_DONE); | ||
1752 | } | ||
1753 | |||
1754 | |||
1755 | |||
1756 | /* ******************************* | 1773 | /* ******************************* |
1757 | * TX aggregation status | 1774 | * TX aggregation status |
1758 | ******************************* */ | 1775 | ******************************* */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index a631afef5e33..aea6a2eee9c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -629,29 +629,36 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
629 | EXPORT_SYMBOL(iwl_tx_cmd_complete); | 629 | EXPORT_SYMBOL(iwl_tx_cmd_complete); |
630 | 630 | ||
631 | #ifdef CONFIG_IWLWIFI_DEBUG | 631 | #ifdef CONFIG_IWLWIFI_DEBUG |
632 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 632 | #define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x |
633 | #define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x | ||
633 | 634 | ||
634 | const char *iwl_get_tx_fail_reason(u32 status) | 635 | const char *iwl_get_tx_fail_reason(u32 status) |
635 | { | 636 | { |
636 | switch (status & TX_STATUS_MSK) { | 637 | switch (status & TX_STATUS_MSK) { |
637 | case TX_STATUS_SUCCESS: | 638 | case TX_STATUS_SUCCESS: |
638 | return "SUCCESS"; | 639 | return "SUCCESS"; |
639 | TX_STATUS_ENTRY(SHORT_LIMIT); | 640 | TX_STATUS_POSTPONE(DELAY); |
640 | TX_STATUS_ENTRY(LONG_LIMIT); | 641 | TX_STATUS_POSTPONE(FEW_BYTES); |
641 | TX_STATUS_ENTRY(FIFO_UNDERRUN); | 642 | TX_STATUS_POSTPONE(BT_PRIO); |
642 | TX_STATUS_ENTRY(MGMNT_ABORT); | 643 | TX_STATUS_POSTPONE(QUIET_PERIOD); |
643 | TX_STATUS_ENTRY(NEXT_FRAG); | 644 | TX_STATUS_POSTPONE(CALC_TTAK); |
644 | TX_STATUS_ENTRY(LIFE_EXPIRE); | 645 | TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY); |
645 | TX_STATUS_ENTRY(DEST_PS); | 646 | TX_STATUS_FAIL(SHORT_LIMIT); |
646 | TX_STATUS_ENTRY(ABORTED); | 647 | TX_STATUS_FAIL(LONG_LIMIT); |
647 | TX_STATUS_ENTRY(BT_RETRY); | 648 | TX_STATUS_FAIL(FIFO_UNDERRUN); |
648 | TX_STATUS_ENTRY(STA_INVALID); | 649 | TX_STATUS_FAIL(DRAIN_FLOW); |
649 | TX_STATUS_ENTRY(FRAG_DROPPED); | 650 | TX_STATUS_FAIL(RFKILL_FLUSH); |
650 | TX_STATUS_ENTRY(TID_DISABLE); | 651 | TX_STATUS_FAIL(LIFE_EXPIRE); |
651 | TX_STATUS_ENTRY(FRAME_FLUSHED); | 652 | TX_STATUS_FAIL(DEST_PS); |
652 | TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); | 653 | TX_STATUS_FAIL(HOST_ABORTED); |
653 | TX_STATUS_ENTRY(TX_LOCKED); | 654 | TX_STATUS_FAIL(BT_RETRY); |
654 | TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); | 655 | TX_STATUS_FAIL(STA_INVALID); |
656 | TX_STATUS_FAIL(FRAG_DROPPED); | ||
657 | TX_STATUS_FAIL(TID_DISABLE); | ||
658 | TX_STATUS_FAIL(FIFO_FLUSHED); | ||
659 | TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); | ||
660 | TX_STATUS_FAIL(FW_DROP); | ||
661 | TX_STATUS_FAIL(STA_COLOR_MISMATCH_DROP); | ||
655 | } | 662 | } |
656 | 663 | ||
657 | return "UNKNOWN"; | 664 | return "UNKNOWN"; |