aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/ops.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 23:01:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 23:01:30 -0500
commitc5ce28df0e7c01a1de23c36ebdefcd803f2b6cbb (patch)
tree9830baf38832769e1cf621708889111bbe3c93df /drivers/net/wireless/iwlwifi/mvm/ops.c
parent29afc4e9a408f2304e09c6dd0dbcfbd2356d0faa (diff)
parent9399f0c51489ae8c16d6559b82a452fdc1895e91 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) More iov_iter conversion work from Al Viro. [ The "crypto: switch af_alg_make_sg() to iov_iter" commit was wrong, and this pull actually adds an extra commit on top of the branch I'm pulling to fix that up, so that the pre-merge state is ok. - Linus ] 2) Various optimizations to the ipv4 forwarding information base trie lookup implementation. From Alexander Duyck. 3) Remove sock_iocb altogether, from CHristoph Hellwig. 4) Allow congestion control algorithm selection via routing metrics. From Daniel Borkmann. 5) Make ipv4 uncached route list per-cpu, from Eric Dumazet. 6) Handle rfs hash collisions more gracefully, also from Eric Dumazet. 7) Add xmit_more support to r8169, e1000, and e1000e drivers. From Florian Westphal. 8) Transparent Ethernet Bridging support for GRO, from Jesse Gross. 9) Add BPF packet actions to packet scheduler, from Jiri Pirko. 10) Add support for uniqu flow IDs to openvswitch, from Joe Stringer. 11) New NetCP ethernet driver, from Muralidharan Karicheri and Wingman Kwok. 12) More sanely handle out-of-window dupacks, which can result in serious ACK storms. From Neal Cardwell. 13) Various rhashtable bug fixes and enhancements, from Herbert Xu, Patrick McHardy, and Thomas Graf. 14) Support xmit_more in be2net, from Sathya Perla. 15) Group Policy extensions for vxlan, from Thomas Graf. 16) Remove Checksum Offload support for vxlan, from Tom Herbert. 17) Like ipv4, support lockless transmit over ipv6 UDP sockets. From Vlad Yasevich. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1494+1 commits) crypto: fix af_alg_make_sg() conversion to iov_iter ipv4: Namespecify TCP PMTU mechanism i40e: Fix for stats init function call in Rx setup tcp: don't include Fast Open option in SYN-ACK on pure SYN-data openvswitch: Only set TUNNEL_VXLAN_OPT if VXLAN-GBP metadata is set ipv6: Make __ipv6_select_ident static ipv6: Fix fragment id assignment on LE arches. bridge: Fix inability to add non-vlan fdb entry net: Mellanox: Delete unnecessary checks before the function call "vunmap" cxgb4: Add support in cxgb4 to get expansion rom version via ethtool ethtool: rename reserved1 memeber in ethtool_drvinfo for expansion ROM version net: dsa: Remove redundant phy_attach() IB/mlx4: Reset flow support for IB kernel ULPs IB/mlx4: Always use the correct port for mirrored multicast attachments net/bonding: Fix potential bad memory access during bonding events tipc: remove tipc_snprintf tipc: nl compat add noop and remove legacy nl framework tipc: convert legacy nl stats show to nl compat tipc: convert legacy nl net id get to nl compat tipc: convert legacy nl net id set to nl compat ...
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/ops.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 97dfba50c682..2dffc3600ed3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -84,15 +84,8 @@
84#include "time-event.h" 84#include "time-event.h"
85#include "iwl-fw-error-dump.h" 85#include "iwl-fw-error-dump.h"
86 86
87/*
88 * module name, copyright, version, etc.
89 */
90#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" 87#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
91
92#define DRV_VERSION IWLWIFI_VERSION
93
94MODULE_DESCRIPTION(DRV_DESCRIPTION); 88MODULE_DESCRIPTION(DRV_DESCRIPTION);
95MODULE_VERSION(DRV_VERSION);
96MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 89MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
97MODULE_LICENSE("GPL"); 90MODULE_LICENSE("GPL");
98 91
@@ -100,6 +93,7 @@ static const struct iwl_op_mode_ops iwl_mvm_ops;
100 93
101struct iwl_mvm_mod_params iwlmvm_mod_params = { 94struct iwl_mvm_mod_params iwlmvm_mod_params = {
102 .power_scheme = IWL_POWER_SCHEME_BPS, 95 .power_scheme = IWL_POWER_SCHEME_BPS,
96 .tfd_q_hang_detect = true
103 /* rest of fields are 0 by default */ 97 /* rest of fields are 0 by default */
104}; 98};
105 99
@@ -109,6 +103,10 @@ MODULE_PARM_DESC(init_dbg,
109module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO); 103module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO);
110MODULE_PARM_DESC(power_scheme, 104MODULE_PARM_DESC(power_scheme,
111 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2"); 105 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2");
106module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect,
107 bool, S_IRUGO);
108MODULE_PARM_DESC(tfd_q_hang_detect,
109 "TFD queues hang detection (default: true");
112 110
113/* 111/*
114 * module init and exit functions 112 * module init and exit functions
@@ -146,13 +144,14 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
146 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 144 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
147 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; 145 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
148 u32 reg_val = 0; 146 u32 reg_val = 0;
147 u32 phy_config = iwl_mvm_get_phy_config(mvm);
149 148
150 radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >> 149 radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
151 FW_PHY_CFG_RADIO_TYPE_POS; 150 FW_PHY_CFG_RADIO_TYPE_POS;
152 radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >> 151 radio_cfg_step = (phy_config & FW_PHY_CFG_RADIO_STEP) >>
153 FW_PHY_CFG_RADIO_STEP_POS; 152 FW_PHY_CFG_RADIO_STEP_POS;
154 radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >> 153 radio_cfg_dash = (phy_config & FW_PHY_CFG_RADIO_DASH) >>
155 FW_PHY_CFG_RADIO_DASH_POS; 154 FW_PHY_CFG_RADIO_DASH_POS;
156 155
157 /* SKU control */ 156 /* SKU control */
158 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << 157 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
@@ -240,6 +239,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
240 239
241 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 240 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
242 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true), 241 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
242 RX_HANDLER(SCAN_ITERATION_COMPLETE,
243 iwl_mvm_rx_scan_offload_iter_complete_notif, false),
243 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 244 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
244 iwl_mvm_rx_scan_offload_complete_notif, true), 245 iwl_mvm_rx_scan_offload_complete_notif, true),
245 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results, 246 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
@@ -274,6 +275,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
274 CMD(MGMT_MCAST_KEY), 275 CMD(MGMT_MCAST_KEY),
275 CMD(TX_CMD), 276 CMD(TX_CMD),
276 CMD(TXPATH_FLUSH), 277 CMD(TXPATH_FLUSH),
278 CMD(SHARED_MEM_CFG),
277 CMD(MAC_CONTEXT_CMD), 279 CMD(MAC_CONTEXT_CMD),
278 CMD(TIME_EVENT_CMD), 280 CMD(TIME_EVENT_CMD),
279 CMD(TIME_EVENT_NOTIFICATION), 281 CMD(TIME_EVENT_NOTIFICATION),
@@ -476,17 +478,19 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
476 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) 478 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
477 trans_cfg.bc_table_dword = true; 479 trans_cfg.bc_table_dword = true;
478 480
479 if (!iwlwifi_mod_params.wd_disable)
480 trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
481 else
482 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
483
484 trans_cfg.command_names = iwl_mvm_cmd_strings; 481 trans_cfg.command_names = iwl_mvm_cmd_strings;
485 482
486 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; 483 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
487 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; 484 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
488 trans_cfg.scd_set_active = true; 485 trans_cfg.scd_set_active = true;
489 486
487 trans_cfg.sdio_adma_addr = fw->sdio_adma_addr;
488
489 /* Set a short watchdog for the command queue */
490 trans_cfg.cmd_q_wdg_timeout =
491 iwlmvm_mod_params.tfd_q_hang_detect ? IWL_DEF_WD_TIMEOUT :
492 IWL_WATCHDOG_DISABLED;
493
490 snprintf(mvm->hw->wiphy->fw_version, 494 snprintf(mvm->hw->wiphy->fw_version,
491 sizeof(mvm->hw->wiphy->fw_version), 495 sizeof(mvm->hw->wiphy->fw_version),
492 "%s", fw->fw_version); 496 "%s", fw->fw_version);
@@ -517,10 +521,15 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
517 min_backoff = calc_min_backoff(trans, cfg); 521 min_backoff = calc_min_backoff(trans, cfg);
518 iwl_mvm_tt_initialize(mvm, min_backoff); 522 iwl_mvm_tt_initialize(mvm, min_backoff);
519 /* set the nvm_file_name according to priority */ 523 /* set the nvm_file_name according to priority */
520 if (iwlwifi_mod_params.nvm_file) 524 if (iwlwifi_mod_params.nvm_file) {
521 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; 525 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
522 else 526 } else {
523 mvm->nvm_file_name = mvm->cfg->default_nvm_file; 527 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
528 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP))
529 mvm->nvm_file_name = mvm->cfg->default_nvm_file_8000A;
530 else
531 mvm->nvm_file_name = mvm->cfg->default_nvm_file;
532 }
524 533
525 if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, 534 if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name,
526 "not allowing power-up and not having nvm_file\n")) 535 "not allowing power-up and not having nvm_file\n"))
@@ -559,6 +568,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
559 if (!mvm->scan_cmd) 568 if (!mvm->scan_cmd)
560 goto out_free; 569 goto out_free;
561 570
571 /* Set EBS as successful as long as not stated otherwise by the FW. */
572 mvm->last_ebs_successful = true;
573
562 err = iwl_mvm_mac_setup_register(mvm); 574 err = iwl_mvm_mac_setup_register(mvm);
563 if (err) 575 if (err)
564 goto out_free; 576 goto out_free;
@@ -817,9 +829,20 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
817 struct iwl_mvm *mvm = 829 struct iwl_mvm *mvm =
818 container_of(work, struct iwl_mvm, fw_error_dump_wk); 830 container_of(work, struct iwl_mvm, fw_error_dump_wk);
819 831
832 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT))
833 return;
834
820 mutex_lock(&mvm->mutex); 835 mutex_lock(&mvm->mutex);
821 iwl_mvm_fw_error_dump(mvm); 836 iwl_mvm_fw_error_dump(mvm);
837
838 /* start recording again if the firmware is not crashed */
839 WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
840 mvm->fw->dbg_dest_tlv &&
841 iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
842
822 mutex_unlock(&mvm->mutex); 843 mutex_unlock(&mvm->mutex);
844
845 iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
823} 846}
824 847
825void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) 848void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
@@ -855,7 +878,10 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
855 * If WoWLAN fw asserted, don't restart either, mac80211 878 * If WoWLAN fw asserted, don't restart either, mac80211
856 * can't recover this since we're already half suspended. 879 * can't recover this since we're already half suspended.
857 */ 880 */
858 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 881 if (!mvm->restart_fw && fw_error) {
882 schedule_work(&mvm->fw_error_dump_wk);
883 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART,
884 &mvm->status)) {
859 struct iwl_mvm_reprobe *reprobe; 885 struct iwl_mvm_reprobe *reprobe;
860 886
861 IWL_ERR(mvm, 887 IWL_ERR(mvm,
@@ -879,16 +905,13 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
879 reprobe->dev = mvm->trans->dev; 905 reprobe->dev = mvm->trans->dev;
880 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); 906 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
881 schedule_work(&reprobe->work); 907 schedule_work(&reprobe->work);
882 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && 908 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR) {
883 (!fw_error || mvm->restart_fw)) {
884 /* don't let the transport/FW power down */ 909 /* don't let the transport/FW power down */
885 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 910 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
886 911
887 if (fw_error && mvm->restart_fw > 0) 912 if (fw_error && mvm->restart_fw > 0)
888 mvm->restart_fw--; 913 mvm->restart_fw--;
889 ieee80211_restart_hw(mvm->hw); 914 ieee80211_restart_hw(mvm->hw);
890 } else if (fw_error) {
891 schedule_work(&mvm->fw_error_dump_wk);
892 } 915 }
893} 916}
894 917
@@ -1031,7 +1054,8 @@ static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
1031out: 1054out:
1032 rcu_read_unlock(); 1055 rcu_read_unlock();
1033} 1056}
1034static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) 1057
1058int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1035{ 1059{
1036 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1060 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1037 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE; 1061 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
@@ -1047,6 +1071,7 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1047 }; 1071 };
1048 struct iwl_d3_manager_config d3_cfg_cmd = { 1072 struct iwl_d3_manager_config d3_cfg_cmd = {
1049 .min_sleep_time = cpu_to_le32(1000), 1073 .min_sleep_time = cpu_to_le32(1000),
1074 .wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR),
1050 }; 1075 };
1051 1076
1052 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n"); 1077 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
@@ -1146,7 +1171,7 @@ void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
1146 1171
1147 if (mvm->d0i3_offloading && qos_seq) { 1172 if (mvm->d0i3_offloading && qos_seq) {
1148 /* update qos seq numbers if offloading was enabled */ 1173 /* update qos seq numbers if offloading was enabled */
1149 mvm_ap_sta = (struct iwl_mvm_sta *)sta->drv_priv; 1174 mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta);
1150 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 1175 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1151 u16 seq = le16_to_cpu(qos_seq[i]); 1176 u16 seq = le16_to_cpu(qos_seq[i]);
1152 /* firmware stores last-used one, we store next one */ 1177 /* firmware stores last-used one, we store next one */
@@ -1245,7 +1270,7 @@ out:
1245 return ret; 1270 return ret;
1246} 1271}
1247 1272
1248static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) 1273int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
1249{ 1274{
1250 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1275 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1251 1276