diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r-- | drivers/net/wireless/b43legacy/leds.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/rfkill.c | 133 |
3 files changed, 88 insertions, 69 deletions
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index f0affb781002..cacb786d9713 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c | |||
@@ -165,6 +165,9 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, | |||
165 | b43legacy_register_led(dev, &dev->led_radio, name, | 165 | b43legacy_register_led(dev, &dev->led_radio, name, |
166 | b43legacy_rfkill_led_name(dev), | 166 | b43legacy_rfkill_led_name(dev), |
167 | led_index, activelow); | 167 | led_index, activelow); |
168 | /* Sync the RF-kill LED state with the switch state. */ | ||
169 | if (dev->radio_hw_enable) | ||
170 | b43legacy_led_turn_on(dev, led_index, activelow); | ||
168 | break; | 171 | break; |
169 | case B43legacy_LED_WEIRD: | 172 | case B43legacy_LED_WEIRD: |
170 | case B43legacy_LED_ASSOC: | 173 | case B43legacy_LED_ASSOC: |
@@ -234,4 +237,5 @@ void b43legacy_leds_exit(struct b43legacy_wldev *dev) | |||
234 | b43legacy_unregister_led(&dev->led_tx); | 237 | b43legacy_unregister_led(&dev->led_tx); |
235 | b43legacy_unregister_led(&dev->led_rx); | 238 | b43legacy_unregister_led(&dev->led_rx); |
236 | b43legacy_unregister_led(&dev->led_assoc); | 239 | b43legacy_unregister_led(&dev->led_assoc); |
240 | b43legacy_unregister_led(&dev->led_radio); | ||
237 | } | 241 | } |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index aa723effcf22..14087fc20f3a 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1995,7 +1995,6 @@ static void b43legacy_mgmtframe_txantenna(struct b43legacy_wldev *dev, | |||
1995 | static void b43legacy_chip_exit(struct b43legacy_wldev *dev) | 1995 | static void b43legacy_chip_exit(struct b43legacy_wldev *dev) |
1996 | { | 1996 | { |
1997 | b43legacy_radio_turn_off(dev, 1); | 1997 | b43legacy_radio_turn_off(dev, 1); |
1998 | b43legacy_leds_exit(dev); | ||
1999 | b43legacy_gpio_cleanup(dev); | 1998 | b43legacy_gpio_cleanup(dev); |
2000 | /* firmware is released later */ | 1999 | /* firmware is released later */ |
2001 | } | 2000 | } |
@@ -2025,11 +2024,10 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) | |||
2025 | err = b43legacy_gpio_init(dev); | 2024 | err = b43legacy_gpio_init(dev); |
2026 | if (err) | 2025 | if (err) |
2027 | goto out; /* firmware is released later */ | 2026 | goto out; /* firmware is released later */ |
2028 | b43legacy_leds_init(dev); | ||
2029 | 2027 | ||
2030 | err = b43legacy_upload_initvals(dev); | 2028 | err = b43legacy_upload_initvals(dev); |
2031 | if (err) | 2029 | if (err) |
2032 | goto err_leds_exit; | 2030 | goto err_gpio_clean; |
2033 | b43legacy_radio_turn_on(dev); | 2031 | b43legacy_radio_turn_on(dev); |
2034 | 2032 | ||
2035 | b43legacy_write16(dev, 0x03E6, 0x0000); | 2033 | b43legacy_write16(dev, 0x03E6, 0x0000); |
@@ -2111,8 +2109,7 @@ out: | |||
2111 | 2109 | ||
2112 | err_radio_off: | 2110 | err_radio_off: |
2113 | b43legacy_radio_turn_off(dev, 1); | 2111 | b43legacy_radio_turn_off(dev, 1); |
2114 | err_leds_exit: | 2112 | err_gpio_clean: |
2115 | b43legacy_leds_exit(dev); | ||
2116 | b43legacy_gpio_cleanup(dev); | 2113 | b43legacy_gpio_cleanup(dev); |
2117 | goto out; | 2114 | goto out; |
2118 | } | 2115 | } |
@@ -2969,10 +2966,7 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
2969 | cancel_work_sync(&dev->restart_work); | 2966 | cancel_work_sync(&dev->restart_work); |
2970 | mutex_lock(&wl->mutex); | 2967 | mutex_lock(&wl->mutex); |
2971 | 2968 | ||
2972 | mutex_unlock(&dev->wl->mutex); | 2969 | b43legacy_leds_exit(dev); |
2973 | b43legacy_rfkill_exit(dev); | ||
2974 | mutex_lock(&dev->wl->mutex); | ||
2975 | |||
2976 | b43legacy_rng_exit(dev->wl); | 2970 | b43legacy_rng_exit(dev->wl); |
2977 | b43legacy_pio_free(dev); | 2971 | b43legacy_pio_free(dev); |
2978 | b43legacy_dma_free(dev); | 2972 | b43legacy_dma_free(dev); |
@@ -3138,11 +3132,11 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) | |||
3138 | memset(wl->mac_addr, 0, ETH_ALEN); | 3132 | memset(wl->mac_addr, 0, ETH_ALEN); |
3139 | b43legacy_upload_card_macaddress(dev); | 3133 | b43legacy_upload_card_macaddress(dev); |
3140 | b43legacy_security_init(dev); | 3134 | b43legacy_security_init(dev); |
3141 | b43legacy_rfkill_init(dev); | ||
3142 | b43legacy_rng_init(wl); | 3135 | b43legacy_rng_init(wl); |
3143 | 3136 | ||
3144 | b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); | 3137 | b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); |
3145 | 3138 | ||
3139 | b43legacy_leds_init(dev); | ||
3146 | out: | 3140 | out: |
3147 | return err; | 3141 | return err; |
3148 | 3142 | ||
@@ -3231,6 +3225,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3231 | int did_init = 0; | 3225 | int did_init = 0; |
3232 | int err = 0; | 3226 | int err = 0; |
3233 | 3227 | ||
3228 | /* First register RFkill. | ||
3229 | * LEDs that are registered later depend on it. */ | ||
3230 | b43legacy_rfkill_init(dev); | ||
3231 | |||
3234 | mutex_lock(&wl->mutex); | 3232 | mutex_lock(&wl->mutex); |
3235 | 3233 | ||
3236 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { | 3234 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { |
@@ -3260,6 +3258,8 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) | |||
3260 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | 3258 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
3261 | struct b43legacy_wldev *dev = wl->current_dev; | 3259 | struct b43legacy_wldev *dev = wl->current_dev; |
3262 | 3260 | ||
3261 | b43legacy_rfkill_exit(dev); | ||
3262 | |||
3263 | mutex_lock(&wl->mutex); | 3263 | mutex_lock(&wl->mutex); |
3264 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) | 3264 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) |
3265 | b43legacy_wireless_core_stop(dev); | 3265 | b43legacy_wireless_core_stop(dev); |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index b9d38a4f286d..520910fd5c45 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "radio.h" | 26 | #include "radio.h" |
27 | #include "b43legacy.h" | 27 | #include "b43legacy.h" |
28 | 28 | ||
29 | #include <linux/kmod.h> | ||
30 | |||
29 | 31 | ||
30 | /* Returns TRUE, if the radio is enabled in hardware. */ | 32 | /* Returns TRUE, if the radio is enabled in hardware. */ |
31 | static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | 33 | static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) |
@@ -51,7 +53,10 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | |||
51 | bool report_change = 0; | 53 | bool report_change = 0; |
52 | 54 | ||
53 | mutex_lock(&wl->mutex); | 55 | mutex_lock(&wl->mutex); |
54 | B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED); | 56 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { |
57 | mutex_unlock(&wl->mutex); | ||
58 | return; | ||
59 | } | ||
55 | enabled = b43legacy_is_hw_radio_enabled(dev); | 60 | enabled = b43legacy_is_hw_radio_enabled(dev); |
56 | if (unlikely(enabled != dev->radio_hw_enable)) { | 61 | if (unlikely(enabled != dev->radio_hw_enable)) { |
57 | dev->radio_hw_enable = enabled; | 62 | dev->radio_hw_enable = enabled; |
@@ -61,8 +66,12 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | |||
61 | } | 66 | } |
62 | mutex_unlock(&wl->mutex); | 67 | mutex_unlock(&wl->mutex); |
63 | 68 | ||
64 | if (unlikely(report_change)) | 69 | /* send the radio switch event to the system - note both a key press |
65 | input_report_key(poll_dev->input, KEY_WLAN, enabled); | 70 | * and a release are required */ |
71 | if (unlikely(report_change)) { | ||
72 | input_report_key(poll_dev->input, KEY_WLAN, 1); | ||
73 | input_report_key(poll_dev->input, KEY_WLAN, 0); | ||
74 | } | ||
66 | } | 75 | } |
67 | 76 | ||
68 | /* Called when the RFKILL toggled in software. | 77 | /* Called when the RFKILL toggled in software. |
@@ -71,13 +80,15 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) | |||
71 | { | 80 | { |
72 | struct b43legacy_wldev *dev = data; | 81 | struct b43legacy_wldev *dev = data; |
73 | struct b43legacy_wl *wl = dev->wl; | 82 | struct b43legacy_wl *wl = dev->wl; |
74 | int err = 0; | 83 | int err = -EBUSY; |
75 | 84 | ||
76 | if (!wl->rfkill.registered) | 85 | if (!wl->rfkill.registered) |
77 | return 0; | 86 | return 0; |
78 | 87 | ||
79 | mutex_lock(&wl->mutex); | 88 | mutex_lock(&wl->mutex); |
80 | B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED); | 89 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) |
90 | goto out_unlock; | ||
91 | err = 0; | ||
81 | switch (state) { | 92 | switch (state) { |
82 | case RFKILL_STATE_ON: | 93 | case RFKILL_STATE_ON: |
83 | if (!dev->radio_hw_enable) { | 94 | if (!dev->radio_hw_enable) { |
@@ -103,11 +114,11 @@ out_unlock: | |||
103 | 114 | ||
104 | char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | 115 | char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) |
105 | { | 116 | { |
106 | struct b43legacy_wl *wl = dev->wl; | 117 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); |
107 | 118 | ||
108 | if (!wl->rfkill.rfkill) | 119 | if (!rfk->registered) |
109 | return NULL; | 120 | return NULL; |
110 | return rfkill_get_led_name(wl->rfkill.rfkill); | 121 | return rfkill_get_led_name(rfk->rfkill); |
111 | } | 122 | } |
112 | 123 | ||
113 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | 124 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) |
@@ -116,53 +127,13 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | |||
116 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | 127 | struct b43legacy_rfkill *rfk = &(wl->rfkill); |
117 | int err; | 128 | int err; |
118 | 129 | ||
119 | if (rfk->rfkill) { | 130 | rfk->registered = 0; |
120 | err = rfkill_register(rfk->rfkill); | ||
121 | if (err) { | ||
122 | b43legacywarn(wl, "Failed to register RF-kill button\n"); | ||
123 | goto err_free_rfk; | ||
124 | } | ||
125 | } | ||
126 | if (rfk->poll_dev) { | ||
127 | err = input_register_polled_device(rfk->poll_dev); | ||
128 | if (err) { | ||
129 | b43legacywarn(wl, "Failed to register RF-kill polldev\n"); | ||
130 | goto err_free_polldev; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | return; | ||
135 | err_free_rfk: | ||
136 | rfkill_free(rfk->rfkill); | ||
137 | rfk->rfkill = NULL; | ||
138 | err_free_polldev: | ||
139 | input_free_polled_device(rfk->poll_dev); | ||
140 | rfk->poll_dev = NULL; | ||
141 | } | ||
142 | |||
143 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
144 | { | ||
145 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
146 | |||
147 | if (rfk->poll_dev) | ||
148 | input_unregister_polled_device(rfk->poll_dev); | ||
149 | if (rfk->rfkill) | ||
150 | rfkill_unregister(rfk->rfkill); | ||
151 | } | ||
152 | |||
153 | void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) | ||
154 | { | ||
155 | struct b43legacy_wl *wl = dev->wl; | ||
156 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | ||
157 | 131 | ||
132 | rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); | ||
133 | if (!rfk->rfkill) | ||
134 | goto out_error; | ||
158 | snprintf(rfk->name, sizeof(rfk->name), | 135 | snprintf(rfk->name, sizeof(rfk->name), |
159 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | 136 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); |
160 | |||
161 | rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); | ||
162 | if (!rfk->rfkill) { | ||
163 | b43legacywarn(wl, "Failed to allocate RF-kill button\n"); | ||
164 | return; | ||
165 | } | ||
166 | rfk->rfkill->name = rfk->name; | 137 | rfk->rfkill->name = rfk->name; |
167 | rfk->rfkill->state = RFKILL_STATE_ON; | 138 | rfk->rfkill->state = RFKILL_STATE_ON; |
168 | rfk->rfkill->data = dev; | 139 | rfk->rfkill->data = dev; |
@@ -170,20 +141,64 @@ void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) | |||
170 | rfk->rfkill->user_claim_unsupported = 1; | 141 | rfk->rfkill->user_claim_unsupported = 1; |
171 | 142 | ||
172 | rfk->poll_dev = input_allocate_polled_device(); | 143 | rfk->poll_dev = input_allocate_polled_device(); |
173 | if (rfk->poll_dev) { | 144 | if (!rfk->poll_dev) |
174 | rfk->poll_dev->private = dev; | 145 | goto err_free_rfk; |
175 | rfk->poll_dev->poll = b43legacy_rfkill_poll; | 146 | rfk->poll_dev->private = dev; |
176 | rfk->poll_dev->poll_interval = 1000; /* msecs */ | 147 | rfk->poll_dev->poll = b43legacy_rfkill_poll; |
177 | } else | 148 | rfk->poll_dev->poll_interval = 1000; /* msecs */ |
178 | b43legacywarn(wl, "Failed to allocate RF-kill polldev\n"); | 149 | |
150 | rfk->poll_dev->input->name = rfk->name; | ||
151 | rfk->poll_dev->input->id.bustype = BUS_HOST; | ||
152 | rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; | ||
153 | rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); | ||
154 | set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); | ||
155 | |||
156 | err = rfkill_register(rfk->rfkill); | ||
157 | if (err) | ||
158 | goto err_free_polldev; | ||
159 | |||
160 | #ifdef CONFIG_RFKILL_INPUT_MODULE | ||
161 | /* B43legacy RF-kill isn't useful without the rfkill-input subsystem. | ||
162 | * Try to load the module. */ | ||
163 | err = request_module("rfkill-input"); | ||
164 | if (err) | ||
165 | b43legacywarn(wl, "Failed to load the rfkill-input module." | ||
166 | "The built-in radio LED will not work.\n"); | ||
167 | #endif /* CONFIG_RFKILL_INPUT */ | ||
168 | |||
169 | err = input_register_polled_device(rfk->poll_dev); | ||
170 | if (err) | ||
171 | goto err_unreg_rfk; | ||
172 | |||
173 | rfk->registered = 1; | ||
174 | |||
175 | return; | ||
176 | err_unreg_rfk: | ||
177 | rfkill_unregister(rfk->rfkill); | ||
178 | err_free_polldev: | ||
179 | input_free_polled_device(rfk->poll_dev); | ||
180 | rfk->poll_dev = NULL; | ||
181 | err_free_rfk: | ||
182 | rfkill_free(rfk->rfkill); | ||
183 | rfk->rfkill = NULL; | ||
184 | out_error: | ||
185 | rfk->registered = 0; | ||
186 | b43legacywarn(wl, "RF-kill button init failed\n"); | ||
179 | } | 187 | } |
180 | 188 | ||
181 | void b43legacy_rfkill_free(struct b43legacy_wldev *dev) | 189 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) |
182 | { | 190 | { |
183 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | 191 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); |
184 | 192 | ||
193 | if (!rfk->registered) | ||
194 | return; | ||
195 | rfk->registered = 0; | ||
196 | |||
197 | input_unregister_polled_device(rfk->poll_dev); | ||
198 | rfkill_unregister(rfk->rfkill); | ||
185 | input_free_polled_device(rfk->poll_dev); | 199 | input_free_polled_device(rfk->poll_dev); |
186 | rfk->poll_dev = NULL; | 200 | rfk->poll_dev = NULL; |
187 | rfkill_free(rfk->rfkill); | 201 | rfkill_free(rfk->rfkill); |
188 | rfk->rfkill = NULL; | 202 | rfk->rfkill = NULL; |
189 | } | 203 | } |
204 | |||