aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-11-16 14:07:54 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-16 14:07:54 -0500
commitdfbebe14428803402293d9a8bf1efef7221d8b78 (patch)
treecd81cb3822ef4fca5925ef3bf0775eb74e905e57
parent0f62248501cbf5047486601d7e39d5ee36d478c2 (diff)
parentd18aa87fbfe80f33076942d11f19c9d813e835b1 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Conflicts: drivers/net/wireless/iwlwifi/pcie/trans.c
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c37
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c18
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h27
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h17
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c39
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c27
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c85
17 files changed, 183 insertions, 112 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 727fbb5db9d..5cf43236421 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -133,12 +133,3 @@ config IWLWIFI_P2P
133 support when it is loaded. 133 support when it is loaded.
134 134
135 Say Y only if you want to experiment with P2P. 135 Say Y only if you want to experiment with P2P.
136
137config IWLWIFI_EXPERIMENTAL_MFP
138 bool "support MFP (802.11w) even if uCode doesn't advertise"
139 depends on IWLWIFI
140 help
141 This option enables experimental MFP (802.11W) support
142 even if the microcode doesn't advertise it.
143
144 Say Y only if you want to experiment with MFP.
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 75e12f29d9e..33b3ad2e546 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -176,8 +176,8 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
176/* lib */ 176/* lib */
177int iwlagn_send_tx_power(struct iwl_priv *priv); 177int iwlagn_send_tx_power(struct iwl_priv *priv);
178void iwlagn_temperature(struct iwl_priv *priv); 178void iwlagn_temperature(struct iwl_priv *priv);
179int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 179int iwlagn_txfifo_flush(struct iwl_priv *priv);
180void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 180void iwlagn_dev_txfifo_flush(struct iwl_priv *priv);
181int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 181int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
182int iwl_send_statistics_request(struct iwl_priv *priv, 182int iwl_send_statistics_request(struct iwl_priv *priv,
183 u8 flags, bool clear); 183 u8 flags, bool clear);
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 01128c96b5d..71ab76b2b39 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -986,8 +986,7 @@ struct iwl_rem_sta_cmd {
986 986
987#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) 987#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00)
988 988
989#define IWL_DROP_SINGLE 0 989#define IWL_DROP_ALL BIT(1)
990#define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN))
991 990
992/* 991/*
993 * REPLY_TXFIFO_FLUSH = 0x1e(command and response) 992 * REPLY_TXFIFO_FLUSH = 0x1e(command and response)
@@ -1004,14 +1003,14 @@ struct iwl_rem_sta_cmd {
1004 * the flush operation ends when both the scheduler DMA done and TXFIFO empty 1003 * the flush operation ends when both the scheduler DMA done and TXFIFO empty
1005 * are set. 1004 * are set.
1006 * 1005 *
1007 * @fifo_control: bit mask for which queues to flush 1006 * @queue_control: bit mask for which queues to flush
1008 * @flush_control: flush controls 1007 * @flush_control: flush controls
1009 * 0: Dump single MSDU 1008 * 0: Dump single MSDU
1010 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. 1009 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
1011 * 2: Dump all FIFO 1010 * 2: Dump all FIFO
1012 */ 1011 */
1013struct iwl_txfifo_flush_cmd { 1012struct iwl_txfifo_flush_cmd {
1014 __le32 fifo_control; 1013 __le32 queue_control;
1015 __le16 flush_control; 1014 __le16 flush_control;
1016 __le16 reserved; 1015 __le16 reserved;
1017} __packed; 1016} __packed;
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index 1a98fa3ab06..769a08bca86 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -2101,7 +2101,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
2101 if (iwl_is_rfkill(priv)) 2101 if (iwl_is_rfkill(priv))
2102 return -EFAULT; 2102 return -EFAULT;
2103 2103
2104 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); 2104 iwlagn_dev_txfifo_flush(priv);
2105 2105
2106 return count; 2106 return count;
2107} 2107}
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index bef88c1a2c9..7e59be4b89b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
136 * 1. acquire mutex before calling 136 * 1. acquire mutex before calling
137 * 2. make sure rf is on and not in exit state 137 * 2. make sure rf is on and not in exit state
138 */ 138 */
139int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) 139int iwlagn_txfifo_flush(struct iwl_priv *priv)
140{ 140{
141 struct iwl_txfifo_flush_cmd flush_cmd; 141 struct iwl_txfifo_flush_cmd flush_cmd;
142 struct iwl_host_cmd cmd = { 142 struct iwl_host_cmd cmd = {
@@ -146,35 +146,34 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
146 .data = { &flush_cmd, }, 146 .data = { &flush_cmd, },
147 }; 147 };
148 148
149 might_sleep();
150
151 memset(&flush_cmd, 0, sizeof(flush_cmd)); 149 memset(&flush_cmd, 0, sizeof(flush_cmd));
152 if (flush_control & BIT(IWL_RXON_CTX_BSS)) 150
153 flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | 151 flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
154 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | 152 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK |
155 IWL_SCD_MGMT_MSK; 153 IWL_SCD_MGMT_MSK;
156 if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && 154 if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
157 (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) 155 flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK |
158 flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | 156 IWL_PAN_SCD_VI_MSK |
159 IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | 157 IWL_PAN_SCD_BE_MSK |
160 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | 158 IWL_PAN_SCD_BK_MSK |
161 IWL_PAN_SCD_MULTICAST_MSK; 159 IWL_PAN_SCD_MGMT_MSK |
160 IWL_PAN_SCD_MULTICAST_MSK;
162 161
163 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) 162 if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)
164 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; 163 flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK;
165 164
166 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", 165 IWL_DEBUG_INFO(priv, "queue control: 0x%x\n",
167 flush_cmd.fifo_control); 166 flush_cmd.queue_control);
168 flush_cmd.flush_control = cpu_to_le16(flush_control); 167 flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL);
169 168
170 return iwl_dvm_send_cmd(priv, &cmd); 169 return iwl_dvm_send_cmd(priv, &cmd);
171} 170}
172 171
173void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) 172void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
174{ 173{
175 mutex_lock(&priv->mutex); 174 mutex_lock(&priv->mutex);
176 ieee80211_stop_queues(priv->hw); 175 ieee80211_stop_queues(priv->hw);
177 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { 176 if (iwlagn_txfifo_flush(priv)) {
178 IWL_ERR(priv, "flush request fail\n"); 177 IWL_ERR(priv, "flush request fail\n");
179 goto done; 178 goto done;
180 } 179 }
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index ff8162d4c45..cb443d54f9b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -168,10 +168,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
168 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 168 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
169 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 169 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
170 170
171#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP
172 /* enable 11w if the uCode advertise */ 171 /* enable 11w if the uCode advertise */
173 if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) 172 if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
174#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */
175 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 173 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
176 174
177 hw->sta_data_size = sizeof(struct iwl_station_priv); 175 hw->sta_data_size = sizeof(struct iwl_station_priv);
@@ -1019,7 +1017,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
1019 */ 1017 */
1020 if (drop) { 1018 if (drop) {
1021 IWL_DEBUG_MAC80211(priv, "send flush command\n"); 1019 IWL_DEBUG_MAC80211(priv, "send flush command\n");
1022 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { 1020 if (iwlagn_txfifo_flush(priv)) {
1023 IWL_ERR(priv, "flush request fail\n"); 1021 IWL_ERR(priv, "flush request fail\n");
1024 goto done; 1022 goto done;
1025 } 1023 }
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 475df45c832..03cbfa765f8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -511,7 +511,7 @@ static void iwl_bg_tx_flush(struct work_struct *work)
511 return; 511 return;
512 512
513 IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); 513 IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
514 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); 514 iwlagn_dev_txfifo_flush(priv);
515} 515}
516 516
517/* 517/*
@@ -1204,7 +1204,7 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1204 return -EINVAL; 1204 return -EINVAL;
1205 } 1205 }
1206 1206
1207 IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); 1207 IWL_DEBUG_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku);
1208 1208
1209 priv->hw_params.tx_chains_num = 1209 priv->hw_params.tx_chains_num =
1210 num_of_ant(priv->eeprom_data->valid_tx_ant); 1210 num_of_ant(priv->eeprom_data->valid_tx_ant);
@@ -1214,9 +1214,9 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
1214 priv->hw_params.rx_chains_num = 1214 priv->hw_params.rx_chains_num =
1215 num_of_ant(priv->eeprom_data->valid_rx_ant); 1215 num_of_ant(priv->eeprom_data->valid_rx_ant);
1216 1216
1217 IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", 1217 IWL_DEBUG_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
1218 priv->eeprom_data->valid_tx_ant, 1218 priv->eeprom_data->valid_tx_ant,
1219 priv->eeprom_data->valid_rx_ant); 1219 priv->eeprom_data->valid_rx_ant);
1220 1220
1221 return 0; 1221 return 0;
1222} 1222}
@@ -1231,7 +1231,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1231 struct iwl_op_mode *op_mode; 1231 struct iwl_op_mode *op_mode;
1232 u16 num_mac; 1232 u16 num_mac;
1233 u32 ucode_flags; 1233 u32 ucode_flags;
1234 struct iwl_trans_config trans_cfg; 1234 struct iwl_trans_config trans_cfg = {};
1235 static const u8 no_reclaim_cmds[] = { 1235 static const u8 no_reclaim_cmds[] = {
1236 REPLY_RX_PHY_CMD, 1236 REPLY_RX_PHY_CMD,
1237 REPLY_RX_MPDU_CMD, 1237 REPLY_RX_MPDU_CMD,
@@ -1507,10 +1507,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1507 1507
1508 iwl_tt_exit(priv); 1508 iwl_tt_exit(priv);
1509 1509
1510 /*This will stop the queues, move the device to low power state */
1511 priv->ucode_loaded = false;
1512 iwl_trans_stop_device(priv->trans);
1513
1514 kfree(priv->eeprom_blob); 1510 kfree(priv->eeprom_blob);
1515 iwl_free_eeprom_data(priv->eeprom_data); 1511 iwl_free_eeprom_data(priv->eeprom_data);
1516 1512
@@ -1926,8 +1922,6 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
1926 * commands by clearing the ready bit */ 1922 * commands by clearing the ready bit */
1927 clear_bit(STATUS_READY, &priv->status); 1923 clear_bit(STATUS_READY, &priv->status);
1928 1924
1929 wake_up(&priv->trans->wait_command_queue);
1930
1931 if (!ondemand) { 1925 if (!ondemand) {
1932 /* 1926 /*
1933 * If firmware keep reloading, then it indicate something 1927 * If firmware keep reloading, then it indicate something
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index 5a9c325804f..9a8d5020774 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -631,8 +631,6 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
631 test_bit(STATUS_RF_KILL_HW, &priv->status))) 631 test_bit(STATUS_RF_KILL_HW, &priv->status)))
632 wiphy_rfkill_set_hw_state(priv->hw->wiphy, 632 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
633 test_bit(STATUS_RF_KILL_HW, &priv->status)); 633 test_bit(STATUS_RF_KILL_HW, &priv->status));
634 else
635 wake_up(&priv->trans->wait_command_queue);
636 return 0; 634 return 0;
637} 635}
638 636
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index f5ca73a8987..4ae031f6726 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -1075,14 +1075,11 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
1075 1075
1076static void iwlagn_set_tx_status(struct iwl_priv *priv, 1076static void iwlagn_set_tx_status(struct iwl_priv *priv,
1077 struct ieee80211_tx_info *info, 1077 struct ieee80211_tx_info *info,
1078 struct iwlagn_tx_resp *tx_resp, 1078 struct iwlagn_tx_resp *tx_resp)
1079 bool is_agg)
1080{ 1079{
1081 u16 status = le16_to_cpu(tx_resp->status.status); 1080 u16 status = le16_to_cpu(tx_resp->status.status);
1082 1081
1083 info->status.rates[0].count = tx_resp->failure_frame + 1; 1082 info->status.rates[0].count = tx_resp->failure_frame + 1;
1084 if (is_agg)
1085 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1086 info->flags |= iwl_tx_status_to_mac80211(status); 1083 info->flags |= iwl_tx_status_to_mac80211(status);
1087 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), 1084 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
1088 info); 1085 info);
@@ -1231,7 +1228,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1231 if (is_agg && !iwl_is_tx_success(status)) 1228 if (is_agg && !iwl_is_tx_success(status))
1232 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1229 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1233 iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb), 1230 iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb),
1234 tx_resp, is_agg); 1231 tx_resp);
1235 if (!is_agg) 1232 if (!is_agg)
1236 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); 1233 iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
1237 1234
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 2cb1efbc5ed..95e6d33f515 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -254,7 +254,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
254 int ret; 254 int ret;
255 int i; 255 int i;
256 256
257 iwl_trans_fw_alive(priv->trans); 257 iwl_trans_fw_alive(priv->trans, 0);
258 258
259 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && 259 if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN &&
260 priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) { 260 priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 678717bf62e..b3fde5f7b9b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -306,7 +306,7 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
306 memcpy(__get_dynamic_array(data), 306 memcpy(__get_dynamic_array(data),
307 ((u8 *)rxbuf) + offs, len - offs); 307 ((u8 *)rxbuf) + offs, len - offs);
308 ), 308 ),
309 TP_printk("[%s] TX frame data", __get_str(dev)) 309 TP_printk("[%s] RX frame data", __get_str(dev))
310); 310);
311 311
312#undef TRACE_SYSTEM 312#undef TRACE_SYSTEM
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index f10170fe879..4a9dc9629ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -889,8 +889,8 @@ int iwl_eeprom_check_version(struct iwl_eeprom_data *data,
889{ 889{
890 if (data->eeprom_version >= trans->cfg->eeprom_ver || 890 if (data->eeprom_version >= trans->cfg->eeprom_ver ||
891 data->calib_version >= trans->cfg->eeprom_calib_ver) { 891 data->calib_version >= trans->cfg->eeprom_calib_ver) {
892 IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", 892 IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
893 data->eeprom_version, data->calib_version); 893 data->eeprom_version, data->calib_version);
894 return 0; 894 return 0;
895 } 895 }
896 896
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index f75ea6d73ff..e378ea6dca9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -221,14 +221,21 @@ struct iwl_device_cmd {
221/** 221/**
222 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command 222 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
223 * 223 *
224 * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's 224 * @IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's
225 * ring. The transport layer doesn't map the command's buffer to DMA, but 225 * ring. The transport layer doesn't map the command's buffer to DMA, but
226 * rather copies it to an previously allocated DMA buffer. This flag tells 226 * rather copies it to an previously allocated DMA buffer. This flag tells
227 * the transport layer not to copy the command, but to map the existing 227 * the transport layer not to copy the command, but to map the existing
228 * buffer. This can save memcpy and is worth with very big comamnds. 228 * buffer (that is passed in) instead. This saves the memcpy and allows
229 * commands that are bigger than the fixed buffer to be submitted.
230 * Note that a TFD entry after a NOCOPY one cannot be a normal copied one.
231 * @IWL_HCMD_DFL_DUP: Only valid without NOCOPY, duplicate the memory for this
232 * chunk internally and free it again after the command completes. This
233 * can (currently) be used only once per command.
234 * Note that a TFD entry after a DUP one cannot be a normal copied one.
229 */ 235 */
230enum iwl_hcmd_dataflag { 236enum iwl_hcmd_dataflag {
231 IWL_HCMD_DFL_NOCOPY = BIT(0), 237 IWL_HCMD_DFL_NOCOPY = BIT(0),
238 IWL_HCMD_DFL_DUP = BIT(1),
232}; 239};
233 240
234/** 241/**
@@ -348,14 +355,17 @@ struct iwl_trans;
348 * @start_fw: allocates and inits all the resources for the transport 355 * @start_fw: allocates and inits all the resources for the transport
349 * layer. Also kick a fw image. 356 * layer. Also kick a fw image.
350 * May sleep 357 * May sleep
351 * @fw_alive: called when the fw sends alive notification 358 * @fw_alive: called when the fw sends alive notification. If the fw provides
359 * the SCD base address in SRAM, then provide it here, or 0 otherwise.
352 * May sleep 360 * May sleep
353 * @stop_device:stops the whole device (embedded CPU put to reset) 361 * @stop_device:stops the whole device (embedded CPU put to reset)
354 * May sleep 362 * May sleep
355 * @wowlan_suspend: put the device into the correct mode for WoWLAN during 363 * @wowlan_suspend: put the device into the correct mode for WoWLAN during
356 * suspend. This is optional, if not implemented WoWLAN will not be 364 * suspend. This is optional, if not implemented WoWLAN will not be
357 * supported. This callback may sleep. 365 * supported. This callback may sleep.
358 * @send_cmd:send a host command 366 * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted.
367 * If RFkill is asserted in the middle of a SYNC host command, it must
368 * return -ERFKILL straight away.
359 * May sleep only if CMD_SYNC is set 369 * May sleep only if CMD_SYNC is set
360 * @tx: send an skb 370 * @tx: send an skb
361 * Must be atomic 371 * Must be atomic
@@ -385,7 +395,7 @@ struct iwl_trans_ops {
385 int (*start_hw)(struct iwl_trans *iwl_trans); 395 int (*start_hw)(struct iwl_trans *iwl_trans);
386 void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); 396 void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving);
387 int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); 397 int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw);
388 void (*fw_alive)(struct iwl_trans *trans); 398 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
389 void (*stop_device)(struct iwl_trans *trans); 399 void (*stop_device)(struct iwl_trans *trans);
390 400
391 void (*wowlan_suspend)(struct iwl_trans *trans); 401 void (*wowlan_suspend)(struct iwl_trans *trans);
@@ -438,7 +448,6 @@ enum iwl_trans_state {
438 * Set during transport allocation. 448 * Set during transport allocation.
439 * @hw_id_str: a string with info about HW ID. Set during transport allocation. 449 * @hw_id_str: a string with info about HW ID. Set during transport allocation.
440 * @pm_support: set to true in start_hw if link pm is supported 450 * @pm_support: set to true in start_hw if link pm is supported
441 * @wait_command_queue: the wait_queue for SYNC host commands
442 * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. 451 * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
443 * The user should use iwl_trans_{alloc,free}_tx_cmd. 452 * The user should use iwl_trans_{alloc,free}_tx_cmd.
444 * @dev_cmd_headroom: room needed for the transport's private use before the 453 * @dev_cmd_headroom: room needed for the transport's private use before the
@@ -465,8 +474,6 @@ struct iwl_trans {
465 474
466 bool pm_support; 475 bool pm_support;
467 476
468 wait_queue_head_t wait_command_queue;
469
470 /* The following fields are internal only */ 477 /* The following fields are internal only */
471 struct kmem_cache *dev_cmd_pool; 478 struct kmem_cache *dev_cmd_pool;
472 size_t dev_cmd_headroom; 479 size_t dev_cmd_headroom;
@@ -508,13 +515,13 @@ static inline void iwl_trans_stop_hw(struct iwl_trans *trans,
508 trans->state = IWL_TRANS_NO_FW; 515 trans->state = IWL_TRANS_NO_FW;
509} 516}
510 517
511static inline void iwl_trans_fw_alive(struct iwl_trans *trans) 518static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr)
512{ 519{
513 might_sleep(); 520 might_sleep();
514 521
515 trans->state = IWL_TRANS_FW_ALIVE; 522 trans->state = IWL_TRANS_FW_ALIVE;
516 523
517 trans->ops->fw_alive(trans); 524 trans->ops->fw_alive(trans, scd_addr);
518} 525}
519 526
520static inline int iwl_trans_start_fw(struct iwl_trans *trans, 527static inline int iwl_trans_start_fw(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 401178f44a3..1f065c630d4 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -186,6 +186,8 @@ struct iwl_pcie_tx_queue_entry {
186 struct iwl_device_cmd *cmd; 186 struct iwl_device_cmd *cmd;
187 struct iwl_device_cmd *copy_cmd; 187 struct iwl_device_cmd *copy_cmd;
188 struct sk_buff *skb; 188 struct sk_buff *skb;
189 /* buffer to free after command completes */
190 const void *free_buf;
189 struct iwl_cmd_meta meta; 191 struct iwl_cmd_meta meta;
190}; 192};
191 193
@@ -268,6 +270,8 @@ struct iwl_trans_pcie {
268 270
269 bool ucode_write_complete; 271 bool ucode_write_complete;
270 wait_queue_head_t ucode_write_waitq; 272 wait_queue_head_t ucode_write_waitq;
273 wait_queue_head_t wait_command_queue;
274
271 unsigned long status; 275 unsigned long status;
272 u8 cmd_queue; 276 u8 cmd_queue;
273 u8 cmd_fifo; 277 u8 cmd_fifo;
@@ -286,10 +290,14 @@ struct iwl_trans_pcie {
286/***************************************************** 290/*****************************************************
287* DRIVER STATUS FUNCTIONS 291* DRIVER STATUS FUNCTIONS
288******************************************************/ 292******************************************************/
289#define STATUS_HCMD_ACTIVE 0 293enum {
290#define STATUS_DEVICE_ENABLED 1 294 STATUS_HCMD_ACTIVE,
291#define STATUS_TPOWER_PMI 2 295 STATUS_DEVICE_ENABLED,
292#define STATUS_INT_ENABLED 3 296 STATUS_TPOWER_PMI,
297 STATUS_INT_ENABLED,
298 STATUS_RFKILL,
299 STATUS_FW_ERROR,
300};
293 301
294#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 302#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
295 ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) 303 ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific))
@@ -346,6 +354,7 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
346 enum dma_data_direction dma_dir); 354 enum dma_data_direction dma_dir);
347int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, 355int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
348 struct sk_buff_head *skbs); 356 struct sk_buff_head *skbs);
357void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id);
349int iwl_queue_space(const struct iwl_queue *q); 358int iwl_queue_space(const struct iwl_queue *q);
350 359
351/***************************************************** 360/*****************************************************
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 137af4c46a6..11a93eddc84 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -199,7 +199,6 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans)
199{ 199{
200 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 200 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
201 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 201 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
202 struct list_head *element;
203 struct iwl_rx_mem_buffer *rxb; 202 struct iwl_rx_mem_buffer *rxb;
204 unsigned long flags; 203 unsigned long flags;
205 204
@@ -221,9 +220,9 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans)
221 BUG_ON(rxb && rxb->page); 220 BUG_ON(rxb && rxb->page);
222 221
223 /* Get next free Rx buffer, remove from free list */ 222 /* Get next free Rx buffer, remove from free list */
224 element = rxq->rx_free.next; 223 rxb = list_first_entry(&rxq->rx_free, struct iwl_rx_mem_buffer,
225 rxb = list_entry(element, struct iwl_rx_mem_buffer, list); 224 list);
226 list_del(element); 225 list_del(&rxb->list);
227 226
228 /* Point to Rx buffer via next RBD in circular buffer */ 227 /* Point to Rx buffer via next RBD in circular buffer */
229 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma); 228 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma);
@@ -260,7 +259,6 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
260{ 259{
261 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 260 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
262 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 261 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
263 struct list_head *element;
264 struct iwl_rx_mem_buffer *rxb; 262 struct iwl_rx_mem_buffer *rxb;
265 struct page *page; 263 struct page *page;
266 unsigned long flags; 264 unsigned long flags;
@@ -308,10 +306,9 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
308 __free_pages(page, trans_pcie->rx_page_order); 306 __free_pages(page, trans_pcie->rx_page_order);
309 return; 307 return;
310 } 308 }
311 element = rxq->rx_used.next; 309 rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer,
312 rxb = list_entry(element, struct iwl_rx_mem_buffer, list); 310 list);
313 list_del(element); 311 list_del(&rxb->list);
314
315 spin_unlock_irqrestore(&rxq->lock, flags); 312 spin_unlock_irqrestore(&rxq->lock, flags);
316 313
317 BUG_ON(rxb->page); 314 BUG_ON(rxb->page);
@@ -452,6 +449,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
452 /* The original command isn't needed any more */ 449 /* The original command isn't needed any more */
453 kfree(txq->entries[cmd_index].copy_cmd); 450 kfree(txq->entries[cmd_index].copy_cmd);
454 txq->entries[cmd_index].copy_cmd = NULL; 451 txq->entries[cmd_index].copy_cmd = NULL;
452 /* nor is the duplicated part of the command */
453 kfree(txq->entries[cmd_index].free_buf);
454 txq->entries[cmd_index].free_buf = NULL;
455 } 455 }
456 456
457 /* 457 /*
@@ -565,24 +565,27 @@ static void iwl_rx_handle(struct iwl_trans *trans)
565 */ 565 */
566static void iwl_irq_handle_error(struct iwl_trans *trans) 566static void iwl_irq_handle_error(struct iwl_trans *trans)
567{ 567{
568 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
569
568 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ 570 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
569 if (trans->cfg->internal_wimax_coex && 571 if (trans->cfg->internal_wimax_coex &&
570 (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & 572 (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) &
571 APMS_CLK_VAL_MRB_FUNC_MODE) || 573 APMS_CLK_VAL_MRB_FUNC_MODE) ||
572 (iwl_read_prph(trans, APMG_PS_CTRL_REG) & 574 (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
573 APMG_PS_CTRL_VAL_RESET_REQ))) { 575 APMG_PS_CTRL_VAL_RESET_REQ))) {
574 struct iwl_trans_pcie *trans_pcie =
575 IWL_TRANS_GET_PCIE_TRANS(trans);
576
577 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 576 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
578 iwl_op_mode_wimax_active(trans->op_mode); 577 iwl_op_mode_wimax_active(trans->op_mode);
579 wake_up(&trans->wait_command_queue); 578 wake_up(&trans_pcie->wait_command_queue);
580 return; 579 return;
581 } 580 }
582 581
583 iwl_dump_csr(trans); 582 iwl_dump_csr(trans);
584 iwl_dump_fh(trans, NULL); 583 iwl_dump_fh(trans, NULL);
585 584
585 set_bit(STATUS_FW_ERROR, &trans_pcie->status);
586 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
587 wake_up(&trans_pcie->wait_command_queue);
588
586 iwl_op_mode_nic_error(trans->op_mode); 589 iwl_op_mode_nic_error(trans->op_mode);
587} 590}
588 591
@@ -676,6 +679,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
676 isr_stats->rfkill++; 679 isr_stats->rfkill++;
677 680
678 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 681 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
682 if (hw_rfkill) {
683 set_bit(STATUS_RFKILL, &trans_pcie->status);
684 if (test_and_clear_bit(STATUS_HCMD_ACTIVE,
685 &trans_pcie->status))
686 IWL_DEBUG_RF_KILL(trans,
687 "Rfkill while SYNC HCMD in flight\n");
688 wake_up(&trans_pcie->wait_command_queue);
689 } else {
690 clear_bit(STATUS_RFKILL, &trans_pcie->status);
691 }
679 692
680 handled |= CSR_INT_BIT_RF_KILL; 693 handled |= CSR_INT_BIT_RF_KILL;
681 } 694 }
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 4d9dfa7de4e..f21bf661931 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -442,10 +442,10 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq,
442 return 0; 442 return 0;
443} 443}
444 444
445/** 445/*
446 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's 446 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
447 */ 447 */
448static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) 448void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
449{ 449{
450 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 450 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
451 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; 451 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
@@ -496,6 +496,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
496 for (i = 0; i < txq->q.n_window; i++) { 496 for (i = 0; i < txq->q.n_window; i++) {
497 kfree(txq->entries[i].cmd); 497 kfree(txq->entries[i].cmd);
498 kfree(txq->entries[i].copy_cmd); 498 kfree(txq->entries[i].copy_cmd);
499 kfree(txq->entries[i].free_buf);
499 } 500 }
500 501
501 /* De-alloc circular buffer of TFDs */ 502 /* De-alloc circular buffer of TFDs */
@@ -1023,6 +1024,7 @@ static int iwl_load_given_ucode(struct iwl_trans *trans,
1023static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, 1024static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1024 const struct fw_img *fw) 1025 const struct fw_img *fw)
1025{ 1026{
1027 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1026 int ret; 1028 int ret;
1027 bool hw_rfkill; 1029 bool hw_rfkill;
1028 1030
@@ -1032,6 +1034,8 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1032 return -EIO; 1034 return -EIO;
1033 } 1035 }
1034 1036
1037 clear_bit(STATUS_FW_ERROR, &trans_pcie->status);
1038
1035 iwl_enable_rfkill_int(trans); 1039 iwl_enable_rfkill_int(trans);
1036 1040
1037 /* If platform's RF_KILL switch is NOT set to KILL */ 1041 /* If platform's RF_KILL switch is NOT set to KILL */
@@ -1076,7 +1080,7 @@ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
1076 iwl_write_prph(trans, SCD_TXFACT, mask); 1080 iwl_write_prph(trans, SCD_TXFACT, mask);
1077} 1081}
1078 1082
1079static void iwl_tx_start(struct iwl_trans *trans) 1083static void iwl_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
1080{ 1084{
1081 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1085 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1082 u32 a; 1086 u32 a;
@@ -1089,6 +1093,10 @@ static void iwl_tx_start(struct iwl_trans *trans)
1089 1093
1090 trans_pcie->scd_base_addr = 1094 trans_pcie->scd_base_addr =
1091 iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); 1095 iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
1096
1097 WARN_ON(scd_base_addr != 0 &&
1098 scd_base_addr != trans_pcie->scd_base_addr);
1099
1092 a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; 1100 a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
1093 /* reset conext data memory */ 1101 /* reset conext data memory */
1094 for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; 1102 for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
@@ -1134,10 +1142,10 @@ static void iwl_tx_start(struct iwl_trans *trans)
1134 APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 1142 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1135} 1143}
1136 1144
1137static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) 1145static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
1138{ 1146{
1139 iwl_reset_ict(trans); 1147 iwl_reset_ict(trans);
1140 iwl_tx_start(trans); 1148 iwl_tx_start(trans, scd_addr);
1141} 1149}
1142 1150
1143/** 1151/**
@@ -1243,6 +1251,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1243 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); 1251 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
1244 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); 1252 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
1245 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); 1253 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status);
1254 clear_bit(STATUS_RFKILL, &trans_pcie->status);
1246} 1255}
1247 1256
1248static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) 1257static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
@@ -2166,12 +2175,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2166 goto out_pci_release_regions; 2175 goto out_pci_release_regions;
2167 } 2176 }
2168 2177
2169 dev_info(&pdev->dev, "pci_resource_len = 0x%08llx\n",
2170 (unsigned long long) pci_resource_len(pdev, 0));
2171 dev_info(&pdev->dev, "pci_resource_base = %p\n", trans_pcie->hw_base);
2172
2173 dev_info(&pdev->dev, "HW Revision ID = 0x%X\n", pdev->revision);
2174
2175 /* We disable the RETRY_TIMEOUT register (0x41) to keep 2178 /* We disable the RETRY_TIMEOUT register (0x41) to keep
2176 * PCI Tx retries from interfering with C3 CPU state */ 2179 * PCI Tx retries from interfering with C3 CPU state */
2177 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); 2180 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
@@ -2197,7 +2200,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2197 } 2200 }
2198 2201
2199 /* Initialize the wait queue for commands */ 2202 /* Initialize the wait queue for commands */
2200 init_waitqueue_head(&trans->wait_command_queue); 2203 init_waitqueue_head(&trans_pcie->wait_command_queue);
2201 spin_lock_init(&trans->reg_lock); 2204 spin_lock_init(&trans->reg_lock);
2202 2205
2203 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), 2206 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index db3efbb84d9..dcc7e1256e3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -494,6 +494,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
494 _iwl_write_targ_mem_dwords(trans, stts_addr, 494 _iwl_write_targ_mem_dwords(trans, stts_addr,
495 zero_val, ARRAY_SIZE(zero_val)); 495 zero_val, ARRAY_SIZE(zero_val));
496 496
497 iwl_tx_queue_unmap(trans, txq_id);
498
497 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); 499 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
498} 500}
499 501
@@ -515,8 +517,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
515 struct iwl_queue *q = &txq->q; 517 struct iwl_queue *q = &txq->q;
516 struct iwl_device_cmd *out_cmd; 518 struct iwl_device_cmd *out_cmd;
517 struct iwl_cmd_meta *out_meta; 519 struct iwl_cmd_meta *out_meta;
520 void *dup_buf = NULL;
518 dma_addr_t phys_addr; 521 dma_addr_t phys_addr;
519 u32 idx; 522 int idx;
520 u16 copy_size, cmd_size; 523 u16 copy_size, cmd_size;
521 bool had_nocopy = false; 524 bool had_nocopy = false;
522 int i; 525 int i;
@@ -533,10 +536,33 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
533 continue; 536 continue;
534 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { 537 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
535 had_nocopy = true; 538 had_nocopy = true;
539 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
540 idx = -EINVAL;
541 goto free_dup_buf;
542 }
543 } else if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) {
544 /*
545 * This is also a chunk that isn't copied
546 * to the static buffer so set had_nocopy.
547 */
548 had_nocopy = true;
549
550 /* only allowed once */
551 if (WARN_ON(dup_buf)) {
552 idx = -EINVAL;
553 goto free_dup_buf;
554 }
555
556 dup_buf = kmemdup(cmd->data[i], cmd->len[i],
557 GFP_ATOMIC);
558 if (!dup_buf)
559 return -ENOMEM;
536 } else { 560 } else {
537 /* NOCOPY must not be followed by normal! */ 561 /* NOCOPY must not be followed by normal! */
538 if (WARN_ON(had_nocopy)) 562 if (WARN_ON(had_nocopy)) {
539 return -EINVAL; 563 idx = -EINVAL;
564 goto free_dup_buf;
565 }
540 copy_size += cmd->len[i]; 566 copy_size += cmd->len[i];
541 } 567 }
542 cmd_size += cmd->len[i]; 568 cmd_size += cmd->len[i];
@@ -551,8 +577,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
551 if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, 577 if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE,
552 "Command %s (%#x) is too large (%d bytes)\n", 578 "Command %s (%#x) is too large (%d bytes)\n",
553 trans_pcie_get_cmd_string(trans_pcie, cmd->id), 579 trans_pcie_get_cmd_string(trans_pcie, cmd->id),
554 cmd->id, copy_size)) 580 cmd->id, copy_size)) {
555 return -EINVAL; 581 idx = -EINVAL;
582 goto free_dup_buf;
583 }
556 584
557 spin_lock_bh(&txq->lock); 585 spin_lock_bh(&txq->lock);
558 586
@@ -561,7 +589,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
561 589
562 IWL_ERR(trans, "No space in command queue\n"); 590 IWL_ERR(trans, "No space in command queue\n");
563 iwl_op_mode_cmd_queue_full(trans->op_mode); 591 iwl_op_mode_cmd_queue_full(trans->op_mode);
564 return -ENOSPC; 592 idx = -ENOSPC;
593 goto free_dup_buf;
565 } 594 }
566 595
567 idx = get_cmd_index(q, q->write_ptr); 596 idx = get_cmd_index(q, q->write_ptr);
@@ -585,7 +614,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
585 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 614 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
586 if (!cmd->len[i]) 615 if (!cmd->len[i])
587 continue; 616 continue;
588 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) 617 if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
618 IWL_HCMD_DFL_DUP))
589 break; 619 break;
590 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); 620 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
591 cmd_pos += cmd->len[i]; 621 cmd_pos += cmd->len[i];
@@ -627,11 +657,16 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
627 iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); 657 iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1);
628 658
629 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 659 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
660 const void *data = cmd->data[i];
661
630 if (!cmd->len[i]) 662 if (!cmd->len[i])
631 continue; 663 continue;
632 if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) 664 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
665 IWL_HCMD_DFL_DUP)))
633 continue; 666 continue;
634 phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], 667 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
668 data = dup_buf;
669 phys_addr = dma_map_single(trans->dev, (void *)data,
635 cmd->len[i], DMA_BIDIRECTIONAL); 670 cmd->len[i], DMA_BIDIRECTIONAL);
636 if (dma_mapping_error(trans->dev, phys_addr)) { 671 if (dma_mapping_error(trans->dev, phys_addr)) {
637 iwl_unmap_tfd(trans, out_meta, 672 iwl_unmap_tfd(trans, out_meta,
@@ -646,6 +681,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
646 } 681 }
647 682
648 out_meta->flags = cmd->flags; 683 out_meta->flags = cmd->flags;
684 if (WARN_ON_ONCE(txq->entries[idx].free_buf))
685 kfree(txq->entries[idx].free_buf);
686 txq->entries[idx].free_buf = dup_buf;
649 687
650 txq->need_update = 1; 688 txq->need_update = 1;
651 689
@@ -662,6 +700,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
662 700
663 out: 701 out:
664 spin_unlock_bh(&txq->lock); 702 spin_unlock_bh(&txq->lock);
703 free_dup_buf:
704 if (idx < 0)
705 kfree(dup_buf);
665 return idx; 706 return idx;
666} 707}
667 708
@@ -786,7 +827,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
786 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", 827 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
787 trans_pcie_get_cmd_string(trans_pcie, 828 trans_pcie_get_cmd_string(trans_pcie,
788 cmd->hdr.cmd)); 829 cmd->hdr.cmd));
789 wake_up(&trans->wait_command_queue); 830 wake_up(&trans_pcie->wait_command_queue);
790 } 831 }
791 832
792 meta->flags = 0; 833 meta->flags = 0;
@@ -845,7 +886,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
845 return ret; 886 return ret;
846 } 887 }
847 888
848 ret = wait_event_timeout(trans->wait_command_queue, 889 ret = wait_event_timeout(trans_pcie->wait_command_queue,
849 !test_bit(STATUS_HCMD_ACTIVE, 890 !test_bit(STATUS_HCMD_ACTIVE,
850 &trans_pcie->status), 891 &trans_pcie->status),
851 HOST_COMPLETE_TIMEOUT); 892 HOST_COMPLETE_TIMEOUT);
@@ -874,6 +915,19 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
874 } 915 }
875 } 916 }
876 917
918 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
919 IWL_ERR(trans, "FW error in SYNC CMD %s\n",
920 trans_pcie_get_cmd_string(trans_pcie, cmd->id));
921 ret = -EIO;
922 goto cancel;
923 }
924
925 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
926 IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
927 ret = -ERFKILL;
928 goto cancel;
929 }
930
877 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { 931 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
878 IWL_ERR(trans, "Error: Response NULL in '%s'\n", 932 IWL_ERR(trans, "Error: Response NULL in '%s'\n",
879 trans_pcie_get_cmd_string(trans_pcie, cmd->id)); 933 trans_pcie_get_cmd_string(trans_pcie, cmd->id));
@@ -905,9 +959,18 @@ cancel:
905 959
906int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 960int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
907{ 961{
962 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
963
964 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
965 return -EIO;
966
967 if (test_bit(STATUS_RFKILL, &trans_pcie->status))
968 return -ERFKILL;
969
908 if (cmd->flags & CMD_ASYNC) 970 if (cmd->flags & CMD_ASYNC)
909 return iwl_send_cmd_async(trans, cmd); 971 return iwl_send_cmd_async(trans, cmd);
910 972
973 /* We still can fail on RFKILL that can be asserted while we wait */
911 return iwl_send_cmd_sync(trans, cmd); 974 return iwl_send_cmd_sync(trans, cmd);
912} 975}
913 976