aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c41
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
196static const char *iwl3945_get_tx_fail_reason(u32 status) 196static 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
2056static int iwl4965_calc_rssi(struct iwl_priv *priv, 2055static 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
164void 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
164static void iwlagn_rx_reply_tx(struct iwl_priv *priv, 172static 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
253void iwlagn_rx_handler_setup(struct iwl_priv *priv) 260void 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);
105int iwlagn_alive_notify(struct iwl_priv *priv); 105int iwlagn_alive_notify(struct iwl_priv *priv);
106 106
107/* lib */ 107/* lib */
108void iwl_check_abort_status(struct iwl_priv *priv,
109 u8 frame_count, u32 status);
108void iwlagn_rx_handler_setup(struct iwl_priv *priv); 110void iwlagn_rx_handler_setup(struct iwl_priv *priv);
109void iwlagn_setup_deferred_work(struct iwl_priv *priv); 111void iwlagn_setup_deferred_work(struct iwl_priv *priv);
110int iwlagn_hw_valid_rtc_data_addr(u32 addr); 112int iwlagn_hw_valid_rtc_data_addr(u32 addr);
@@ -146,4 +148,26 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv);
146int iwlagn_txq_ctx_reset(struct iwl_priv *priv); 148int iwlagn_txq_ctx_reset(struct iwl_priv *priv);
147void iwlagn_txq_ctx_stop(struct iwl_priv *priv); 149void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
148 150
151static 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
166static 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 */
1692enum { 1692enum {
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 */
1720enum {
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
1732static 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
1747static 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)
629EXPORT_SYMBOL(iwl_tx_cmd_complete); 629EXPORT_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
634const char *iwl_get_tx_fail_reason(u32 status) 635const 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";