diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2007-10-10 23:44:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:03:27 -0500 |
commit | 93bb7f3a7bb5c95da10242d9763994a466c90b1d (patch) | |
tree | 8c248e88ea2be5ae791003050bda848b4a72dd36 | |
parent | ba48f7bb8062982ec916868cc8c90360aad82e53 (diff) |
b43legacy: RF-kill support
This adds full support for the RFKILL button and the RFKILL LED trigger.
This is a port to b43legacy of a patch by Michael Buesch <mb@bu3sch.de>
for b43.
Signed-off-by: Larry Finger<Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/b43legacy/Kconfig | 8 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/b43legacy.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/leds.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/radio.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/radio.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/rfkill.c | 158 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/rfkill.h | 51 |
9 files changed, 250 insertions, 15 deletions
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 1bf777578e5f..68e05f06b33f 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig | |||
@@ -37,7 +37,13 @@ config B43LEGACY_PCICORE_AUTOSELECT | |||
37 | # LED support | 37 | # LED support |
38 | config B43LEGACY_LEDS | 38 | config B43LEGACY_LEDS |
39 | bool | 39 | bool |
40 | depends on MAC80211_LEDS | 40 | depends on B43LEGACY && MAC80211_LEDS |
41 | default y | ||
42 | |||
43 | # RFKILL support | ||
44 | config B43LEGACY_RFKILL | ||
45 | bool | ||
46 | depends on B43LEGACY && RFKILL | ||
41 | default y | 47 | default y |
42 | 48 | ||
43 | config B43LEGACY_DEBUG | 49 | config B43LEGACY_DEBUG |
diff --git a/drivers/net/wireless/b43legacy/Makefile b/drivers/net/wireless/b43legacy/Makefile index abaa404bb148..80cdb73bd140 100644 --- a/drivers/net/wireless/b43legacy/Makefile +++ b/drivers/net/wireless/b43legacy/Makefile | |||
@@ -5,6 +5,8 @@ b43legacy-y += phy.o | |||
5 | b43legacy-y += radio.o | 5 | b43legacy-y += radio.o |
6 | b43legacy-y += sysfs.o | 6 | b43legacy-y += sysfs.o |
7 | b43legacy-y += xmit.o | 7 | b43legacy-y += xmit.o |
8 | # b43 RFKILL button support | ||
9 | b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o | ||
8 | # b43legacy LED support | 10 | # b43legacy LED support |
9 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o | 11 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o |
10 | # b43legacy debugging | 12 | # b43legacy debugging |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 41243ba821ac..fe2af06f5599 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "debugfs.h" | 20 | #include "debugfs.h" |
21 | #include "leds.h" | 21 | #include "leds.h" |
22 | #include "rfkill.h" | ||
22 | #include "phy.h" | 23 | #include "phy.h" |
23 | 24 | ||
24 | 25 | ||
@@ -592,6 +593,9 @@ struct b43legacy_wl { | |||
592 | u8 rng_initialized; | 593 | u8 rng_initialized; |
593 | char rng_name[30 + 1]; | 594 | char rng_name[30 + 1]; |
594 | 595 | ||
596 | /* The RF-kill button */ | ||
597 | struct b43legacy_rfkill rfkill; | ||
598 | |||
595 | /* List of all wireless devices on this chip */ | 599 | /* List of all wireless devices on this chip */ |
596 | struct list_head devlist; | 600 | struct list_head devlist; |
597 | u8 nr_devs; | 601 | u8 nr_devs; |
@@ -667,6 +671,7 @@ struct b43legacy_wldev { | |||
667 | struct b43legacy_led led_tx; | 671 | struct b43legacy_led led_tx; |
668 | struct b43legacy_led led_rx; | 672 | struct b43legacy_led led_rx; |
669 | struct b43legacy_led led_assoc; | 673 | struct b43legacy_led led_assoc; |
674 | struct b43legacy_led led_radio; | ||
670 | 675 | ||
671 | /* Reason code of the last interrupt. */ | 676 | /* Reason code of the last interrupt. */ |
672 | u32 irq_reason; | 677 | u32 irq_reason; |
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index 1e30919582c5..9ef284fda80e 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c | |||
@@ -156,12 +156,16 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, | |||
156 | ieee80211_get_rx_led_name(hw), | 156 | ieee80211_get_rx_led_name(hw), |
157 | led_index, activelow); | 157 | led_index, activelow); |
158 | break; | 158 | break; |
159 | /*FIXME: We need another trigger for the "radio-on" LEDs below. | ||
160 | * Wiggle that somehow into the rfkill subsystem. */ | ||
161 | case B43legacy_LED_RADIO_ALL: | 159 | case B43legacy_LED_RADIO_ALL: |
162 | case B43legacy_LED_RADIO_A: | 160 | case B43legacy_LED_RADIO_A: |
163 | case B43legacy_LED_RADIO_B: | 161 | case B43legacy_LED_RADIO_B: |
164 | case B43legacy_LED_MODE_BG: | 162 | case B43legacy_LED_MODE_BG: |
163 | snprintf(name, sizeof(name), | ||
164 | "b43legacy-%s:radio", wiphy_name(hw->wiphy)); | ||
165 | b43legacy_register_led(dev, &dev->led_radio, name, | ||
166 | b43legacy_rfkill_led_name(dev), | ||
167 | led_index, activelow); | ||
168 | break; | ||
165 | case B43legacy_LED_WEIRD: | 169 | case B43legacy_LED_WEIRD: |
166 | case B43legacy_LED_ASSOC: | 170 | case B43legacy_LED_ASSOC: |
167 | snprintf(name, sizeof(name), | 171 | snprintf(name, sizeof(name), |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 43edd08297a4..04bc3f6c5e63 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1993,7 +1993,7 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
1993 | /* This is the opposite of b43legacy_chip_init() */ | 1993 | /* This is the opposite of b43legacy_chip_init() */ |
1994 | static void b43legacy_chip_exit(struct b43legacy_wldev *dev) | 1994 | static void b43legacy_chip_exit(struct b43legacy_wldev *dev) |
1995 | { | 1995 | { |
1996 | b43legacy_radio_turn_off(dev); | 1996 | b43legacy_radio_turn_off(dev, 1); |
1997 | b43legacy_leds_exit(dev); | 1997 | b43legacy_leds_exit(dev); |
1998 | b43legacy_gpio_cleanup(dev); | 1998 | b43legacy_gpio_cleanup(dev); |
1999 | /* firmware is released later */ | 1999 | /* firmware is released later */ |
@@ -2106,7 +2106,7 @@ out: | |||
2106 | return err; | 2106 | return err; |
2107 | 2107 | ||
2108 | err_radio_off: | 2108 | err_radio_off: |
2109 | b43legacy_radio_turn_off(dev); | 2109 | b43legacy_radio_turn_off(dev, 1); |
2110 | err_leds_exit: | 2110 | err_leds_exit: |
2111 | b43legacy_leds_exit(dev); | 2111 | b43legacy_leds_exit(dev); |
2112 | b43legacy_gpio_cleanup(dev); | 2112 | b43legacy_gpio_cleanup(dev); |
@@ -2154,8 +2154,7 @@ static void b43legacy_periodic_every1sec(struct b43legacy_wldev *dev) | |||
2154 | radio_hw_enable = b43legacy_is_hw_radio_enabled(dev); | 2154 | radio_hw_enable = b43legacy_is_hw_radio_enabled(dev); |
2155 | if (unlikely(dev->radio_hw_enable != radio_hw_enable)) { | 2155 | if (unlikely(dev->radio_hw_enable != radio_hw_enable)) { |
2156 | dev->radio_hw_enable = radio_hw_enable; | 2156 | dev->radio_hw_enable = radio_hw_enable; |
2157 | b43legacyinfo(dev->wl, "Radio hardware status changed to %s\n", | 2157 | b43legacy_rfkill_toggled(dev, radio_hw_enable); |
2158 | (radio_hw_enable) ? "enabled" : "disabled"); | ||
2159 | } | 2158 | } |
2160 | } | 2159 | } |
2161 | 2160 | ||
@@ -2647,7 +2646,7 @@ static int b43legacy_dev_config(struct ieee80211_hw *hw, | |||
2647 | " physically off. Press the" | 2646 | " physically off. Press the" |
2648 | " button to turn it on.\n"); | 2647 | " button to turn it on.\n"); |
2649 | } else { | 2648 | } else { |
2650 | b43legacy_radio_turn_off(dev); | 2649 | b43legacy_radio_turn_off(dev, 0); |
2651 | b43legacyinfo(dev->wl, "Radio turned off by" | 2650 | b43legacyinfo(dev->wl, "Radio turned off by" |
2652 | " software\n"); | 2651 | " software\n"); |
2653 | } | 2652 | } |
@@ -3034,11 +3033,15 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
3034 | cancel_work_sync(&dev->restart_work); | 3033 | cancel_work_sync(&dev->restart_work); |
3035 | mutex_lock(&wl->mutex); | 3034 | mutex_lock(&wl->mutex); |
3036 | 3035 | ||
3036 | mutex_unlock(&dev->wl->mutex); | ||
3037 | b43legacy_rfkill_exit(dev); | ||
3038 | mutex_lock(&dev->wl->mutex); | ||
3039 | |||
3037 | b43legacy_rng_exit(dev->wl); | 3040 | b43legacy_rng_exit(dev->wl); |
3038 | b43legacy_pio_free(dev); | 3041 | b43legacy_pio_free(dev); |
3039 | b43legacy_dma_free(dev); | 3042 | b43legacy_dma_free(dev); |
3040 | b43legacy_chip_exit(dev); | 3043 | b43legacy_chip_exit(dev); |
3041 | b43legacy_radio_turn_off(dev); | 3044 | b43legacy_radio_turn_off(dev, 1); |
3042 | b43legacy_switch_analog(dev, 0); | 3045 | b43legacy_switch_analog(dev, 0); |
3043 | if (phy->dyn_tssi_tbl) | 3046 | if (phy->dyn_tssi_tbl) |
3044 | kfree(phy->tssi2dbm); | 3047 | kfree(phy->tssi2dbm); |
@@ -3206,6 +3209,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) | |||
3206 | memset(wl->mac_addr, 0, ETH_ALEN); | 3209 | memset(wl->mac_addr, 0, ETH_ALEN); |
3207 | b43legacy_upload_card_macaddress(dev); | 3210 | b43legacy_upload_card_macaddress(dev); |
3208 | b43legacy_security_init(dev); | 3211 | b43legacy_security_init(dev); |
3212 | b43legacy_rfkill_init(dev); | ||
3209 | b43legacy_rng_init(wl); | 3213 | b43legacy_rng_init(wl); |
3210 | 3214 | ||
3211 | b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); | 3215 | b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); |
@@ -3527,7 +3531,7 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) | |||
3527 | wl->current_dev = dev; | 3531 | wl->current_dev = dev; |
3528 | INIT_WORK(&dev->restart_work, b43legacy_chip_reset); | 3532 | INIT_WORK(&dev->restart_work, b43legacy_chip_reset); |
3529 | 3533 | ||
3530 | b43legacy_radio_turn_off(dev); | 3534 | b43legacy_radio_turn_off(dev, 1); |
3531 | b43legacy_switch_analog(dev, 0); | 3535 | b43legacy_switch_analog(dev, 0); |
3532 | ssb_device_disable(dev->dev, 0); | 3536 | ssb_device_disable(dev->dev, 0); |
3533 | ssb_bus_may_powerdown(bus); | 3537 | ssb_bus_may_powerdown(bus); |
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c index 34cb0d801ce1..1dc351ca883c 100644 --- a/drivers/net/wireless/b43legacy/radio.c +++ b/drivers/net/wireless/b43legacy/radio.c | |||
@@ -2115,18 +2115,23 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev) | |||
2115 | phy->radio_on = 1; | 2115 | phy->radio_on = 1; |
2116 | } | 2116 | } |
2117 | 2117 | ||
2118 | void b43legacy_radio_turn_off(struct b43legacy_wldev *dev) | 2118 | void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force) |
2119 | { | 2119 | { |
2120 | struct b43legacy_phy *phy = &dev->phy; | 2120 | struct b43legacy_phy *phy = &dev->phy; |
2121 | 2121 | ||
2122 | if (!phy->radio_on && !force) | ||
2123 | return; | ||
2124 | |||
2122 | if (phy->type == B43legacy_PHYTYPE_G && dev->dev->id.revision >= 5) { | 2125 | if (phy->type == B43legacy_PHYTYPE_G && dev->dev->id.revision >= 5) { |
2123 | u16 rfover, rfoverval; | 2126 | u16 rfover, rfoverval; |
2124 | 2127 | ||
2125 | rfover = b43legacy_phy_read(dev, B43legacy_PHY_RFOVER); | 2128 | rfover = b43legacy_phy_read(dev, B43legacy_PHY_RFOVER); |
2126 | rfoverval = b43legacy_phy_read(dev, B43legacy_PHY_RFOVERVAL); | 2129 | rfoverval = b43legacy_phy_read(dev, B43legacy_PHY_RFOVERVAL); |
2127 | phy->radio_off_context.rfover = rfover; | 2130 | if (!force) { |
2128 | phy->radio_off_context.rfoverval = rfoverval; | 2131 | phy->radio_off_context.rfover = rfover; |
2129 | phy->radio_off_context.valid = 1; | 2132 | phy->radio_off_context.rfoverval = rfoverval; |
2133 | phy->radio_off_context.valid = 1; | ||
2134 | } | ||
2130 | b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C); | 2135 | b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C); |
2131 | b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL, | 2136 | b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL, |
2132 | rfoverval & 0xFF73); | 2137 | rfoverval & 0xFF73); |
diff --git a/drivers/net/wireless/b43legacy/radio.h b/drivers/net/wireless/b43legacy/radio.h index 6c6a203439e1..ad90d9c03462 100644 --- a/drivers/net/wireless/b43legacy/radio.h +++ b/drivers/net/wireless/b43legacy/radio.h | |||
@@ -61,7 +61,7 @@ void b43legacy_radio_write16(struct b43legacy_wldev *dev, u16 offset, u16 val); | |||
61 | u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev); | 61 | u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev); |
62 | 62 | ||
63 | void b43legacy_radio_turn_on(struct b43legacy_wldev *dev); | 63 | void b43legacy_radio_turn_on(struct b43legacy_wldev *dev); |
64 | void b43legacy_radio_turn_off(struct b43legacy_wldev *dev); | 64 | void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force); |
65 | 65 | ||
66 | int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, u8 channel, | 66 | int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, u8 channel, |
67 | int synthetic_pu_workaround); | 67 | int synthetic_pu_workaround); |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c new file mode 100644 index 000000000000..db6292642057 --- /dev/null +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | |||
3 | Broadcom B43legacy wireless driver | ||
4 | RFKILL support | ||
5 | |||
6 | Copyright (c) 2007 Michael Buesch <mb@bu3sch.de> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; see the file COPYING. If not, write to | ||
20 | the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, | ||
21 | Boston, MA 02110-1301, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #include "rfkill.h" | ||
26 | #include "radio.h" | ||
27 | #include "b43legacy.h" | ||
28 | |||
29 | |||
30 | static void b43legacy_notify_rfkill_press(struct work_struct *work) | ||
31 | { | ||
32 | struct b43legacy_rfkill *rfk = container_of(work, | ||
33 | struct b43legacy_rfkill, | ||
34 | notify_work); | ||
35 | struct b43legacy_wl *wl = container_of(rfk, struct b43legacy_wl, | ||
36 | rfkill); | ||
37 | struct b43legacy_wldev *dev; | ||
38 | enum rfkill_state state; | ||
39 | |||
40 | mutex_lock(&wl->mutex); | ||
41 | dev = wl->current_dev; | ||
42 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { | ||
43 | mutex_unlock(&wl->mutex); | ||
44 | return; | ||
45 | } | ||
46 | if (dev->radio_hw_enable) | ||
47 | state = RFKILL_STATE_ON; | ||
48 | else | ||
49 | state = RFKILL_STATE_OFF; | ||
50 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | ||
51 | dev->radio_hw_enable ? "ENABLED" : "DISABLED"); | ||
52 | mutex_unlock(&wl->mutex); | ||
53 | |||
54 | if (rfk->rfkill) { | ||
55 | /* Be careful. This calls back into the software toggle | ||
56 | * routines. So we must unlock before calling. */ | ||
57 | rfkill_switch_all(rfk->rfkill->type, state); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* Called when the RFKILL toggled in hardware. | ||
62 | * This is called with the mutex locked. */ | ||
63 | void b43legacy_rfkill_toggled(struct b43legacy_wldev *dev, bool on) | ||
64 | { | ||
65 | struct b43legacy_wl *wl = dev->wl; | ||
66 | |||
67 | B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED); | ||
68 | /* Update the RF status asynchronously, as rfkill will | ||
69 | * call back into the software toggle handler. | ||
70 | * This would deadlock if done synchronously. */ | ||
71 | queue_work(wl->hw->workqueue, &wl->rfkill.notify_work); | ||
72 | } | ||
73 | |||
74 | /* Called when the RFKILL toggled in software. | ||
75 | * This is called without locking. */ | ||
76 | static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) | ||
77 | { | ||
78 | struct b43legacy_wldev *dev = data; | ||
79 | struct b43legacy_wl *wl = dev->wl; | ||
80 | int err = 0; | ||
81 | |||
82 | mutex_lock(&wl->mutex); | ||
83 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) | ||
84 | goto out_unlock; | ||
85 | |||
86 | switch (state) { | ||
87 | case RFKILL_STATE_ON: | ||
88 | if (!dev->radio_hw_enable) { | ||
89 | /* No luck. We can't toggle the hardware RF-kill | ||
90 | * button from software. */ | ||
91 | err = -EBUSY; | ||
92 | goto out_unlock; | ||
93 | } | ||
94 | if (!dev->phy.radio_on) | ||
95 | b43legacy_radio_turn_on(dev); | ||
96 | break; | ||
97 | case RFKILL_STATE_OFF: | ||
98 | if (dev->phy.radio_on) | ||
99 | b43legacy_radio_turn_off(dev, 0); | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | out_unlock: | ||
104 | mutex_unlock(&wl->mutex); | ||
105 | |||
106 | return err; | ||
107 | } | ||
108 | |||
109 | char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
110 | { | ||
111 | struct b43legacy_wl *wl = dev->wl; | ||
112 | |||
113 | if (!wl->rfkill.rfkill) | ||
114 | return NULL; | ||
115 | return rfkill_get_led_name(wl->rfkill.rfkill); | ||
116 | } | ||
117 | |||
118 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
119 | { | ||
120 | struct b43legacy_wl *wl = dev->wl; | ||
121 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | ||
122 | int err; | ||
123 | |||
124 | snprintf(rfk->name, sizeof(rfk->name), | ||
125 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | ||
126 | rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); | ||
127 | if (!rfk->rfkill) | ||
128 | goto error; | ||
129 | rfk->rfkill->name = rfk->name; | ||
130 | rfk->rfkill->state = RFKILL_STATE_ON; | ||
131 | rfk->rfkill->data = dev; | ||
132 | rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; | ||
133 | rfk->rfkill->user_claim_unsupported = 1; | ||
134 | |||
135 | INIT_WORK(&rfk->notify_work, b43legacy_notify_rfkill_press); | ||
136 | |||
137 | err = rfkill_register(rfk->rfkill); | ||
138 | if (err) | ||
139 | goto error; | ||
140 | |||
141 | return; | ||
142 | error: | ||
143 | b43legacywarn(dev->wl, "Failed to initialize the RF-kill button\n"); | ||
144 | rfkill_free(rfk->rfkill); | ||
145 | rfk->rfkill = NULL; | ||
146 | } | ||
147 | |||
148 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
149 | { | ||
150 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
151 | |||
152 | if (!rfk->rfkill) | ||
153 | return; | ||
154 | cancel_work_sync(&rfk->notify_work); | ||
155 | rfkill_unregister(rfk->rfkill); | ||
156 | rfkill_free(rfk->rfkill); | ||
157 | rfk->rfkill = NULL; | ||
158 | } | ||
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h new file mode 100644 index 000000000000..388ee0b855a6 --- /dev/null +++ b/drivers/net/wireless/b43legacy/rfkill.h | |||
@@ -0,0 +1,51 @@ | |||
1 | #ifndef B43legacy_RFKILL_H_ | ||
2 | #define B43legacy_RFKILL_H_ | ||
3 | |||
4 | struct b43legacy_wldev; | ||
5 | |||
6 | #ifdef CONFIG_B43LEGACY_RFKILL | ||
7 | |||
8 | #include <linux/rfkill.h> | ||
9 | #include <linux/workqueue.h> | ||
10 | |||
11 | |||
12 | struct b43legacy_rfkill { | ||
13 | /* The RFKILL subsystem data structure */ | ||
14 | struct rfkill *rfkill; | ||
15 | /* The unique name of this rfkill switch */ | ||
16 | char name[32]; | ||
17 | /* Workqueue for asynchronous notification. */ | ||
18 | struct work_struct notify_work; | ||
19 | }; | ||
20 | |||
21 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev); | ||
22 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); | ||
23 | void b43legacy_rfkill_toggled(struct b43legacy_wldev *dev, bool on); | ||
24 | char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); | ||
25 | |||
26 | |||
27 | #else /* CONFIG_B43LEGACY_RFKILL */ | ||
28 | /* No RFKILL support. */ | ||
29 | |||
30 | struct b43legacy_rfkill { | ||
31 | /* empty */ | ||
32 | }; | ||
33 | |||
34 | static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
35 | { | ||
36 | } | ||
37 | static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
38 | { | ||
39 | } | ||
40 | static inline void b43legacy_rfkill_toggled(struct b43legacy_wldev *dev, | ||
41 | bool on) | ||
42 | { | ||
43 | } | ||
44 | static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
45 | { | ||
46 | return NULL; | ||
47 | } | ||
48 | |||
49 | #endif /* CONFIG_B43LEGACY_RFKILL */ | ||
50 | |||
51 | #endif /* B43legacy_RFKILL_H_ */ | ||