aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c101
1 files changed, 68 insertions, 33 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 5be0d3695d03..915183a3a873 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -32,7 +32,6 @@
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34 34
35#include "iwl-wifi.h"
36#include "iwl-dev.h" 35#include "iwl-dev.h"
37#include "iwl-core.h" 36#include "iwl-core.h"
38#include "iwl-io.h" 37#include "iwl-io.h"
@@ -52,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
52 struct iwlagn_tx_power_dbm_cmd tx_power_cmd; 51 struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
53 u8 tx_ant_cfg_cmd; 52 u8 tx_ant_cfg_cmd;
54 53
55 if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status), 54 if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
56 "TX Power requested while scanning!\n")) 55 "TX Power requested while scanning!\n"))
57 return -EAGAIN; 56 return -EAGAIN;
58 57
@@ -77,17 +76,19 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
77 tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; 76 tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
78 tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; 77 tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
79 78
80 if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1) 79 if (IWL_UCODE_API(priv->fw->ucode_ver) == 1)
81 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; 80 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
82 else 81 else
83 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; 82 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
84 83
85 return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC, 84 return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC,
86 sizeof(tx_power_cmd), &tx_power_cmd); 85 sizeof(tx_power_cmd), &tx_power_cmd);
87} 86}
88 87
89void iwlagn_temperature(struct iwl_priv *priv) 88void iwlagn_temperature(struct iwl_priv *priv)
90{ 89{
90 lockdep_assert_held(&priv->statistics.lock);
91
91 /* store temperature from correct statistics (in Celsius) */ 92 /* store temperature from correct statistics (in Celsius) */
92 priv->temperature = le32_to_cpu(priv->statistics.common.temperature); 93 priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
93 iwl_tt_handler(priv); 94 iwl_tt_handler(priv);
@@ -233,19 +234,19 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
233 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | 234 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
234 IWL_PAN_SCD_MULTICAST_MSK; 235 IWL_PAN_SCD_MULTICAST_MSK;
235 236
236 if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) 237 if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
237 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; 238 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
238 239
239 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", 240 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
240 flush_cmd.fifo_control); 241 flush_cmd.fifo_control);
241 flush_cmd.flush_control = cpu_to_le16(flush_control); 242 flush_cmd.flush_control = cpu_to_le16(flush_control);
242 243
243 return iwl_trans_send_cmd(trans(priv), &cmd); 244 return iwl_dvm_send_cmd(priv, &cmd);
244} 245}
245 246
246void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) 247void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
247{ 248{
248 mutex_lock(&priv->shrd->mutex); 249 mutex_lock(&priv->mutex);
249 ieee80211_stop_queues(priv->hw); 250 ieee80211_stop_queues(priv->hw);
250 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { 251 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
251 IWL_ERR(priv, "flush request fail\n"); 252 IWL_ERR(priv, "flush request fail\n");
@@ -255,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
255 iwl_trans_wait_tx_queue_empty(trans(priv)); 256 iwl_trans_wait_tx_queue_empty(trans(priv));
256done: 257done:
257 ieee80211_wake_queues(priv->hw); 258 ieee80211_wake_queues(priv->hw);
258 mutex_unlock(&priv->shrd->mutex); 259 mutex_unlock(&priv->mutex);
259} 260}
260 261
261/* 262/*
@@ -434,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
434 if (cfg(priv)->bt_params->bt_session_2) { 435 if (cfg(priv)->bt_params->bt_session_2) {
435 memcpy(&bt_cmd_2000.basic, &basic, 436 memcpy(&bt_cmd_2000.basic, &basic,
436 sizeof(basic)); 437 sizeof(basic));
437 ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, 438 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
438 CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); 439 CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000);
439 } else { 440 } else {
440 memcpy(&bt_cmd_6000.basic, &basic, 441 memcpy(&bt_cmd_6000.basic, &basic,
441 sizeof(basic)); 442 sizeof(basic));
442 ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, 443 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
443 CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); 444 CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000);
444 } 445 }
445 if (ret) 446 if (ret)
@@ -452,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena)
452 struct iwl_rxon_context *ctx, *found_ctx = NULL; 453 struct iwl_rxon_context *ctx, *found_ctx = NULL;
453 bool found_ap = false; 454 bool found_ap = false;
454 455
455 lockdep_assert_held(&priv->shrd->mutex); 456 lockdep_assert_held(&priv->mutex);
456 457
457 /* Check whether AP or GO mode is active. */ 458 /* Check whether AP or GO mode is active. */
458 if (rssi_ena) { 459 if (rssi_ena) {
@@ -565,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
565 break; 566 break;
566 } 567 }
567 568
568 mutex_lock(&priv->shrd->mutex); 569 mutex_lock(&priv->mutex);
569 570
570 /* 571 /*
571 * We can not send command to firmware while scanning. When the scan 572 * We can not send command to firmware while scanning. When the scan
@@ -574,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
574 * STATUS_SCANNING to avoid race when queue_work two times from 575 * STATUS_SCANNING to avoid race when queue_work two times from
575 * different notifications, but quit and not perform any work at all. 576 * different notifications, but quit and not perform any work at all.
576 */ 577 */
577 if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) 578 if (test_bit(STATUS_SCAN_HW, &priv->status))
578 goto out; 579 goto out;
579 580
580 iwl_update_chain_flags(priv); 581 iwl_update_chain_flags(priv);
@@ -593,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
593 */ 594 */
594 iwlagn_bt_coex_rssi_monitor(priv); 595 iwlagn_bt_coex_rssi_monitor(priv);
595out: 596out:
596 mutex_unlock(&priv->shrd->mutex); 597 mutex_unlock(&priv->mutex);
597} 598}
598 599
599/* 600/*
@@ -705,12 +706,11 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
705} 706}
706 707
707int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 708int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
708 struct iwl_rx_mem_buffer *rxb, 709 struct iwl_rx_cmd_buffer *rxb,
709 struct iwl_device_cmd *cmd) 710 struct iwl_device_cmd *cmd)
710{ 711{
711 unsigned long flags;
712 struct iwl_rx_packet *pkt = rxb_addr(rxb); 712 struct iwl_rx_packet *pkt = rxb_addr(rxb);
713 struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; 713 struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data;
714 struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; 714 struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
715 715
716 if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { 716 if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
@@ -754,9 +754,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
754 754
755 /* FIXME: based on notification, adjust the prio_boost */ 755 /* FIXME: based on notification, adjust the prio_boost */
756 756
757 spin_lock_irqsave(&priv->shrd->lock, flags);
758 priv->bt_ci_compliance = coex->bt_ci_compliance; 757 priv->bt_ci_compliance = coex->bt_ci_compliance;
759 spin_unlock_irqrestore(&priv->shrd->lock, flags);
760 return 0; 758 return 0;
761} 759}
762 760
@@ -971,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
971 u16 p1k[IWLAGN_P1K_SIZE]; 969 u16 p1k[IWLAGN_P1K_SIZE];
972 int ret, i; 970 int ret, i;
973 971
974 mutex_lock(&priv->shrd->mutex); 972 mutex_lock(&priv->mutex);
975 973
976 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || 974 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
977 key->cipher == WLAN_CIPHER_SUITE_WEP104) && 975 key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
@@ -1077,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
1077 break; 1075 break;
1078 } 1076 }
1079 1077
1080 mutex_unlock(&priv->shrd->mutex); 1078 mutex_unlock(&priv->mutex);
1081} 1079}
1082 1080
1083int iwlagn_send_patterns(struct iwl_priv *priv, 1081int iwlagn_send_patterns(struct iwl_priv *priv,
@@ -1117,13 +1115,12 @@ int iwlagn_send_patterns(struct iwl_priv *priv,
1117 } 1115 }
1118 1116
1119 cmd.data[0] = pattern_cmd; 1117 cmd.data[0] = pattern_cmd;
1120 err = iwl_trans_send_cmd(trans(priv), &cmd); 1118 err = iwl_dvm_send_cmd(priv, &cmd);
1121 kfree(pattern_cmd); 1119 kfree(pattern_cmd);
1122 return err; 1120 return err;
1123} 1121}
1124 1122
1125int iwlagn_suspend(struct iwl_priv *priv, 1123int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
1126 struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1127{ 1124{
1128 struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; 1125 struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd;
1129 struct iwl_rxon_cmd rxon; 1126 struct iwl_rxon_cmd rxon;
@@ -1194,9 +1191,9 @@ int iwlagn_suspend(struct iwl_priv *priv,
1194 1191
1195 iwl_trans_stop_device(trans(priv)); 1192 iwl_trans_stop_device(trans(priv));
1196 1193
1197 priv->shrd->wowlan = true; 1194 priv->wowlan = true;
1198 1195
1199 ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); 1196 ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
1200 if (ret) 1197 if (ret)
1201 goto out; 1198 goto out;
1202 1199
@@ -1224,11 +1221,11 @@ int iwlagn_suspend(struct iwl_priv *priv,
1224 * constraints. Since we're in the suspend path 1221 * constraints. Since we're in the suspend path
1225 * that isn't really a problem though. 1222 * that isn't really a problem though.
1226 */ 1223 */
1227 mutex_unlock(&priv->shrd->mutex); 1224 mutex_unlock(&priv->mutex);
1228 ieee80211_iter_keys(priv->hw, ctx->vif, 1225 ieee80211_iter_keys(priv->hw, ctx->vif,
1229 iwlagn_wowlan_program_keys, 1226 iwlagn_wowlan_program_keys,
1230 &key_data); 1227 &key_data);
1231 mutex_lock(&priv->shrd->mutex); 1228 mutex_lock(&priv->mutex);
1232 if (key_data.error) { 1229 if (key_data.error) {
1233 ret = -EIO; 1230 ret = -EIO;
1234 goto out; 1231 goto out;
@@ -1243,13 +1240,13 @@ int iwlagn_suspend(struct iwl_priv *priv,
1243 .len[0] = sizeof(key_data.rsc_tsc), 1240 .len[0] = sizeof(key_data.rsc_tsc),
1244 }; 1241 };
1245 1242
1246 ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); 1243 ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd);
1247 if (ret) 1244 if (ret)
1248 goto out; 1245 goto out;
1249 } 1246 }
1250 1247
1251 if (key_data.use_tkip) { 1248 if (key_data.use_tkip) {
1252 ret = iwl_trans_send_cmd_pdu(trans(priv), 1249 ret = iwl_dvm_send_cmd_pdu(priv,
1253 REPLY_WOWLAN_TKIP_PARAMS, 1250 REPLY_WOWLAN_TKIP_PARAMS,
1254 CMD_SYNC, sizeof(tkip_cmd), 1251 CMD_SYNC, sizeof(tkip_cmd),
1255 &tkip_cmd); 1252 &tkip_cmd);
@@ -1265,7 +1262,7 @@ int iwlagn_suspend(struct iwl_priv *priv,
1265 kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); 1262 kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
1266 kek_kck_cmd.replay_ctr = priv->replay_ctr; 1263 kek_kck_cmd.replay_ctr = priv->replay_ctr;
1267 1264
1268 ret = iwl_trans_send_cmd_pdu(trans(priv), 1265 ret = iwl_dvm_send_cmd_pdu(priv,
1269 REPLY_WOWLAN_KEK_KCK_MATERIAL, 1266 REPLY_WOWLAN_KEK_KCK_MATERIAL,
1270 CMD_SYNC, sizeof(kek_kck_cmd), 1267 CMD_SYNC, sizeof(kek_kck_cmd),
1271 &kek_kck_cmd); 1268 &kek_kck_cmd);
@@ -1274,12 +1271,12 @@ int iwlagn_suspend(struct iwl_priv *priv,
1274 } 1271 }
1275 } 1272 }
1276 1273
1277 ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, 1274 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC,
1278 sizeof(d3_cfg_cmd), &d3_cfg_cmd); 1275 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
1279 if (ret) 1276 if (ret)
1280 goto out; 1277 goto out;
1281 1278
1282 ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, 1279 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER,
1283 CMD_SYNC, sizeof(wakeup_filter_cmd), 1280 CMD_SYNC, sizeof(wakeup_filter_cmd),
1284 &wakeup_filter_cmd); 1281 &wakeup_filter_cmd);
1285 if (ret) 1282 if (ret)
@@ -1291,3 +1288,41 @@ int iwlagn_suspend(struct iwl_priv *priv,
1291 return ret; 1288 return ret;
1292} 1289}
1293#endif 1290#endif
1291
1292int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1293{
1294 if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
1295 IWL_WARN(priv, "Not sending command - %s KILL\n",
1296 iwl_is_rfkill(priv) ? "RF" : "CT");
1297 return -EIO;
1298 }
1299
1300 /*
1301 * Synchronous commands from this op-mode must hold
1302 * the mutex, this ensures we don't try to send two
1303 * (or more) synchronous commands at a time.
1304 */
1305 if (cmd->flags & CMD_SYNC)
1306 lockdep_assert_held(&priv->mutex);
1307
1308 if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
1309 !(cmd->flags & CMD_ON_DEMAND)) {
1310 IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
1311 return -EIO;
1312 }
1313
1314 return iwl_trans_send_cmd(trans(priv), cmd);
1315}
1316
1317int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
1318 u32 flags, u16 len, const void *data)
1319{
1320 struct iwl_host_cmd cmd = {
1321 .id = id,
1322 .len = { len, },
1323 .data = { data, },
1324 .flags = flags,
1325 };
1326
1327 return iwl_dvm_send_cmd(priv, &cmd);
1328}