]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/iwl-core.c
iwlwifi: change check triggering device restart after rfkill change
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / iwl-core.c
index 085e9cf1cac99f0be0613063adcfd782a05cccf2..82abb1f9087fefce7fed4797dc65246b0278e585 100644 (file)
@@ -1298,6 +1298,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
                    IEEE80211_HW_NOISE_DBM |
                    IEEE80211_HW_AMPDU_AGGREGATION |
+                   IEEE80211_HW_SPECTRUM_MGMT |
                    IEEE80211_HW_SUPPORTS_PS;
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_STATION) |
@@ -1308,9 +1309,6 @@ int iwl_setup_mac(struct iwl_priv *priv)
 
        /* Default value; 4 EDCA QOS priorities */
        hw->queues = 4;
-       /* queues to support 11n aggregation */
-       if (priv->cfg->sku & IWL_SKU_N)
-               hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
 
        hw->conf.beacon_int = 100;
        hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
@@ -1437,6 +1435,10 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 
        priv->tx_power_user_lmt = tx_power;
 
+       /* if nic is not up don't send command */
+       if (!iwl_is_ready_rf(priv))
+               return ret;
+
        if (force && priv->cfg->ops->lib->send_tx_power)
                ret = priv->cfg->ops->lib->send_tx_power(priv);
 
@@ -2052,7 +2054,7 @@ void iwl_bg_rf_kill(struct work_struct *work)
                          "HW and/or SW RF Kill no longer active, restarting "
                          "device\n");
                if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
-                   test_bit(STATUS_ALIVE, &priv->status))
+                   priv->is_open)
                        queue_work(priv->workqueue, &priv->restart);
        } else {
                /* make sure mac80211 stop sending Tx frame */
@@ -2110,3 +2112,86 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
 }
 EXPORT_SYMBOL(iwl_rx_reply_error);
 
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                          const struct ieee80211_tx_queue_params *params)
+{
+       struct iwl_priv *priv = hw->priv;
+       unsigned long flags;
+       int q;
+
+       IWL_DEBUG_MAC80211(priv, "enter\n");
+
+       if (!iwl_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+               return -EIO;
+       }
+
+       if (queue >= AC_NUM) {
+               IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
+               return 0;
+       }
+
+       q = AC_NUM - 1 - queue;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
+       priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
+       priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+       priv->qos_data.def_qos_parm.ac[q].edca_txop =
+                       cpu_to_le16((params->txop * 32));
+
+       priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+       priv->qos_data.qos_active = 1;
+
+       if (priv->iw_mode == NL80211_IFTYPE_AP)
+               iwl_activate_qos(priv, 1);
+       else if (priv->assoc_id && iwl_is_associated(priv))
+               iwl_activate_qos(priv, 0);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+       return 0;
+}
+EXPORT_SYMBOL(iwl_mac_conf_tx);
+#ifdef CONFIG_PM
+
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct iwl_priv *priv = pci_get_drvdata(pdev);
+
+       /*
+        * This function is called when system goes into suspend state
+        * mac80211 will call iwl_mac_stop() from the mac80211 suspend function
+        * first but since iwl_mac_stop() has no knowledge of who the caller is,
+        * it will not call apm_ops.stop() to stop the DMA operation.
+        * Calling apm_ops.stop here to make sure we stop the DMA.
+        */
+       priv->cfg->ops->lib->apm_ops.stop(priv);
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_pci_suspend);
+
+int iwl_pci_resume(struct pci_dev *pdev)
+{
+       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       int ret;
+
+       pci_set_power_state(pdev, PCI_D0);
+       ret = pci_enable_device(pdev);
+       if (ret)
+               return ret;
+       pci_restore_state(pdev);
+       iwl_enable_interrupts(priv);
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_pci_resume);
+
+#endif /* CONFIG_PM */