summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/commands.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/led.h71
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/led.c56
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c1
7 files changed, 130 insertions, 10 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index c7b8cffdf281..0eb35b119ae9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -288,6 +288,11 @@ enum iwl_legacy_cmds {
NON_QOS_TX_COUNTER_CMD = 0x2d,
/**
+ * @LEDS_CMD: command is &struct iwl_led_cmd
+ */
+ LEDS_CMD = 0x48,
+
+ /**
* @LQ_CMD: using &struct iwl_lq_cmd
*/
LQ_CMD = 0x4e,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/led.h b/drivers/net/wireless/intel/iwlwifi/fw/api/led.h
new file mode 100644
index 000000000000..b30c9d229d6e
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/led.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2017 Intel Deutschland GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <linuxwifi@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 Intel Deutschland GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#ifndef __iwl_fw_api_led_h__
+#define __iwl_fw_api_led_h__
+
+/**
+ * struct iwl_led_cmd - LED switching command
+ *
+ * @status: LED status (on/off)
+ */
+struct iwl_led_cmd {
+ __le32 status;
+} __packed; /* LEDS_CMD_API_S_VER_2 */
+
+#endif /* __iwl_fw_api_led_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 69336f38ac58..e8e74dd558f7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -83,6 +83,7 @@
#include "fw/api/commands.h"
#include "fw/api/d3.h"
#include "fw/api/filter.h"
+#include "fw/api/led.h"
#include "fw/api/mac.h"
#include "fw/api/nvm-reg.h"
#include "fw/api/phy-ctxt.h"
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 875cf3a60adb..ec018d94a9dd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1217,6 +1217,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (ret)
goto error;
+ iwl_mvm_leds_sync(mvm);
+
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
return 0;
error:
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c
index 95ef37df292f..005e2e7278a5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c
@@ -6,6 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2017 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
* BSD LICENSE
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,26 +68,45 @@
#include "iwl-csr.h"
#include "mvm.h"
-/* Set led register on */
-static void iwl_mvm_led_enable(struct iwl_mvm *mvm)
+static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)
{
- iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON);
+ struct iwl_led_cmd led_cmd = {
+ .status = cpu_to_le32(on),
+ };
+ struct iwl_host_cmd cmd = {
+ .id = WIDE_ID(LONG_GROUP, LEDS_CMD),
+ .len = { sizeof(led_cmd), },
+ .data = { &led_cmd, },
+ .flags = CMD_ASYNC,
+ };
+ int err;
+
+ if (!iwl_mvm_firmware_running(mvm))
+ return;
+
+ err = iwl_mvm_send_cmd(mvm, &cmd);
+
+ if (err)
+ IWL_WARN(mvm, "LED command failed: %d\n", err);
}
-/* Set led register off */
-static void iwl_mvm_led_disable(struct iwl_mvm *mvm)
+static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)
{
- iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_OFF);
+ if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
+ iwl_mvm_send_led_fw_cmd(mvm, on);
+ return;
+ }
+
+ iwl_write32(mvm->trans, CSR_LED_REG,
+ on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);
}
static void iwl_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);
- if (brightness > 0)
- iwl_mvm_led_enable(mvm);
- else
- iwl_mvm_led_disable(mvm);
+
+ iwl_mvm_led_set(mvm, brightness > 0);
}
int iwl_mvm_leds_init(struct iwl_mvm *mvm)
@@ -127,6 +148,21 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
return 0;
}
+void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
+{
+ if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
+ return;
+
+ /*
+ * if we control through the register, we're doing it
+ * even when the firmware isn't up, so no need to sync
+ */
+ if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000)
+ return;
+
+ iwl_mvm_led_set(mvm, mvm->led.brightness > 0);
+}
+
void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
{
if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index c274fe177dfa..8b6238e1c7ea 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1566,6 +1566,7 @@ void iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
#ifdef CONFIG_IWLWIFI_LEDS
int iwl_mvm_leds_init(struct iwl_mvm *mvm);
void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
+void iwl_mvm_leds_sync(struct iwl_mvm *mvm);
#else
static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
{
@@ -1574,6 +1575,9 @@ static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
static inline void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
{
}
+static inline void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
+{
+}
#endif
/* D3 (WoWLAN, NetDetect) */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 9c9c1b4b6d48..29a21a11c7f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -350,6 +350,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(BINDING_CONTEXT_CMD),
HCMD_NAME(TIME_QUOTA_CMD),
HCMD_NAME(NON_QOS_TX_COUNTER_CMD),
+ HCMD_NAME(LEDS_CMD),
HCMD_NAME(LQ_CMD),
HCMD_NAME(FW_PAGING_BLOCK_CMD),
HCMD_NAME(SCAN_OFFLOAD_REQUEST_CMD),