aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig5
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/led.c126
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/led.h36
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h4
6 files changed, 177 insertions, 2 deletions
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index 1d92d874ebb6..747e9317dabd 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -12,8 +12,9 @@ config BRCMSMAC
12 select CORDIC 12 select CORDIC
13 ---help--- 13 ---help---
14 This module adds support for PCIe wireless adapters based on Broadcom 14 This module adds support for PCIe wireless adapters based on Broadcom
15 IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll 15 IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will
16 be called brcmsmac.ko. 16 be available if you select BCMA_DRIVER_GPIO. If you choose to build a
17 module, the driver will be called brcmsmac.ko.
17 18
18config BRCMFMAC 19config BRCMFMAC
19 tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" 20 tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index d3d4151c3eda..cba19d839b77 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -43,6 +43,10 @@ BRCMSMAC_OFILES := \
43 brcms_trace_events.o \ 43 brcms_trace_events.o \
44 debug.o 44 debug.o
45 45
46ifdef CONFIG_BCMA_DRIVER_GPIO
47BRCMSMAC_OFILES += led.o
48endif
49
46MODULEPFX := brcmsmac 50MODULEPFX := brcmsmac
47 51
48obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o 52obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/led.c b/drivers/net/wireless/brcm80211/brcmsmac/led.c
new file mode 100644
index 000000000000..74b17cecb189
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/led.c
@@ -0,0 +1,126 @@
1#include <net/mac80211.h>
2#include <linux/bcma/bcma_driver_chipcommon.h>
3#include <linux/gpio.h>
4
5#include "mac80211_if.h"
6#include "pub.h"
7#include "main.h"
8#include "led.h"
9
10 /* number of leds */
11#define BRCMS_LED_NO 4
12 /* behavior mask */
13#define BRCMS_LED_BEH_MASK 0x7f
14 /* activelow (polarity) bit */
15#define BRCMS_LED_AL_MASK 0x80
16 /* radio enabled */
17#define BRCMS_LED_RADIO 3
18
19static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
20{
21 if (wl->radio_led.gpio == -1)
22 return;
23
24 if (wl->radio_led.active_low)
25 state = !state;
26
27 if (state)
28 gpio_set_value(wl->radio_led.gpio, 1);
29 else
30 gpio_set_value(wl->radio_led.gpio, 0);
31}
32
33
34/* Callback from the LED subsystem. */
35static void brcms_led_brightness_set(struct led_classdev *led_dev,
36 enum led_brightness brightness)
37{
38 struct brcms_info *wl = container_of(led_dev,
39 struct brcms_info, led_dev);
40 brcms_radio_led_ctrl(wl, brightness);
41}
42
43void brcms_led_unregister(struct brcms_info *wl)
44{
45 if (wl->led_dev.dev)
46 led_classdev_unregister(&wl->led_dev);
47 if (wl->radio_led.gpio != -1)
48 gpio_free(wl->radio_led.gpio);
49}
50
51int brcms_led_register(struct brcms_info *wl)
52{
53 int i, err;
54 struct brcms_led *radio_led = &wl->radio_led;
55 /* get CC core */
56 struct bcma_drv_cc *cc_drv = &wl->wlc->hw->d11core->bus->drv_cc;
57 struct gpio_chip *bcma_gpio = &cc_drv->gpio;
58 struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;
59 u8 *leds[] = { &sprom->gpio0,
60 &sprom->gpio1,
61 &sprom->gpio2,
62 &sprom->gpio3 };
63 unsigned gpio = -1;
64 bool active_low = false;
65
66 /* none by default */
67 radio_led->gpio = -1;
68 radio_led->active_low = false;
69
70 if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
71 return -ENODEV;
72
73 /* find radio enabled LED */
74 for (i = 0; i < BRCMS_LED_NO; i++) {
75 u8 led = *leds[i];
76 if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
77 gpio = bcma_gpio->base + i;
78 if (led & BRCMS_LED_AL_MASK)
79 active_low = true;
80 break;
81 }
82 }
83
84 if (gpio == -1 || !gpio_is_valid(gpio))
85 return -ENODEV;
86
87 /* request and configure LED gpio */
88 err = gpio_request_one(gpio,
89 active_low ? GPIOF_OUT_INIT_HIGH
90 : GPIOF_OUT_INIT_LOW,
91 "radio on");
92 if (err) {
93 wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
94 gpio, err);
95 return err;
96 }
97 err = gpio_direction_output(gpio, 1);
98 if (err) {
99 wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
100 gpio, err);
101 return err;
102 }
103
104 snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),
105 "brcmsmac-%s:radio", wiphy_name(wl->wiphy));
106
107 wl->led_dev.name = wl->radio_led.name;
108 wl->led_dev.default_trigger =
109 ieee80211_get_radio_led_name(wl->pub->ieee_hw);
110 wl->led_dev.brightness_set = brcms_led_brightness_set;
111 err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
112
113 if (err) {
114 wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",
115 wl->radio_led.name, err);
116 return err;
117 }
118
119 wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
120 wl->radio_led.name,
121 gpio);
122 radio_led->gpio = gpio;
123 radio_led->active_low = active_low;
124
125 return 0;
126}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/led.h b/drivers/net/wireless/brcm80211/brcmsmac/led.h
new file mode 100644
index 000000000000..17a0b1f5dbcf
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/led.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_LED_H_
18#define _BRCM_LED_H_
19struct brcms_led {
20 char name[32];
21 unsigned gpio;
22 bool active_low;
23};
24
25#ifdef CONFIG_BCMA_DRIVER_GPIO
26void brcms_led_unregister(struct brcms_info *wl);
27int brcms_led_register(struct brcms_info *wl);
28#else
29static inline void brcms_led_unregister(struct brcms_info *wl) {};
30static inline int brcms_led_register(struct brcms_info *wl)
31{
32 return -ENOTSUPP;
33};
34#endif
35
36#endif /* _BRCM_LED_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index c6451c61407a..c70cf7b654cd 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -34,6 +34,7 @@
34#include "mac80211_if.h" 34#include "mac80211_if.h"
35#include "main.h" 35#include "main.h"
36#include "debug.h" 36#include "debug.h"
37#include "led.h"
37 38
38#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ 39#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
39#define BRCMS_FLUSH_TIMEOUT 500 /* msec */ 40#define BRCMS_FLUSH_TIMEOUT 500 /* msec */
@@ -904,6 +905,7 @@ static void brcms_remove(struct bcma_device *pdev)
904 struct brcms_info *wl = hw->priv; 905 struct brcms_info *wl = hw->priv;
905 906
906 if (wl->wlc) { 907 if (wl->wlc) {
908 brcms_led_unregister(wl);
907 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); 909 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
908 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); 910 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
909 ieee80211_unregister_hw(hw); 911 ieee80211_unregister_hw(hw);
@@ -1151,6 +1153,8 @@ static int brcms_bcma_probe(struct bcma_device *pdev)
1151 pr_err("%s: brcms_attach failed!\n", __func__); 1153 pr_err("%s: brcms_attach failed!\n", __func__);
1152 return -ENODEV; 1154 return -ENODEV;
1153 } 1155 }
1156 brcms_led_register(wl);
1157
1154 return 0; 1158 return 0;
1155} 1159}
1156 1160
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 947ccacf43e6..4090032e81a2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -20,8 +20,10 @@
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/leds.h>
23 24
24#include "ucode_loader.h" 25#include "ucode_loader.h"
26#include "led.h"
25/* 27/*
26 * Starting index for 5G rates in the 28 * Starting index for 5G rates in the
27 * legacy rate table. 29 * legacy rate table.
@@ -81,6 +83,8 @@ struct brcms_info {
81 struct wiphy *wiphy; 83 struct wiphy *wiphy;
82 struct brcms_ucode ucode; 84 struct brcms_ucode ucode;
83 bool mute_tx; 85 bool mute_tx;
86 struct brcms_led radio_led;
87 struct led_classdev led_dev;
84}; 88};
85 89
86/* misc callbacks */ 90/* misc callbacks */