cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

led.c (2752B)


      1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
      2/*
      3 * Copyright (C) 2012-2014, 2018-2019 Intel Corporation
      4 * Copyright (C) 2017 Intel Deutschland GmbH
      5 */
      6#include <linux/leds.h>
      7#include "iwl-io.h"
      8#include "iwl-csr.h"
      9#include "mvm.h"
     10
     11static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)
     12{
     13	struct iwl_led_cmd led_cmd = {
     14		.status = cpu_to_le32(on),
     15	};
     16	struct iwl_host_cmd cmd = {
     17		.id = WIDE_ID(LONG_GROUP, LEDS_CMD),
     18		.len = { sizeof(led_cmd), },
     19		.data = { &led_cmd, },
     20		.flags = CMD_ASYNC,
     21	};
     22	int err;
     23
     24	if (!iwl_mvm_firmware_running(mvm))
     25		return;
     26
     27	err = iwl_mvm_send_cmd(mvm, &cmd);
     28
     29	if (err)
     30		IWL_WARN(mvm, "LED command failed: %d\n", err);
     31}
     32
     33static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)
     34{
     35	if (fw_has_capa(&mvm->fw->ucode_capa,
     36			IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT)) {
     37		iwl_mvm_send_led_fw_cmd(mvm, on);
     38		return;
     39	}
     40
     41	iwl_write32(mvm->trans, CSR_LED_REG,
     42		    on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);
     43}
     44
     45static void iwl_led_brightness_set(struct led_classdev *led_cdev,
     46				   enum led_brightness brightness)
     47{
     48	struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);
     49
     50	iwl_mvm_led_set(mvm, brightness > 0);
     51}
     52
     53int iwl_mvm_leds_init(struct iwl_mvm *mvm)
     54{
     55	int mode = iwlwifi_mod_params.led_mode;
     56	int ret;
     57
     58	switch (mode) {
     59	case IWL_LED_BLINK:
     60		IWL_ERR(mvm, "Blink led mode not supported, used default\n");
     61		fallthrough;
     62	case IWL_LED_DEFAULT:
     63	case IWL_LED_RF_STATE:
     64		mode = IWL_LED_RF_STATE;
     65		break;
     66	case IWL_LED_DISABLE:
     67		IWL_INFO(mvm, "Led disabled\n");
     68		return 0;
     69	default:
     70		return -EINVAL;
     71	}
     72
     73	mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
     74				   wiphy_name(mvm->hw->wiphy));
     75	if (!mvm->led.name)
     76		return -ENOMEM;
     77
     78	mvm->led.brightness_set = iwl_led_brightness_set;
     79	mvm->led.max_brightness = 1;
     80
     81	if (mode == IWL_LED_RF_STATE)
     82		mvm->led.default_trigger =
     83			ieee80211_get_radio_led_name(mvm->hw);
     84
     85	ret = led_classdev_register(mvm->trans->dev, &mvm->led);
     86	if (ret) {
     87		kfree(mvm->led.name);
     88		IWL_INFO(mvm, "Failed to enable led\n");
     89		return ret;
     90	}
     91
     92	mvm->init_status |= IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;
     93	return 0;
     94}
     95
     96void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
     97{
     98	if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
     99		return;
    100
    101	/*
    102	 * if we control through the register, we're doing it
    103	 * even when the firmware isn't up, so no need to sync
    104	 */
    105	if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
    106		return;
    107
    108	iwl_mvm_led_set(mvm, mvm->led.brightness > 0);
    109}
    110
    111void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
    112{
    113	if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
    114		return;
    115
    116	led_classdev_unregister(&mvm->led);
    117	kfree(mvm->led.name);
    118	mvm->init_status &= ~IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE;
    119}