linux bcm43455 wifi led状态灯调试

前言:
wifi 状态灯在嵌入式项目中很常见,同过状态灯可以判断wifi是否正常工作,不同的led status,可以表示数据发,收等。在nxp项目中,用到的是bcm43455 wifi (博通ap6255),需要增加一个led灯来表示wifi是否正常工作。有以下方案:

	方案一:bcm43xx ap硬件有先关的led-gpio,由硬件来完成
	方案二:无led-gpio,需要nxp主控引出一个gpio与wifi状态tx、rx、radio状态建立trigger
	方案三:wifi驱动力面增加phytx0、phyrx0 triger条件,注册对应的gpio

1. 方案分析
方案一:可以看到,wifi硬件tx、rx、radio无对应的gpio引出,硬件无法实现。
在这里插入图片描述
方案二:
通过以下配置,实现wifi_led,但是出现了问题,bcm-wifi用的cfg80211,在 err = wiphy_register(wiphy); 注册的时候,不会注册、生成phy0rx phy0tx triger 条件。如下,无 phy0rx phy0tx 的triger。在linux 内核调试了半天也没有看到wifi对应的triger条件,反而把网口的百兆、千兆triger打开了。当然使用网口的不行。方案二是一个大众的方案,标准,但是bcm43xx wifi驱动里不支持。所以实行方案三。

 #dts配置gpio1_1
        leds {
                compatible = "gpio-leds";
				status = "okay";
                wlan_led {
                        label = "green-wlan";
                        gpios = <&gpio1 1 0>; /* wlan */
                };
            };


#系统配置实现:
#/etc/config/system
config led wlan-led                                         ——配置项目的标签
        option name     wlan_led                            ——配置项目的名字
        option sysfs    green-wlan                            ——设备号
        option trigger    phy0rx phy0tx                     ——触发的设备类型
        option dev        wlan0_led                       ——对应的设备
        option mode     link tx rx                        ——要响应的设备活动事件
        option default   0                                
cat trigger 
none rc-feedback bluetooth-power kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock [mmc0] mmc1 mmc2 heartbeat cpu cpu0 cpu1 cpu2 cpu3 default-on 

方案三:在wifi驱动增加led, 如下所示:
在调试过程中,通过
ieee80211_create_tpt_led_trigger(hw,IEEE80211_TPT_LEDTRIG_FL_RADIO,tpt_blink,ARRAY_SIZE(tpt_blink));注册triger条件,返回的null值,这个问题由于项目关系,没有看到底。自然triger没有生效,wifi的状态灯,是wifi驱动正常probe 后,gpio1_1 点亮。如果没有wifi芯片或者probe失败,不会点亮。

2. 驱动调试
1->wifi驱动增加led


diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
index 9d99eb42d917..a19649a481be 100644
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -27,6 +27,15 @@ config BRCMFMAC
 	  interface support. If you choose to build a module, it'll be called
 	  brcmfmac.ko.
 
+config BCMXX_LED
+	tristate "Broadcom WLAN LED driver"
+	depends on BRCMFMAC
+	---help---
+	  This module adds support for wireless adapters based on Broadcom
+	  FullMAC chipsets. It has to work with at least one of the bus
+	  interface support. If you choose to build a module, it'll be called
+	  brcmfmac.ko.
+
 config BRCMFMAC_PROTO_BCDC
 	bool
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
index 1f5a9b948abf..b3b2696a86ba 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
@@ -54,3 +54,4 @@ brcmfmac-$(CONFIG_BRCM_TRACING) += \
 		tracepoint.o
 brcmfmac-$(CONFIG_OF) += \
 		of.o
+brcmfmac-$(CONFIG_BCMXX_LED) += led.o
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index d1cc95584128..ef479312e80d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -21,6 +21,9 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <net/cfg80211.h>
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+#include <net/mac80211.h>
+#endif
 #include <net/netlink.h>
 
 #include <brcmu_utils.h>
@@ -7215,6 +7218,16 @@ static void brcmf_free_wiphy(struct wiphy *wiphy)
 	wiphy_free(wiphy);
 }
 
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+int led_blink = 1;
+module_param_named(blink, led_blink, int, 0444);
+MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+
+static const struct ieee80211_tpt_blink tpt_blink[] = {
+	        { .throughput = 0 * 1024, .blink_time = 334 },
+};
+#endif
+
 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 						  struct device *busdev,
 						  bool p2pdev_forced)
@@ -7225,6 +7238,9 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 	struct cfg80211_ops *ops;
 	struct brcmf_cfg80211_vif *vif;
 	struct brcmf_if *ifp;
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+	struct ieee80211_hw *hw;
+#endif
 	s32 err = 0;
 	s32 io_type;
 	u16 *cap = NULL;
