iwlwifi: mvm: configure TDLS peers to FW
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / mvm / ops.c
index 8c5bdf9360f9d45827e63e3995dec7bd0b8dd365..9f9c7672b95670e0eb304bdb88da97b207ff922d 100644 (file)
@@ -244,6 +244,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
                   iwl_mvm_rx_scan_offload_complete_notif, true),
        RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
                   false),
+       RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif,
+                  true),
 
        RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
        RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
@@ -254,6 +256,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
        RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
        RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
                   iwl_mvm_power_uapsd_misbehaving_ap_notif, false),
+       RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true),
+
 };
 #undef RX_HANDLER
 #define CMD(x) [x] = #x
@@ -344,6 +348,13 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
        CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
        CMD(ANTENNA_COUPLING_NOTIFICATION),
        CMD(SCD_QUEUE_CFG),
+       CMD(SCAN_CFG_CMD),
+       CMD(SCAN_REQ_UMAC),
+       CMD(SCAN_ABORT_UMAC),
+       CMD(SCAN_COMPLETE_UMAC),
+       CMD(TDLS_CHANNEL_SWITCH_CMD),
+       CMD(TDLS_CHANNEL_SWITCH_NOTIFICATION),
+       CMD(TDLS_CONFIG_CMD),
 };
 #undef CMD
 
@@ -427,6 +438,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        }
        mvm->sf_state = SF_UNINIT;
        mvm->low_latency_agg_frame_limit = 6;
+       mvm->cur_ucode = IWL_UCODE_INIT;
 
        mutex_init(&mvm->mutex);
        mutex_init(&mvm->d0i3_suspend_mutex);
@@ -534,16 +546,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
                }
        }
 
-       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
-               scan_size = sizeof(struct iwl_scan_req_unified_lmac) +
-                       sizeof(struct iwl_scan_channel_cfg_lmac) *
-                               mvm->fw->ucode_capa.n_scan_channels +
-                       sizeof(struct iwl_scan_probe_req);
-       else
-               scan_size = sizeof(struct iwl_scan_cmd) +
-                       mvm->fw->ucode_capa.max_probe_length +
-                       mvm->fw->ucode_capa.n_scan_channels *
-                               sizeof(struct iwl_scan_channel);
+       scan_size = iwl_mvm_scan_size(mvm);
 
        mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL);
        if (!mvm->scan_cmd)
@@ -597,8 +600,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
                kfree(mvm->nd_config->match_sets);
                kfree(mvm->nd_config);
                mvm->nd_config = NULL;
-               kfree(mvm->nd_ies);
-               mvm->nd_ies = NULL;
        }
 #endif
 
@@ -758,6 +759,7 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
 static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
 {
        struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+       bool calibrating = ACCESS_ONCE(mvm->calibrating);
 
        if (state)
                set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
@@ -766,7 +768,15 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
 
        wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
 
-       return state && mvm->cur_ucode != IWL_UCODE_INIT;
+       /* iwl_run_init_mvm_ucode is waiting for results, abort it */
+       if (calibrating)
+               iwl_abort_notification_waits(&mvm->notif_wait);
+
+       /*
+        * Stop the device if we run OPERATIONAL firmware or if we are in the
+        * middle of the calibrations.
+        */
+       return state && (mvm->cur_ucode != IWL_UCODE_INIT || calibrating);
 }
 
 static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
@@ -1041,6 +1051,19 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
        set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
        synchronize_net();
 
+       /*
+        * iwl_mvm_ref_sync takes a reference before checking the flag.
+        * so by checking there is no held reference we prevent a state
+        * in which iwl_mvm_ref_sync continues successfully while we
+        * configure the firmware to enter d0i3
+        */
+       if (iwl_mvm_ref_taken(mvm)) {
+               IWL_DEBUG_RPM(mvm->trans, "abort d0i3 due to taken ref\n");
+               clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
+               wake_up(&mvm->d0i3_exit_waitq);
+               return 1;
+       }
+
        ieee80211_iterate_active_interfaces_atomic(mvm->hw,
                                                   IEEE80211_IFACE_ITER_NORMAL,
                                                   iwl_mvm_enter_d0i3_iterator,
This page took 0.026028 seconds and 5 git commands to generate.