Search Linux Wireless

RE: [PATCH] wifi: rtw88: Add support for LED blinking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx> wrote:
> Register a struct led_classdev with the kernel's LED subsystem and
> create a throughput-based trigger for it. Then mac80211 makes the LED
> blink.
> 
> Tested with Tenda U12 (RTL8812AU), Tenda U9 (RTL8811CU), TP-Link Archer
> T2U Nano (RTL8811AU), TP-Link Archer T3U Plus (RTL8812BU), Edimax
> EW-7611UCB (RTL8821AU), LM842 (RTL8822CU).
> 
> Also tested with devices which don't have LEDs: the laptop's internal
> RTL8822CE and a no-name RTL8723DU.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> ---
>  drivers/net/wireless/realtek/rtw88/main.c     | 91 ++++++++++++++++++-
>  drivers/net/wireless/realtek/rtw88/main.h     |  9 ++
>  drivers/net/wireless/realtek/rtw88/reg.h      | 12 +++
>  drivers/net/wireless/realtek/rtw88/rtw8812a.c | 23 +++++
>  drivers/net/wireless/realtek/rtw88/rtw8821a.c | 32 +++++++
>  drivers/net/wireless/realtek/rtw88/rtw8821c.c | 25 +++++
>  drivers/net/wireless/realtek/rtw88/rtw8822b.c | 25 +++++
>  drivers/net/wireless/realtek/rtw88/rtw8822c.c | 25 +++++
>  8 files changed, 240 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> index 6993f93c8f06..387940839f8b 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -2221,6 +2221,86 @@ void rtw_core_deinit(struct rtw_dev *rtwdev)
>  }
>  EXPORT_SYMBOL(rtw_core_deinit);
> 
> +#ifdef CONFIG_LEDS_CLASS

Not prefer to have #ifdef in code. Please add a led.c and add an entry
  obj-$(CONFIG_LEDS_CLASS) += led.c 
to Makefile. 

Since you enclose whole functions, it looks not a big problem for this case.
But I still want to avoid using of #ifdef to prevent people imitate this wrongly. 

> +
> +static int rtw_led_set_blocking(struct led_classdev *led,
> +                               enum led_brightness brightness)
> +{
> +       struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
> +
> +       rtwdev->chip->ops->led_set(led, brightness);
> +
> +       return 0;
> +}
> +
> +static void rtw_led_init(struct rtw_dev *rtwdev)
> +{
> +       static const struct ieee80211_tpt_blink rtw_tpt_blink[] = {
> +               { .throughput = 0 * 1024, .blink_time = 334 },
> +               { .throughput = 1 * 1024, .blink_time = 260 },
> +               { .throughput = 5 * 1024, .blink_time = 220 },
> +               { .throughput = 10 * 1024, .blink_time = 190 },
> +               { .throughput = 20 * 1024, .blink_time = 170 },
> +               { .throughput = 50 * 1024, .blink_time = 150 },
> +               { .throughput = 70 * 1024, .blink_time = 130 },
> +               { .throughput = 100 * 1024, .blink_time = 110 },
> +               { .throughput = 200 * 1024, .blink_time = 80 },
> +               { .throughput = 300 * 1024, .blink_time = 50 },
> +       };
> +       struct led_classdev *led = &rtwdev->led_cdev;
> +       int err;
> +
> +       if (!rtwdev->chip->ops->led_set)
> +               return;
> +
> +       if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB)
> +               led->brightness_set_blocking = rtw_led_set_blocking;
> +       else
> +               led->brightness_set = rtwdev->chip->ops->led_set;
> +
> +       snprintf(rtwdev->led_name, sizeof(rtwdev->led_name),
> +                "rtw88-%s", dev_name(rtwdev->dev));
> +
> +       led->name = rtwdev->led_name;
> +       led->max_brightness = LED_ON;
> +       led->default_trigger =
> +               ieee80211_create_tpt_led_trigger(rtwdev->hw,
> +                                                IEEE80211_TPT_LEDTRIG_FL_RADIO,
> +                                                rtw_tpt_blink,
> +                                                ARRAY_SIZE(rtw_tpt_blink));
> +
> +       err = led_classdev_register(rtwdev->dev, led);
> +       if (err) {
> +               rtw_warn(rtwdev, "Failed to register the LED, error %d\n", err);
> +               return;
> +       }
> +
> +       rtwdev->led_registered = true;
> +}
> +
> +static void rtw_led_deinit(struct rtw_dev *rtwdev)
> +{
> +       struct led_classdev *led = &rtwdev->led_cdev;
> +
> +       if (!rtwdev->led_registered)
> +               return;
> +
> +       rtwdev->chip->ops->led_set(led, LED_OFF);
> +       led_classdev_unregister(led);
> +}
> +
> +#else
> +
> +static void rtw_led_init(struct rtw_dev *rtwdev)
> +{
> +}
> +
> +static void rtw_led_deinit(struct rtw_dev *rtwdev)
> +{
> +}
> +
> +#endif
> +

[...]

> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> index 21795286a1a0..e16ba8d8a792 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
> @@ -868,6 +868,26 @@ static void rtw8812a_pwr_track(struct rtw_dev *rtwdev)
>         dm_info->pwr_trk_triggered = false;
>  }
> 
> +#ifdef CONFIG_LEDS_CLASS
> +
> +static void rtw8812a_led_set(struct led_classdev *led,
> +                            enum led_brightness brightness)
> +{
> +       struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
> +       u8 ledcfg;
> +
> +       ledcfg = rtw_read8(rtwdev, REG_LED_CFG);
> +       ledcfg &= BIT(6) | BIT(4);
> +       ledcfg |= BIT(5);
> +
> +       if (brightness == LED_OFF)
> +               ledcfg |= BIT(3);
> +
> +       rtw_write8(rtwdev, REG_LED_CFG, ledcfg);
> +}
> +
> +#endif
> +
>  static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
>                                           struct rtw_tx_pkt_info *pkt_info,
>                                           u8 *txdesc)
> @@ -916,6 +936,9 @@ static const struct rtw_chip_ops rtw8812a_ops = {
>         .config_bfee            = NULL,
>         .set_gid_table          = NULL,
>         .cfg_csi_rate           = NULL,
> +#ifdef CONFIG_LEDS_CLASS
> +       .led_set                = rtw8812a_led_set,
> +#endif

Just build the code without checking CONFIG_LEDS_CLASS.
It will waste some space, but acceptable. 

            before  after   delta
rtw8812a.o  15619   15771   152
rtw8821a.o  12922   13186   264
rtw8821c.o  18890   19034   144
rtw8822b.o  24860   25004   144
rtw8822c.o  65963   66155   192

Also I'm thinking if we can move rtw8812a_led_set to led.c as well. However,
it looks very different from chip to chip. 






[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux