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 (5319B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2009-2010  Realtek Corporation.*/
      3
      4#include "../wifi.h"
      5#include "../pci.h"
      6#include "reg.h"
      7#include "led.h"
      8
      9static void _rtl8821ae_init_led(struct ieee80211_hw *hw,
     10				struct rtl_led *pled,
     11				enum rtl_led_pin ledpin)
     12{
     13	pled->hw = hw;
     14	pled->ledpin = ledpin;
     15	pled->ledon = false;
     16}
     17
     18void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
     19{
     20	u8 ledcfg;
     21	struct rtl_priv *rtlpriv = rtl_priv(hw);
     22
     23	rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
     24		"LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
     25
     26	switch (pled->ledpin) {
     27	case LED_PIN_GPIO0:
     28		break;
     29	case LED_PIN_LED0:
     30		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
     31		ledcfg &= ~BIT(6);
     32		rtl_write_byte(rtlpriv,
     33			       REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
     34		break;
     35	case LED_PIN_LED1:
     36		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
     37		rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
     38		break;
     39	default:
     40		rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
     41			"switch case %#x not processed\n", pled->ledpin);
     42		break;
     43	}
     44	pled->ledon = true;
     45}
     46
     47void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
     48{
     49	u16	ledreg = REG_LEDCFG1;
     50	u8	ledcfg = 0;
     51	struct rtl_priv *rtlpriv = rtl_priv(hw);
     52
     53	switch (pled->ledpin) {
     54	case LED_PIN_LED0:
     55		ledreg = REG_LEDCFG1;
     56		break;
     57
     58	case LED_PIN_LED1:
     59		ledreg = REG_LEDCFG2;
     60		break;
     61
     62	case LED_PIN_GPIO0:
     63	default:
     64		break;
     65	}
     66
     67	rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
     68		"In SwLedOn, LedAddr:%X LEDPIN=%d\n",
     69		ledreg, pled->ledpin);
     70
     71	ledcfg =  rtl_read_byte(rtlpriv, ledreg);
     72	ledcfg |= BIT(5); /*Set 0x4c[21]*/
     73	ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
     74		/*Clear 0x4c[23:22] and 0x4c[19:16]*/
     75	rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/
     76	pled->ledon = true;
     77}
     78
     79void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
     80{
     81	struct rtl_priv *rtlpriv = rtl_priv(hw);
     82	u8 ledcfg;
     83
     84	rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
     85		"LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
     86
     87	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
     88
     89	switch (pled->ledpin) {
     90	case LED_PIN_GPIO0:
     91		break;
     92	case LED_PIN_LED0:
     93		ledcfg &= 0xf0;
     94		if (rtlpriv->ledctl.led_opendrain) {
     95			ledcfg &= 0x90; /* Set to software control. */
     96			rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
     97			ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
     98			ledcfg &= 0xFE;
     99			rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
    100		} else {
    101			ledcfg &= ~BIT(6);
    102			rtl_write_byte(rtlpriv, REG_LEDCFG2,
    103				       (ledcfg | BIT(3) | BIT(5)));
    104		}
    105		break;
    106	case LED_PIN_LED1:
    107		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
    108		ledcfg &= 0x10; /* Set to software control. */
    109		rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
    110		break;
    111	default:
    112		rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
    113			"switch case %#x not processed\n", pled->ledpin);
    114		break;
    115	}
    116	pled->ledon = false;
    117}
    118
    119void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
    120{
    121	u16 ledreg = REG_LEDCFG1;
    122	struct rtl_priv *rtlpriv = rtl_priv(hw);
    123
    124	switch (pled->ledpin) {
    125	case LED_PIN_LED0:
    126		ledreg = REG_LEDCFG1;
    127		break;
    128
    129	case LED_PIN_LED1:
    130		ledreg = REG_LEDCFG2;
    131		break;
    132
    133	case LED_PIN_GPIO0:
    134	default:
    135		break;
    136	}
    137
    138	rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
    139		"In SwLedOff,LedAddr:%X LEDPIN=%d\n",
    140		ledreg, pled->ledpin);
    141	/*Open-drain arrangement for controlling the LED*/
    142	if (rtlpriv->ledctl.led_opendrain) {
    143		u8 ledcfg = rtl_read_byte(rtlpriv, ledreg);
    144
    145		ledreg &= 0xd0; /* Set to software control.*/
    146		rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3)));
    147
    148		/*Open-drain arrangement*/
    149		ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
    150		ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/
    151		rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
    152	} else {
    153		rtl_write_byte(rtlpriv, ledreg, 0x28);
    154	}
    155
    156	pled->ledon = false;
    157}
    158
    159void rtl8821ae_init_sw_leds(struct ieee80211_hw *hw)
    160{
    161	struct rtl_priv *rtlpriv = rtl_priv(hw);
    162
    163	_rtl8821ae_init_led(hw, &rtlpriv->ledctl.sw_led0, LED_PIN_LED0);
    164	_rtl8821ae_init_led(hw, &rtlpriv->ledctl.sw_led1, LED_PIN_LED1);
    165}
    166
    167static void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw,
    168				      enum led_ctl_mode ledaction)
    169{
    170	struct rtl_priv *rtlpriv = rtl_priv(hw);
    171	struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
    172	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    173
    174	switch (ledaction) {
    175	case LED_CTL_POWER_ON:
    176	case LED_CTL_LINK:
    177	case LED_CTL_NO_LINK:
    178		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
    179			rtl8812ae_sw_led_on(hw, pled0);
    180		else
    181			rtl8821ae_sw_led_on(hw, pled0);
    182		break;
    183	case LED_CTL_POWER_OFF:
    184		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
    185			rtl8812ae_sw_led_off(hw, pled0);
    186		else
    187			rtl8821ae_sw_led_off(hw, pled0);
    188		break;
    189	default:
    190		break;
    191	}
    192}
    193
    194void rtl8821ae_led_control(struct ieee80211_hw *hw,
    195			   enum led_ctl_mode ledaction)
    196{
    197	struct rtl_priv *rtlpriv = rtl_priv(hw);
    198	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
    199
    200	if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
    201	    (ledaction == LED_CTL_TX ||
    202	     ledaction == LED_CTL_RX ||
    203	     ledaction == LED_CTL_SITE_SURVEY ||
    204	     ledaction == LED_CTL_LINK ||
    205	     ledaction == LED_CTL_NO_LINK ||
    206	     ledaction == LED_CTL_START_TO_LINK ||
    207	     ledaction == LED_CTL_POWER_ON)) {
    208		return;
    209	}
    210	rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n",
    211		ledaction);
    212	_rtl8821ae_sw_led_control(hw, ledaction);
    213}