@@ -7302,6 +7318,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
 		*cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 	}
+
 	err = wiphy_register(wiphy);
 	if (err < 0) {
 		brcmf_err("Could not register wiphy device (%d)\n", err);
@@ -7384,6 +7401,16 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 #endif
 	}
 
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+	//printk("zyy bcmxx led..............");
+	hw = wiphy_to_ieee80211_hw(wiphy);
+	
+	cfg->led_dev.name = wiphy_name(wiphy); 
+	cfg->led_dev.default_trigger = ieee80211_create_tpt_led_trigger(hw,IEEE80211_TPT_LEDTRIG_FL_RADIO,tpt_blink,ARRAY_SIZE(tpt_blink));
+
+	if(hw) brcm_led_register(cfg);
+
+#endif
 	return cfg;
 
 detach:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 00faae6e50ab..74e2f62d1267 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -23,6 +23,11 @@
 #include "core.h"
 #include "fwil_types.h"
 #include "p2p.h"
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+#include "led.h"
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#endif
 
 #define BRCMF_SCAN_IE_LEN_MAX		2048
 
@@ -304,7 +309,13 @@ struct brcmf_cfg80211_wowl {
 	bool nd_data_completed;
 	bool nd_enabled;
 };
-
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+struct brcm_led {
+	char name[32];
+	unsigned gpio;
+	bool active_low;
+};
+#endif
 /**
  * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
  *
@@ -376,6 +387,14 @@ struct brcmf_cfg80211_info {
 	struct brcmf_pno_info *pno;
 	u8 ac_priority[MAX_8021D_PRIO];
 	u8 pm_state;
+
+#if IS_ENABLED(CONFIG_BCMXX_LED)
+	struct brcm_led radio_led;
+	struct led_classdev led_dev;
+	struct gpio_chip gpio;
+	struct work_struct led_work;
+	struct device_node *nd;
+#endif
 };
 
 /**
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/led.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/led.c
new file mode 100644
index 000000000000..e0f8c11a9c3f
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/led.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <net/mac80211.h>
+#include <linux/bcma/bcma_driver_chipcommon.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+
+#include "led.h"
+#include "cfg80211.h"
+
+
+void brcm_radio_led_ctrl(struct brcmf_cfg80211_info *wl, bool state)
+{
+	if (wl->radio_led.gpio == -1)
+		return;
+
+	if (wl->radio_led.active_low)
+		state = !state;
+
+	if (state)
+		gpio_set_value(wl->radio_led.gpio, 1);
+	else
+		gpio_set_value(wl->radio_led.gpio, 0);
+}
+
+
+
+void bcm_led_work(struct work_struct *work)
+{
+	struct brcmf_cfg80211_info *wl = container_of(work,struct brcmf_cfg80211_info,led_work);
+	brcm_radio_led_ctrl(wl, 0);
+}
+
+/* Callback from the LED subsystem. */
+static void brcm_led_brightness_set(struct led_classdev *led_dev,
+				   enum led_brightness brightness)
+{
+	struct brcmf_cfg80211_info *wl = container_of(led_dev,
+		struct brcmf_cfg80211_info, led_dev);
+	brcm_radio_led_ctrl(wl, 0);
+}
+
+void brcm_led_unregister(struct brcmf_cfg80211_info *wl)
+{
+	if (wl->led_dev.dev)
+		led_classdev_unregister(&wl->led_dev);
+	if (wl->radio_led.gpio != -1)
+		gpio_free(wl->radio_led.gpio);
+}
+
+int brcm_led_register(struct brcmf_cfg80211_info *wl)
+{
+	int i, err;
+	struct brcm_led *radio_led = &wl->radio_led;
+	//struct ssb_sprom *sprom = &wl->pub->bus_sprom;
+	unsigned gpio = -1;
+	bool active_low = false;
+	struct ieee80211_hw *hw;
+	char name[20 + 1];
+
+	//printk("wlan-gt810..................... \r\n");
+	wl->nd = of_find_node_by_path("/bcmxxled");
+	if(wl->nd == NULL)
+	{
+		printk("wlan-gt810 not find \r\n");
+		return -EINVAL;
+	}
+
+	radio_led->gpio = of_get_named_gpio(wl->nd,"wlan-gpio",0);
+	if(radio_led->gpio<0)
+	{
+		printk("can't get wlan-gpio\r\n");
+		return -EINVAL;
+	}
+	
+
+	//u8 *leds[] = { &sprom->gpio0,&sprom->gpio1,&sprom->gpio2,&sprom->gpio3 };
+
+	/* none by default */
+	//radio_led->gpio = -1;
+	radio_led->active_low = false;
+/*
+        for (i = 0; i < BRCMS_LED_NO; i++) {
+		u8 led = *leds[i];
+		if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
+			gpio = bcma_gpio->base + i;
+			if (led & BRCMS_LED_AL_MASK)
+				active_low = true;
+			break;
+		}
+	}
+*/
+	/* request and configure LED gpio */
+	err = gpio_request_one(radio_led->gpio,GPIOF_OUT_INIT_HIGH,"radio on");
+	if (err) {
+		return err;
+	}
+	err = gpio_direction_output(radio_led->gpio, 1);
+	if (err) {
+		return err;
+	}
+
+	hw = wiphy_to_ieee80211_hw(wl->wiphy);
+	snprintf(name, sizeof(name),"b43-%s::tx", wiphy_name(hw->wiphy));
+
+	//wl->led_dev.name = "wlan-led";//wl->radio_led.name;
+	printk("...........default :%s\r\n",ieee80211_get_radio_led_name(hw));
+	wl->led_dev.default_trigger = ieee80211_get_radio_led_name(hw);
+	wl->led_dev.brightness_set = brcm_led_brightness_set;
+	err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
+
+	if (err) {
+		return err;
+	}
+	
+	INIT_WORK(&wl->led_work, bcm_led_work);
+
+	//radio_led->gpio = 1;
+	radio_led->active_low = active_low;
+
+	return 0;
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/led.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/led.h
new file mode 100644
index 000000000000..f56d4333cffb
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/led.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _BRCM_LED_H_
+#define _BRCM_LED_H_
+#include "cfg80211.h"
+void brcm_radio_led_ctrl(struct brcmf_cfg80211_info *wl, bool state);
+void brcm_led_unregister(struct brcmf_cfg80211_info *wl);
+int brcm_led_register(struct brcmf_cfg80211_info *wl);
+#endif /* _BRCM_LED_H_ */

2->dts 配置

index cc1afbd..cd01ff5 100755
--- a/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8mm-evk.dts
@@ -32,6 +32,10 @@
                        clock-frequency = <16000000>;
                };
        };
