diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy/rfkill.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/rfkill.c | 115 |
1 files changed, 18 insertions, 97 deletions
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index c6230a64505..8783022db11 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -22,15 +22,12 @@ | |||
22 | 22 | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "rfkill.h" | ||
26 | #include "radio.h" | 25 | #include "radio.h" |
27 | #include "b43legacy.h" | 26 | #include "b43legacy.h" |
28 | 27 | ||
29 | #include <linux/kmod.h> | ||
30 | |||
31 | 28 | ||
32 | /* Returns TRUE, if the radio is enabled in hardware. */ | 29 | /* Returns TRUE, if the radio is enabled in hardware. */ |
33 | static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | 30 | bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) |
34 | { | 31 | { |
35 | if (dev->phy.rev >= 3) { | 32 | if (dev->phy.rev >= 3) { |
36 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) | 33 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) |
@@ -45,23 +42,31 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
45 | } | 42 | } |
46 | 43 | ||
47 | /* The poll callback for the hardware button. */ | 44 | /* The poll callback for the hardware button. */ |
48 | static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data) | 45 | void b43legacy_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 46 | { |
50 | struct b43legacy_wldev *dev = data; | 47 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
51 | struct b43legacy_wl *wl = dev->wl; | 48 | struct b43legacy_wldev *dev = wl->current_dev; |
49 | struct ssb_bus *bus = dev->dev->bus; | ||
52 | bool enabled; | 50 | bool enabled; |
51 | bool brought_up = false; | ||
53 | 52 | ||
54 | mutex_lock(&wl->mutex); | 53 | mutex_lock(&wl->mutex); |
55 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { | 54 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { |
56 | mutex_unlock(&wl->mutex); | 55 | if (ssb_bus_powerup(bus, 0)) { |
57 | return; | 56 | mutex_unlock(&wl->mutex); |
57 | return; | ||
58 | } | ||
59 | ssb_device_enable(dev->dev, 0); | ||
60 | brought_up = true; | ||
58 | } | 61 | } |
62 | |||
59 | enabled = b43legacy_is_hw_radio_enabled(dev); | 63 | enabled = b43legacy_is_hw_radio_enabled(dev); |
64 | |||
60 | if (unlikely(enabled != dev->radio_hw_enable)) { | 65 | if (unlikely(enabled != dev->radio_hw_enable)) { |
61 | dev->radio_hw_enable = enabled; | 66 | dev->radio_hw_enable = enabled; |
62 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | 67 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", |
63 | enabled ? "ENABLED" : "DISABLED"); | 68 | enabled ? "ENABLED" : "DISABLED"); |
64 | enabled = !rfkill_set_hw_state(rfkill, !enabled); | 69 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); |
65 | if (enabled != dev->phy.radio_on) { | 70 | if (enabled != dev->phy.radio_on) { |
66 | if (enabled) | 71 | if (enabled) |
67 | b43legacy_radio_turn_on(dev); | 72 | b43legacy_radio_turn_on(dev); |
@@ -69,95 +74,11 @@ static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data) | |||
69 | b43legacy_radio_turn_off(dev, 0); | 74 | b43legacy_radio_turn_off(dev, 0); |
70 | } | 75 | } |
71 | } | 76 | } |
72 | mutex_unlock(&wl->mutex); | ||
73 | } | ||
74 | |||
75 | /* Called when the RFKILL toggled in software. | ||
76 | * This is called without locking. */ | ||
77 | static int b43legacy_rfkill_soft_set(void *data, bool blocked) | ||
78 | { | ||
79 | struct b43legacy_wldev *dev = data; | ||
80 | struct b43legacy_wl *wl = dev->wl; | ||
81 | int ret = -EINVAL; | ||
82 | 77 | ||
83 | if (!wl->rfkill.registered) | 78 | if (brought_up) { |
84 | return -EINVAL; | 79 | ssb_device_disable(dev->dev, 0); |
85 | 80 | ssb_bus_may_powerdown(bus); | |
86 | mutex_lock(&wl->mutex); | ||
87 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) | ||
88 | goto out_unlock; | ||
89 | |||
90 | if (!dev->radio_hw_enable) | ||
91 | goto out_unlock; | ||
92 | |||
93 | if (!blocked != dev->phy.radio_on) { | ||
94 | if (!blocked) | ||
95 | b43legacy_radio_turn_on(dev); | ||
96 | else | ||
97 | b43legacy_radio_turn_off(dev, 0); | ||
98 | } | 81 | } |
99 | ret = 0; | ||
100 | 82 | ||
101 | out_unlock: | ||
102 | mutex_unlock(&wl->mutex); | 83 | mutex_unlock(&wl->mutex); |
103 | return ret; | ||
104 | } | ||
105 | |||
106 | const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
107 | { | ||
108 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
109 | |||
110 | if (!rfk->registered) | ||
111 | return NULL; | ||
112 | return rfkill_get_led_trigger_name(rfk->rfkill); | ||
113 | } | 84 | } |
114 | |||
115 | static const struct rfkill_ops b43legacy_rfkill_ops = { | ||
116 | .set_block = b43legacy_rfkill_soft_set, | ||
117 | .poll = b43legacy_rfkill_poll, | ||
118 | }; | ||
119 | |||
120 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
121 | { | ||
122 | struct b43legacy_wl *wl = dev->wl; | ||
123 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | ||
124 | int err; | ||
125 | |||
126 | rfk->registered = 0; | ||
127 | |||
128 | snprintf(rfk->name, sizeof(rfk->name), | ||
129 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | ||
130 | rfk->rfkill = rfkill_alloc(rfk->name, | ||
131 | dev->dev->dev, | ||
132 | RFKILL_TYPE_WLAN, | ||
133 | &b43legacy_rfkill_ops, dev); | ||
134 | if (!rfk->rfkill) | ||
135 | goto out_error; | ||
136 | |||
137 | err = rfkill_register(rfk->rfkill); | ||
138 | if (err) | ||
139 | goto err_free; | ||
140 | |||
141 | rfk->registered = 1; | ||
142 | |||
143 | return; | ||
144 | err_free: | ||
145 | rfkill_destroy(rfk->rfkill); | ||
146 | out_error: | ||
147 | rfk->registered = 0; | ||
148 | b43legacywarn(wl, "RF-kill button init failed\n"); | ||
149 | } | ||
150 | |||
151 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
152 | { | ||
153 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
154 | |||
155 | if (!rfk->registered) | ||
156 | return; | ||
157 | rfk->registered = 0; | ||
158 | |||
159 | rfkill_unregister(rfk->rfkill); | ||
160 | rfkill_destroy(rfk->rfkill); | ||
161 | rfk->rfkill = NULL; | ||
162 | } | ||
163 | |||