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

rt2x00leds.c (5980B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
      4	<http://rt2x00.serialmonkey.com>
      5
      6 */
      7
      8/*
      9	Module: rt2x00lib
     10	Abstract: rt2x00 led specific routines.
     11 */
     12
     13#include <linux/kernel.h>
     14#include <linux/module.h>
     15
     16#include "rt2x00.h"
     17#include "rt2x00lib.h"
     18
     19void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi)
     20{
     21	struct rt2x00_led *led = &rt2x00dev->led_qual;
     22	unsigned int brightness;
     23
     24	if ((led->type != LED_TYPE_QUALITY) || !(led->flags & LED_REGISTERED))
     25		return;
     26
     27	/*
     28	 * Led handling requires a positive value for the rssi,
     29	 * to do that correctly we need to add the correction.
     30	 */
     31	rssi += rt2x00dev->rssi_offset;
     32
     33	/*
     34	 * Get the rssi level, this is used to convert the rssi
     35	 * to a LED value inside the range LED_OFF - LED_FULL.
     36	 */
     37	if (rssi <= 30)
     38		rssi = 0;
     39	else if (rssi <= 39)
     40		rssi = 1;
     41	else if (rssi <= 49)
     42		rssi = 2;
     43	else if (rssi <= 53)
     44		rssi = 3;
     45	else if (rssi <= 63)
     46		rssi = 4;
     47	else
     48		rssi = 5;
     49
     50	/*
     51	 * Note that we must _not_ send LED_OFF since the driver
     52	 * is going to calculate the value and might use it in a
     53	 * division.
     54	 */
     55	brightness = ((LED_FULL / 6) * rssi) + 1;
     56	if (brightness != led->led_dev.brightness) {
     57		led->led_dev.brightness_set(&led->led_dev, brightness);
     58		led->led_dev.brightness = brightness;
     59	}
     60}
     61
     62static void rt2x00led_led_simple(struct rt2x00_led *led, bool enabled)
     63{
     64	unsigned int brightness = enabled ? LED_FULL : LED_OFF;
     65
     66	if (!(led->flags & LED_REGISTERED))
     67		return;
     68
     69	led->led_dev.brightness_set(&led->led_dev, brightness);
     70	led->led_dev.brightness = brightness;
     71}
     72
     73void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled)
     74{
     75	if (rt2x00dev->led_qual.type == LED_TYPE_ACTIVITY)
     76		rt2x00led_led_simple(&rt2x00dev->led_qual, enabled);
     77}
     78
     79void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
     80{
     81	if (rt2x00dev->led_assoc.type == LED_TYPE_ASSOC)
     82		rt2x00led_led_simple(&rt2x00dev->led_assoc, enabled);
     83}
     84
     85void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
     86{
     87	if (rt2x00dev->led_radio.type == LED_TYPE_RADIO)
     88		rt2x00led_led_simple(&rt2x00dev->led_radio, enabled);
     89}
     90
     91static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
     92				   struct rt2x00_led *led,
     93				   const char *name)
     94{
     95	struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
     96	int retval;
     97
     98	led->led_dev.name = name;
     99	led->led_dev.brightness = LED_OFF;
    100
    101	retval = led_classdev_register(device, &led->led_dev);
    102	if (retval) {
    103		rt2x00_err(rt2x00dev, "Failed to register led handler\n");
    104		return retval;
    105	}
    106
    107	led->flags |= LED_REGISTERED;
    108
    109	return 0;
    110}
    111
    112void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
    113{
    114	char name[36];
    115	int retval;
    116	unsigned long on_period;
    117	unsigned long off_period;
    118	const char *phy_name = wiphy_name(rt2x00dev->hw->wiphy);
    119
    120	if (rt2x00dev->led_radio.flags & LED_INITIALIZED) {
    121		snprintf(name, sizeof(name), "%s-%s::radio",
    122			 rt2x00dev->ops->name, phy_name);
    123
    124		retval = rt2x00leds_register_led(rt2x00dev,
    125						 &rt2x00dev->led_radio,
    126						 name);
    127		if (retval)
    128			goto exit_fail;
    129	}
    130
    131	if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) {
    132		snprintf(name, sizeof(name), "%s-%s::assoc",
    133			 rt2x00dev->ops->name, phy_name);
    134
    135		retval = rt2x00leds_register_led(rt2x00dev,
    136						 &rt2x00dev->led_assoc,
    137						 name);
    138		if (retval)
    139			goto exit_fail;
    140	}
    141
    142	if (rt2x00dev->led_qual.flags & LED_INITIALIZED) {
    143		snprintf(name, sizeof(name), "%s-%s::quality",
    144			 rt2x00dev->ops->name, phy_name);
    145
    146		retval = rt2x00leds_register_led(rt2x00dev,
    147						 &rt2x00dev->led_qual,
    148						 name);
    149		if (retval)
    150			goto exit_fail;
    151	}
    152
    153	/*
    154	 * Initialize blink time to default value:
    155	 * On period: 70ms
    156	 * Off period: 30ms
    157	 */
    158	if (rt2x00dev->led_radio.led_dev.blink_set) {
    159		on_period = 70;
    160		off_period = 30;
    161		rt2x00dev->led_radio.led_dev.blink_set(
    162		    &rt2x00dev->led_radio.led_dev, &on_period, &off_period);
    163	}
    164
    165	return;
    166
    167exit_fail:
    168	rt2x00leds_unregister(rt2x00dev);
    169}
    170
    171static void rt2x00leds_unregister_led(struct rt2x00_led *led)
    172{
    173	led_classdev_unregister(&led->led_dev);
    174
    175	/*
    176	 * This might look weird, but when we are unregistering while
    177	 * suspended the led is already off, and since we haven't
    178	 * fully resumed yet, access to the device might not be
    179	 * possible yet.
    180	 */
    181	if (!(led->led_dev.flags & LED_SUSPENDED))
    182		led->led_dev.brightness_set(&led->led_dev, LED_OFF);
    183
    184	led->flags &= ~LED_REGISTERED;
    185}
    186
    187void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
    188{
    189	if (rt2x00dev->led_qual.flags & LED_REGISTERED)
    190		rt2x00leds_unregister_led(&rt2x00dev->led_qual);
    191	if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
    192		rt2x00leds_unregister_led(&rt2x00dev->led_assoc);
    193	if (rt2x00dev->led_radio.flags & LED_REGISTERED)
    194		rt2x00leds_unregister_led(&rt2x00dev->led_radio);
    195}
    196
    197static inline void rt2x00leds_suspend_led(struct rt2x00_led *led)
    198{
    199	led_classdev_suspend(&led->led_dev);
    200
    201	/* This shouldn't be needed, but just to be safe */
    202	led->led_dev.brightness_set(&led->led_dev, LED_OFF);
    203	led->led_dev.brightness = LED_OFF;
    204}
    205
    206void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
    207{
    208	if (rt2x00dev->led_qual.flags & LED_REGISTERED)
    209		rt2x00leds_suspend_led(&rt2x00dev->led_qual);
    210	if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
    211		rt2x00leds_suspend_led(&rt2x00dev->led_assoc);
    212	if (rt2x00dev->led_radio.flags & LED_REGISTERED)
    213		rt2x00leds_suspend_led(&rt2x00dev->led_radio);
    214}
    215
    216static inline void rt2x00leds_resume_led(struct rt2x00_led *led)
    217{
    218	led_classdev_resume(&led->led_dev);
    219
    220	/* Device might have enabled the LEDS during resume */
    221	led->led_dev.brightness_set(&led->led_dev, LED_OFF);
    222	led->led_dev.brightness = LED_OFF;
    223}
    224
    225void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
    226{
    227	if (rt2x00dev->led_radio.flags & LED_REGISTERED)
    228		rt2x00leds_resume_led(&rt2x00dev->led_radio);
    229	if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
    230		rt2x00leds_resume_led(&rt2x00dev->led_assoc);
    231	if (rt2x00dev->led_qual.flags & LED_REGISTERED)
    232		rt2x00leds_resume_led(&rt2x00dev->led_qual);
    233}