+
+       bcmxxled {
+               wlan-gpio = <&gpio1 1 0>;
+       };
        
        leds {
                compatible = "gpio-leds";
@@ -44,6 +48,32 @@
                        gpios = <&gpio3 16 0>;
                        default-state = "on";
                };
+
+               user_led1 {
+                        label = "green-sys";
+                        gpios = <&gpio1 8 0>;  /* sys */
+                        linux,default-trigger = "heartbeat";
+                };
+
+               user_led2 {
+                        label = "green-error";
+                        gpios = <&gpio2 20 0>; /* error */
+                        linux,default-trigger = "mmc2";
+                };
+#if 0
+                wlan_led {
+                        label = "green-wlan";
+                        gpios = <&gpio1 1 0>; /* wlan */
+                        linux,default-trigger = "mmc0";
+                        default-state = "off";
+                };
+#endif
+                bt_led {
+                        label = "green-bt";
+                        gpios = <&gpio1 7 0>; /* bt */
+                        linux,default-trigger = "hci0-power";
+                        default-state = "off";
+                };
        };

3->kconfig /Makefile 配置

diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
index 9d99eb42d917..a19649a481be 100644
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -27,6 +27,15 @@ config BRCMFMAC
 	  interface support. If you choose to build a module, it'll be called
 	  brcmfmac.ko.
 
+config BCMXX_LED
+	tristate "Broadcom WLAN LED driver"
+	depends on BRCMFMAC
+	---help---
+	  This module adds support for wireless adapters based on Broadcom
+	  FullMAC chipsets. It has to work with at least one of the bus
+	  interface support. If you choose to build a module, it'll be called
+	  brcmfmac.ko.
+
 config BRCMFMAC_PROTO_BCDC
 	bool
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
index 1f5a9b948abf..b3b2696a86ba 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
@@ -54,3 +54,4 @@ brcmfmac-$(CONFIG_BRCM_TRACING) += \
 		tracepoint.o
 brcmfmac-$(CONFIG_OF) += \
 		of.o
+brcmfmac-$(CONFIG_BCMXX_LED) += led.o

4-> defconfig 配置

--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
 CONFIG_BRIDGE_LT9611=y
+CONFIG_BCMXX_LED=y

5->遗留问题

//创建trigger失败问题。

ieee80211_create_tpt_led_trigger(hw,IEEE80211_TPT_LEDTRIG_FL_RADIO,tpt_blink,ARRAY_SIZE(tpt_blink));
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值