diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 101 |
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 | ||
89 | void iwlagn_temperature(struct iwl_priv *priv) | 88 | void 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 | ||
246 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | 247 | void 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)); |
256 | done: | 257 | done: |
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); |
595 | out: | 596 | out: |
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 | ||
707 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | 708 | int 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 | ||
1083 | int iwlagn_send_patterns(struct iwl_priv *priv, | 1081 | int 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 | ||
1125 | int iwlagn_suspend(struct iwl_priv *priv, | 1123 | int 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 | |||
1292 | int 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 | |||
1317 | int 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 | } | ||