diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/airo.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 64 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_leds.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 64 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_phy.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_pio.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 162 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/prism54/isl_ioctl.c | 573 | ||||
-rw-r--r-- | drivers/net/wireless/prism54/isl_ioctl.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/prism54/islpci_dev.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/prism54/islpci_dev.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_netdev.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 2 |
16 files changed, 780 insertions, 270 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a4dd13942714..16befbcea58c 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -3950,13 +3950,11 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { | |||
3950 | pRsp->rsp0 = IN4500(ai, RESP0); | 3950 | pRsp->rsp0 = IN4500(ai, RESP0); |
3951 | pRsp->rsp1 = IN4500(ai, RESP1); | 3951 | pRsp->rsp1 = IN4500(ai, RESP1); |
3952 | pRsp->rsp2 = IN4500(ai, RESP2); | 3952 | pRsp->rsp2 = IN4500(ai, RESP2); |
3953 | if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) { | 3953 | if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) |
3954 | airo_print_err(ai->dev->name, "cmd= %x\n", pCmd->cmd); | 3954 | airo_print_err(ai->dev->name, |
3955 | airo_print_err(ai->dev->name, "status= %x\n", pRsp->status); | 3955 | "cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x", |
3956 | airo_print_err(ai->dev->name, "Rsp0= %x\n", pRsp->rsp0); | 3956 | pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1, |
3957 | airo_print_err(ai->dev->name, "Rsp1= %x\n", pRsp->rsp1); | 3957 | pRsp->rsp2); |
3958 | airo_print_err(ai->dev->name, "Rsp2= %x\n", pRsp->rsp2); | ||
3959 | } | ||
3960 | 3958 | ||
3961 | // clear stuck command busy if necessary | 3959 | // clear stuck command busy if necessary |
3962 | if (IN4500(ai, COMMAND) & COMMAND_BUSY) { | 3960 | if (IN4500(ai, COMMAND) & COMMAND_BUSY) { |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 17a56828e232..ee6571ed706d 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -649,6 +649,19 @@ enum { | |||
649 | #define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) | 649 | #define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) |
650 | #define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) | 650 | #define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) |
651 | 651 | ||
652 | /* *** THEORY OF LOCKING *** | ||
653 | * | ||
654 | * We have two different locks in the bcm43xx driver. | ||
655 | * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private | ||
656 | * and the device registers. This mutex does _not_ protect | ||
657 | * against concurrency from the IRQ handler. | ||
658 | * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. | ||
659 | * | ||
660 | * Please note that, if you only take the irq_lock, you are not protected | ||
661 | * against concurrency from the periodic work handlers. | ||
662 | * Most times you want to take _both_ locks. | ||
663 | */ | ||
664 | |||
652 | struct bcm43xx_private { | 665 | struct bcm43xx_private { |
653 | struct ieee80211_device *ieee; | 666 | struct ieee80211_device *ieee; |
654 | struct ieee80211softmac_device *softmac; | 667 | struct ieee80211softmac_device *softmac; |
@@ -659,7 +672,6 @@ struct bcm43xx_private { | |||
659 | 672 | ||
660 | void __iomem *mmio_addr; | 673 | void __iomem *mmio_addr; |
661 | 674 | ||
662 | /* Locking, see "theory of locking" text below. */ | ||
663 | spinlock_t irq_lock; | 675 | spinlock_t irq_lock; |
664 | struct mutex mutex; | 676 | struct mutex mutex; |
665 | 677 | ||
@@ -691,6 +703,7 @@ struct bcm43xx_private { | |||
691 | struct bcm43xx_sprominfo sprom; | 703 | struct bcm43xx_sprominfo sprom; |
692 | #define BCM43xx_NR_LEDS 4 | 704 | #define BCM43xx_NR_LEDS 4 |
693 | struct bcm43xx_led leds[BCM43xx_NR_LEDS]; | 705 | struct bcm43xx_led leds[BCM43xx_NR_LEDS]; |
706 | spinlock_t leds_lock; | ||
694 | 707 | ||
695 | /* The currently active core. */ | 708 | /* The currently active core. */ |
696 | struct bcm43xx_coreinfo *current_core; | 709 | struct bcm43xx_coreinfo *current_core; |
@@ -763,55 +776,6 @@ struct bcm43xx_private { | |||
763 | }; | 776 | }; |
764 | 777 | ||
765 | 778 | ||
766 | /* *** THEORY OF LOCKING *** | ||
767 | * | ||
768 | * We have two different locks in the bcm43xx driver. | ||
769 | * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private | ||
770 | * and the device registers. | ||
771 | * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. | ||
772 | * | ||
773 | * We have three types of helper function pairs to utilize these locks. | ||
774 | * (Always use the helper functions.) | ||
775 | * 1) bcm43xx_{un}lock_noirq(): | ||
776 | * Takes bcm->mutex. Does _not_ protect against IRQ concurrency, | ||
777 | * so it is almost always unsafe, if device IRQs are enabled. | ||
778 | * So only use this, if device IRQs are masked. | ||
779 | * Locking may sleep. | ||
780 | * You can sleep within the critical section. | ||
781 | * 2) bcm43xx_{un}lock_irqonly(): | ||
782 | * Takes bcm->irq_lock. Does _not_ protect against | ||
783 | * bcm43xx_lock_noirq() critical sections. | ||
784 | * Does only protect against the IRQ handler path and other | ||
785 | * irqonly() critical sections. | ||
786 | * Locking does not sleep. | ||
787 | * You must not sleep within the critical section. | ||
788 | * 3) bcm43xx_{un}lock_irqsafe(): | ||
789 | * This is the cummulative lock and takes both, mutex and irq_lock. | ||
790 | * Protects against noirq() and irqonly() critical sections (and | ||
791 | * the IRQ handler path). | ||
792 | * Locking may sleep. | ||
793 | * You must not sleep within the critical section. | ||
794 | */ | ||
795 | |||
796 | /* Lock type 1 */ | ||
797 | #define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex) | ||
798 | #define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex) | ||
799 | /* Lock type 2 */ | ||
800 | #define bcm43xx_lock_irqonly(bcm, flags) \ | ||
801 | spin_lock_irqsave(&(bcm)->irq_lock, flags) | ||
802 | #define bcm43xx_unlock_irqonly(bcm, flags) \ | ||
803 | spin_unlock_irqrestore(&(bcm)->irq_lock, flags) | ||
804 | /* Lock type 3 */ | ||
805 | #define bcm43xx_lock_irqsafe(bcm, flags) do { \ | ||
806 | bcm43xx_lock_noirq(bcm); \ | ||
807 | bcm43xx_lock_irqonly(bcm, flags); \ | ||
808 | } while (0) | ||
809 | #define bcm43xx_unlock_irqsafe(bcm, flags) do { \ | ||
810 | bcm43xx_unlock_irqonly(bcm, flags); \ | ||
811 | bcm43xx_unlock_noirq(bcm); \ | ||
812 | } while (0) | ||
813 | |||
814 | |||
815 | static inline | 779 | static inline |
816 | struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) | 780 | struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) |
817 | { | 781 | { |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index ce2e40b29b4f..2600ee4b803a 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | |||
@@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, | |||
77 | 77 | ||
78 | down(&big_buffer_sem); | 78 | down(&big_buffer_sem); |
79 | 79 | ||
80 | bcm43xx_lock_irqsafe(bcm, flags); | 80 | mutex_lock(&bcm->mutex); |
81 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
81 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { | 82 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { |
82 | fappend("Board not initialized.\n"); | 83 | fappend("Board not initialized.\n"); |
83 | goto out; | 84 | goto out; |
@@ -121,7 +122,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, | |||
121 | fappend("\n"); | 122 | fappend("\n"); |
122 | 123 | ||
123 | out: | 124 | out: |
124 | bcm43xx_unlock_irqsafe(bcm, flags); | 125 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
126 | mutex_unlock(&bcm->mutex); | ||
125 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | 127 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); |
126 | up(&big_buffer_sem); | 128 | up(&big_buffer_sem); |
127 | return res; | 129 | return res; |
@@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, | |||
159 | unsigned long flags; | 161 | unsigned long flags; |
160 | 162 | ||
161 | down(&big_buffer_sem); | 163 | down(&big_buffer_sem); |
162 | bcm43xx_lock_irqsafe(bcm, flags); | 164 | mutex_lock(&bcm->mutex); |
165 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
163 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { | 166 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { |
164 | fappend("Board not initialized.\n"); | 167 | fappend("Board not initialized.\n"); |
165 | goto out; | 168 | goto out; |
@@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, | |||
169 | fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); | 172 | fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); |
170 | 173 | ||
171 | out: | 174 | out: |
172 | bcm43xx_unlock_irqsafe(bcm, flags); | 175 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
176 | mutex_unlock(&bcm->mutex); | ||
173 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | 177 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); |
174 | up(&big_buffer_sem); | 178 | up(&big_buffer_sem); |
175 | return res; | 179 | return res; |
@@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, | |||
188 | u64 tsf; | 192 | u64 tsf; |
189 | 193 | ||
190 | down(&big_buffer_sem); | 194 | down(&big_buffer_sem); |
191 | bcm43xx_lock_irqsafe(bcm, flags); | 195 | mutex_lock(&bcm->mutex); |
196 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
192 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { | 197 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { |
193 | fappend("Board not initialized.\n"); | 198 | fappend("Board not initialized.\n"); |
194 | goto out; | 199 | goto out; |
@@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, | |||
199 | (unsigned int)(tsf & 0xFFFFFFFFULL)); | 204 | (unsigned int)(tsf & 0xFFFFFFFFULL)); |
200 | 205 | ||
201 | out: | 206 | out: |
202 | bcm43xx_unlock_irqsafe(bcm, flags); | 207 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
208 | mutex_unlock(&bcm->mutex); | ||
203 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | 209 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); |
204 | up(&big_buffer_sem); | 210 | up(&big_buffer_sem); |
205 | return res; | 211 | return res; |
@@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, | |||
221 | res = -EFAULT; | 227 | res = -EFAULT; |
222 | goto out_up; | 228 | goto out_up; |
223 | } | 229 | } |
224 | bcm43xx_lock_irqsafe(bcm, flags); | 230 | mutex_lock(&bcm->mutex); |
231 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
225 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { | 232 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { |
226 | printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); | 233 | printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); |
227 | res = -EFAULT; | 234 | res = -EFAULT; |
@@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, | |||
237 | res = buf_size; | 244 | res = buf_size; |
238 | 245 | ||
239 | out_unlock: | 246 | out_unlock: |
240 | bcm43xx_unlock_irqsafe(bcm, flags); | 247 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
248 | mutex_unlock(&bcm->mutex); | ||
241 | out_up: | 249 | out_up: |
242 | up(&big_buffer_sem); | 250 | up(&big_buffer_sem); |
243 | return res; | 251 | return res; |
@@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, | |||
258 | int i, cnt, j = 0; | 266 | int i, cnt, j = 0; |
259 | 267 | ||
260 | down(&big_buffer_sem); | 268 | down(&big_buffer_sem); |
261 | bcm43xx_lock_irqsafe(bcm, flags); | 269 | mutex_lock(&bcm->mutex); |
270 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
262 | 271 | ||
263 | fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", | 272 | fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", |
264 | BCM43xx_NR_LOGGED_XMITSTATUS); | 273 | BCM43xx_NR_LOGGED_XMITSTATUS); |
@@ -294,14 +303,15 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, | |||
294 | i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; | 303 | i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; |
295 | } | 304 | } |
296 | 305 | ||
297 | bcm43xx_unlock_irqsafe(bcm, flags); | 306 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
298 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | 307 | res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); |
299 | bcm43xx_lock_irqsafe(bcm, flags); | 308 | spin_lock_irqsave(&bcm->irq_lock, flags); |
300 | if (*ppos == pos) { | 309 | if (*ppos == pos) { |
301 | /* Done. Drop the copied data. */ | 310 | /* Done. Drop the copied data. */ |
302 | e->xmitstatus_printing = 0; | 311 | e->xmitstatus_printing = 0; |
303 | } | 312 | } |
304 | bcm43xx_unlock_irqsafe(bcm, flags); | 313 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
314 | mutex_unlock(&bcm->mutex); | ||
305 | up(&big_buffer_sem); | 315 | up(&big_buffer_sem); |
306 | return res; | 316 | return res; |
307 | } | 317 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index ec80692d638a..c3f90c8563d9 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c | |||
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d) | |||
51 | struct bcm43xx_private *bcm = led->bcm; | 51 | struct bcm43xx_private *bcm = led->bcm; |
52 | unsigned long flags; | 52 | unsigned long flags; |
53 | 53 | ||
54 | bcm43xx_lock_irqonly(bcm, flags); | 54 | spin_lock_irqsave(&bcm->leds_lock, flags); |
55 | if (led->blink_interval) { | 55 | if (led->blink_interval) { |
56 | bcm43xx_led_changestate(led); | 56 | bcm43xx_led_changestate(led); |
57 | mod_timer(&led->blink_timer, jiffies + led->blink_interval); | 57 | mod_timer(&led->blink_timer, jiffies + led->blink_interval); |
58 | } | 58 | } |
59 | bcm43xx_unlock_irqonly(bcm, flags); | 59 | spin_unlock_irqrestore(&bcm->leds_lock, flags); |
60 | } | 60 | } |
61 | 61 | ||
62 | static void bcm43xx_led_blink_start(struct bcm43xx_led *led, | 62 | static void bcm43xx_led_blink_start(struct bcm43xx_led *led, |
@@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) | |||
177 | int i, turn_on; | 177 | int i, turn_on; |
178 | unsigned long interval = 0; | 178 | unsigned long interval = 0; |
179 | u16 ledctl; | 179 | u16 ledctl; |
180 | unsigned long flags; | ||
180 | 181 | ||
182 | spin_lock_irqsave(&bcm->leds_lock, flags); | ||
181 | ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); | 183 | ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); |
182 | for (i = 0; i < BCM43xx_NR_LEDS; i++) { | 184 | for (i = 0; i < BCM43xx_NR_LEDS; i++) { |
183 | led = &(bcm->leds[i]); | 185 | led = &(bcm->leds[i]); |
@@ -266,6 +268,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) | |||
266 | ledctl &= ~(1 << i); | 268 | ledctl &= ~(1 << i); |
267 | } | 269 | } |
268 | bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); | 270 | bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); |
271 | spin_unlock_irqrestore(&bcm->leds_lock, flags); | ||
269 | } | 272 | } |
270 | 273 | ||
271 | void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) | 274 | void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) |
@@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) | |||
274 | u16 ledctl; | 277 | u16 ledctl; |
275 | int i; | 278 | int i; |
276 | int bit_on; | 279 | int bit_on; |
280 | unsigned long flags; | ||
277 | 281 | ||
282 | spin_lock_irqsave(&bcm->leds_lock, flags); | ||
278 | ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); | 283 | ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); |
279 | for (i = 0; i < BCM43xx_NR_LEDS; i++) { | 284 | for (i = 0; i < BCM43xx_NR_LEDS; i++) { |
280 | led = &(bcm->leds[i]); | 285 | led = &(bcm->leds[i]); |
@@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) | |||
290 | ledctl &= ~(1 << i); | 295 | ledctl &= ~(1 << i); |
291 | } | 296 | } |
292 | bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); | 297 | bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); |
298 | spin_unlock_irqrestore(&bcm->leds_lock, flags); | ||
293 | } | 299 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index df317c1e12a8..ab3a0ee9fac8 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -514,13 +514,13 @@ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *old | |||
514 | unsigned long flags; | 514 | unsigned long flags; |
515 | u32 old; | 515 | u32 old; |
516 | 516 | ||
517 | bcm43xx_lock_irqonly(bcm, flags); | 517 | spin_lock_irqsave(&bcm->irq_lock, flags); |
518 | if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { | 518 | if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { |
519 | bcm43xx_unlock_irqonly(bcm, flags); | 519 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
520 | return -EBUSY; | 520 | return -EBUSY; |
521 | } | 521 | } |
522 | old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 522 | old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
523 | bcm43xx_unlock_irqonly(bcm, flags); | 523 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
524 | bcm43xx_synchronize_irq(bcm); | 524 | bcm43xx_synchronize_irq(bcm); |
525 | 525 | ||
526 | if (oldstate) | 526 | if (oldstate) |
@@ -1720,7 +1720,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1720 | # define bcmirq_handled(irq) do { /* nothing */ } while (0) | 1720 | # define bcmirq_handled(irq) do { /* nothing */ } while (0) |
1721 | #endif /* CONFIG_BCM43XX_DEBUG*/ | 1721 | #endif /* CONFIG_BCM43XX_DEBUG*/ |
1722 | 1722 | ||
1723 | bcm43xx_lock_irqonly(bcm, flags); | 1723 | spin_lock_irqsave(&bcm->irq_lock, flags); |
1724 | reason = bcm->irq_reason; | 1724 | reason = bcm->irq_reason; |
1725 | dma_reason[0] = bcm->dma_reason[0]; | 1725 | dma_reason[0] = bcm->dma_reason[0]; |
1726 | dma_reason[1] = bcm->dma_reason[1]; | 1726 | dma_reason[1] = bcm->dma_reason[1]; |
@@ -1746,7 +1746,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1746 | dma_reason[2], dma_reason[3]); | 1746 | dma_reason[2], dma_reason[3]); |
1747 | bcm43xx_controller_restart(bcm, "DMA error"); | 1747 | bcm43xx_controller_restart(bcm, "DMA error"); |
1748 | mmiowb(); | 1748 | mmiowb(); |
1749 | bcm43xx_unlock_irqonly(bcm, flags); | 1749 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
1750 | return; | 1750 | return; |
1751 | } | 1751 | } |
1752 | if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | | 1752 | if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | |
@@ -1834,7 +1834,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1834 | bcm43xx_leds_update(bcm, activity); | 1834 | bcm43xx_leds_update(bcm, activity); |
1835 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); | 1835 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); |
1836 | mmiowb(); | 1836 | mmiowb(); |
1837 | bcm43xx_unlock_irqonly(bcm, flags); | 1837 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
1838 | } | 1838 | } |
1839 | 1839 | ||
1840 | static void pio_irq_workaround(struct bcm43xx_private *bcm, | 1840 | static void pio_irq_workaround(struct bcm43xx_private *bcm, |
@@ -3182,25 +3182,26 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3182 | /* Periodic work will take a long time, so we want it to | 3182 | /* Periodic work will take a long time, so we want it to |
3183 | * be preemtible. | 3183 | * be preemtible. |
3184 | */ | 3184 | */ |
3185 | bcm43xx_lock_irqonly(bcm, flags); | ||
3186 | netif_stop_queue(bcm->net_dev); | 3185 | netif_stop_queue(bcm->net_dev); |
3186 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
3187 | if (bcm43xx_using_pio(bcm)) | 3187 | if (bcm43xx_using_pio(bcm)) |
3188 | bcm43xx_pio_freeze_txqueues(bcm); | 3188 | bcm43xx_pio_freeze_txqueues(bcm); |
3189 | savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 3189 | savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
3190 | bcm43xx_unlock_irqonly(bcm, flags); | 3190 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3191 | bcm43xx_lock_noirq(bcm); | 3191 | mutex_lock(&bcm->mutex); |
3192 | bcm43xx_synchronize_irq(bcm); | 3192 | bcm43xx_synchronize_irq(bcm); |
3193 | } else { | 3193 | } else { |
3194 | /* Periodic work should take short time, so we want low | 3194 | /* Periodic work should take short time, so we want low |
3195 | * locking overhead. | 3195 | * locking overhead. |
3196 | */ | 3196 | */ |
3197 | bcm43xx_lock_irqsafe(bcm, flags); | 3197 | mutex_lock(&bcm->mutex); |
3198 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
3198 | } | 3199 | } |
3199 | 3200 | ||
3200 | do_periodic_work(bcm); | 3201 | do_periodic_work(bcm); |
3201 | 3202 | ||
3202 | if (badness > BADNESS_LIMIT) { | 3203 | if (badness > BADNESS_LIMIT) { |
3203 | bcm43xx_lock_irqonly(bcm, flags); | 3204 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3204 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { | 3205 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { |
3205 | tasklet_enable(&bcm->isr_tasklet); | 3206 | tasklet_enable(&bcm->isr_tasklet); |
3206 | bcm43xx_interrupt_enable(bcm, savedirqs); | 3207 | bcm43xx_interrupt_enable(bcm, savedirqs); |
@@ -3208,13 +3209,10 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3208 | bcm43xx_pio_thaw_txqueues(bcm); | 3209 | bcm43xx_pio_thaw_txqueues(bcm); |
3209 | } | 3210 | } |
3210 | netif_wake_queue(bcm->net_dev); | 3211 | netif_wake_queue(bcm->net_dev); |
3211 | mmiowb(); | ||
3212 | bcm43xx_unlock_irqonly(bcm, flags); | ||
3213 | bcm43xx_unlock_noirq(bcm); | ||
3214 | } else { | ||
3215 | mmiowb(); | ||
3216 | bcm43xx_unlock_irqsafe(bcm, flags); | ||
3217 | } | 3212 | } |
3213 | mmiowb(); | ||
3214 | spin_unlock_irqrestore(&bcm->irq_lock, flags); | ||
3215 | mutex_unlock(&bcm->mutex); | ||
3218 | } | 3216 | } |
3219 | 3217 | ||
3220 | static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) | 3218 | static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) |
@@ -3276,7 +3274,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) | |||
3276 | { | 3274 | { |
3277 | int i, err; | 3275 | int i, err; |
3278 | 3276 | ||
3279 | bcm43xx_lock_noirq(bcm); | 3277 | mutex_lock(&bcm->mutex); |
3280 | bcm43xx_sysfs_unregister(bcm); | 3278 | bcm43xx_sysfs_unregister(bcm); |
3281 | bcm43xx_periodic_tasks_delete(bcm); | 3279 | bcm43xx_periodic_tasks_delete(bcm); |
3282 | 3280 | ||
@@ -3297,7 +3295,7 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) | |||
3297 | bcm43xx_pctl_set_crystal(bcm, 0); | 3295 | bcm43xx_pctl_set_crystal(bcm, 0); |
3298 | 3296 | ||
3299 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); | 3297 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); |
3300 | bcm43xx_unlock_noirq(bcm); | 3298 | mutex_unlock(&bcm->mutex); |
3301 | } | 3299 | } |
3302 | 3300 | ||
3303 | static int bcm43xx_init_board(struct bcm43xx_private *bcm) | 3301 | static int bcm43xx_init_board(struct bcm43xx_private *bcm) |
@@ -3307,7 +3305,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3307 | 3305 | ||
3308 | might_sleep(); | 3306 | might_sleep(); |
3309 | 3307 | ||
3310 | bcm43xx_lock_noirq(bcm); | 3308 | mutex_lock(&bcm->mutex); |
3311 | bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); | 3309 | bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); |
3312 | 3310 | ||
3313 | err = bcm43xx_pctl_set_crystal(bcm, 1); | 3311 | err = bcm43xx_pctl_set_crystal(bcm, 1); |
@@ -3389,7 +3387,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3389 | 3387 | ||
3390 | assert(err == 0); | 3388 | assert(err == 0); |
3391 | out: | 3389 | out: |
3392 | bcm43xx_unlock_noirq(bcm); | 3390 | mutex_unlock(&bcm->mutex); |
3393 | 3391 | ||
3394 | return err; | 3392 | return err; |
3395 | 3393 | ||
@@ -3647,7 +3645,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, | |||
3647 | struct bcm43xx_radioinfo *radio; | 3645 | struct bcm43xx_radioinfo *radio; |
3648 | unsigned long flags; | 3646 | unsigned long flags; |
3649 | 3647 | ||
3650 | bcm43xx_lock_irqsafe(bcm, flags); | 3648 | mutex_lock(&bcm->mutex); |
3649 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
3651 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { | 3650 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { |
3652 | bcm43xx_mac_suspend(bcm); | 3651 | bcm43xx_mac_suspend(bcm); |
3653 | bcm43xx_radio_selectchannel(bcm, channel, 0); | 3652 | bcm43xx_radio_selectchannel(bcm, channel, 0); |
@@ -3656,7 +3655,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, | |||
3656 | radio = bcm43xx_current_radio(bcm); | 3655 | radio = bcm43xx_current_radio(bcm); |
3657 | radio->initial_channel = channel; | 3656 | radio->initial_channel = channel; |
3658 | } | 3657 | } |
3659 | bcm43xx_unlock_irqsafe(bcm, flags); | 3658 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3659 | mutex_unlock(&bcm->mutex); | ||
3660 | } | 3660 | } |
3661 | 3661 | ||
3662 | /* set_security() callback in struct ieee80211_device */ | 3662 | /* set_security() callback in struct ieee80211_device */ |
@@ -3670,7 +3670,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3670 | 3670 | ||
3671 | dprintk(KERN_INFO PFX "set security called"); | 3671 | dprintk(KERN_INFO PFX "set security called"); |
3672 | 3672 | ||
3673 | bcm43xx_lock_irqsafe(bcm, flags); | 3673 | mutex_lock(&bcm->mutex); |
3674 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
3674 | 3675 | ||
3675 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) | 3676 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) |
3676 | if (sec->flags & (1<<keyidx)) { | 3677 | if (sec->flags & (1<<keyidx)) { |
@@ -3739,7 +3740,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3739 | } else | 3740 | } else |
3740 | bcm43xx_clear_keys(bcm); | 3741 | bcm43xx_clear_keys(bcm); |
3741 | } | 3742 | } |
3742 | bcm43xx_unlock_irqsafe(bcm, flags); | 3743 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3744 | mutex_unlock(&bcm->mutex); | ||
3743 | } | 3745 | } |
3744 | 3746 | ||
3745 | /* hard_start_xmit() callback in struct ieee80211_device */ | 3747 | /* hard_start_xmit() callback in struct ieee80211_device */ |
@@ -3751,10 +3753,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, | |||
3751 | int err = -ENODEV; | 3753 | int err = -ENODEV; |
3752 | unsigned long flags; | 3754 | unsigned long flags; |
3753 | 3755 | ||
3754 | bcm43xx_lock_irqonly(bcm, flags); | 3756 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3755 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) | 3757 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) |
3756 | err = bcm43xx_tx(bcm, txb); | 3758 | err = bcm43xx_tx(bcm, txb); |
3757 | bcm43xx_unlock_irqonly(bcm, flags); | 3759 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3758 | 3760 | ||
3759 | return err; | 3761 | return err; |
3760 | } | 3762 | } |
@@ -3769,9 +3771,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev) | |||
3769 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 3771 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
3770 | unsigned long flags; | 3772 | unsigned long flags; |
3771 | 3773 | ||
3772 | bcm43xx_lock_irqonly(bcm, flags); | 3774 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3773 | bcm43xx_controller_restart(bcm, "TX timeout"); | 3775 | bcm43xx_controller_restart(bcm, "TX timeout"); |
3774 | bcm43xx_unlock_irqonly(bcm, flags); | 3776 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
3775 | } | 3777 | } |
3776 | 3778 | ||
3777 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3779 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -3822,6 +3824,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
3822 | bcm->net_dev = net_dev; | 3824 | bcm->net_dev = net_dev; |
3823 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; | 3825 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; |
3824 | spin_lock_init(&bcm->irq_lock); | 3826 | spin_lock_init(&bcm->irq_lock); |
3827 | spin_lock_init(&bcm->leds_lock); | ||
3825 | mutex_init(&bcm->mutex); | 3828 | mutex_init(&bcm->mutex); |
3826 | tasklet_init(&bcm->isr_tasklet, | 3829 | tasklet_init(&bcm->isr_tasklet, |
3827 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, | 3830 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, |
@@ -4002,16 +4005,13 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4002 | { | 4005 | { |
4003 | struct net_device *net_dev = pci_get_drvdata(pdev); | 4006 | struct net_device *net_dev = pci_get_drvdata(pdev); |
4004 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 4007 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
4005 | unsigned long flags; | ||
4006 | int try_to_shutdown = 0, err; | 4008 | int try_to_shutdown = 0, err; |
4007 | 4009 | ||
4008 | dprintk(KERN_INFO PFX "Suspending...\n"); | 4010 | dprintk(KERN_INFO PFX "Suspending...\n"); |
4009 | 4011 | ||
4010 | bcm43xx_lock_irqsafe(bcm, flags); | ||
4011 | bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); | 4012 | bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); |
4012 | if (bcm->was_initialized) | 4013 | if (bcm->was_initialized) |
4013 | try_to_shutdown = 1; | 4014 | try_to_shutdown = 1; |
4014 | bcm43xx_unlock_irqsafe(bcm, flags); | ||
4015 | 4015 | ||
4016 | netif_device_detach(net_dev); | 4016 | netif_device_detach(net_dev); |
4017 | if (try_to_shutdown) { | 4017 | if (try_to_shutdown) { |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index f8200deecc8a..eafd0f662686 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c | |||
@@ -81,6 +81,16 @@ static const s8 bcm43xx_tssi2dbm_g_table[] = { | |||
81 | static void bcm43xx_phy_initg(struct bcm43xx_private *bcm); | 81 | static void bcm43xx_phy_initg(struct bcm43xx_private *bcm); |
82 | 82 | ||
83 | 83 | ||
84 | static inline | ||
85 | void bcm43xx_voluntary_preempt(void) | ||
86 | { | ||
87 | assert(!in_atomic() && !in_irq() && | ||
88 | !in_interrupt() && !irqs_disabled()); | ||
89 | #ifndef CONFIG_PREEMPT | ||
90 | cond_resched(); | ||
91 | #endif /* CONFIG_PREEMPT */ | ||
92 | } | ||
93 | |||
84 | void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm) | 94 | void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm) |
85 | { | 95 | { |
86 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); | 96 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); |
@@ -133,22 +143,14 @@ void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val) | |||
133 | void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm) | 143 | void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm) |
134 | { | 144 | { |
135 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); | 145 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); |
136 | unsigned long flags; | ||
137 | 146 | ||
138 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */ | 147 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */ |
139 | if (phy->calibrated) | 148 | if (phy->calibrated) |
140 | return; | 149 | return; |
141 | if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) { | 150 | if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) { |
142 | /* We do not want to be preempted while calibrating | ||
143 | * the hardware. | ||
144 | */ | ||
145 | local_irq_save(flags); | ||
146 | |||
147 | bcm43xx_wireless_core_reset(bcm, 0); | 151 | bcm43xx_wireless_core_reset(bcm, 0); |
148 | bcm43xx_phy_initg(bcm); | 152 | bcm43xx_phy_initg(bcm); |
149 | bcm43xx_wireless_core_reset(bcm, 1); | 153 | bcm43xx_wireless_core_reset(bcm, 1); |
150 | |||
151 | local_irq_restore(flags); | ||
152 | } | 154 | } |
153 | phy->calibrated = 1; | 155 | phy->calibrated = 1; |
154 | } | 156 | } |
@@ -1299,7 +1301,9 @@ static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm) | |||
1299 | { | 1301 | { |
1300 | int i; | 1302 | int i; |
1301 | u16 ret = 0; | 1303 | u16 ret = 0; |
1304 | unsigned long flags; | ||
1302 | 1305 | ||
1306 | local_irq_save(flags); | ||
1303 | for (i = 0; i < 10; i++){ | 1307 | for (i = 0; i < 10; i++){ |
1304 | bcm43xx_phy_write(bcm, 0x0015, 0xAFA0); | 1308 | bcm43xx_phy_write(bcm, 0x0015, 0xAFA0); |
1305 | udelay(1); | 1309 | udelay(1); |
@@ -1309,6 +1313,8 @@ static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm) | |||
1309 | udelay(40); | 1313 | udelay(40); |
1310 | ret += bcm43xx_phy_read(bcm, 0x002C); | 1314 | ret += bcm43xx_phy_read(bcm, 0x002C); |
1311 | } | 1315 | } |
1316 | local_irq_restore(flags); | ||
1317 | bcm43xx_voluntary_preempt(); | ||
1312 | 1318 | ||
1313 | return ret; | 1319 | return ret; |
1314 | } | 1320 | } |
@@ -1435,6 +1441,7 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) | |||
1435 | } | 1441 | } |
1436 | ret = bcm43xx_phy_read(bcm, 0x002D); | 1442 | ret = bcm43xx_phy_read(bcm, 0x002D); |
1437 | local_irq_restore(flags); | 1443 | local_irq_restore(flags); |
1444 | bcm43xx_voluntary_preempt(); | ||
1438 | 1445 | ||
1439 | return ret; | 1446 | return ret; |
1440 | } | 1447 | } |
@@ -1760,6 +1767,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) | |||
1760 | bcm43xx_radio_write16(bcm, 0x43, i); | 1767 | bcm43xx_radio_write16(bcm, 0x43, i); |
1761 | bcm43xx_radio_write16(bcm, 0x52, radio->txctl2); | 1768 | bcm43xx_radio_write16(bcm, 0x52, radio->txctl2); |
1762 | udelay(10); | 1769 | udelay(10); |
1770 | bcm43xx_voluntary_preempt(); | ||
1763 | 1771 | ||
1764 | bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); | 1772 | bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); |
1765 | 1773 | ||
@@ -1803,6 +1811,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) | |||
1803 | radio->txctl2 | 1811 | radio->txctl2 |
1804 | | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above? | 1812 | | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above? |
1805 | udelay(10); | 1813 | udelay(10); |
1814 | bcm43xx_voluntary_preempt(); | ||
1806 | 1815 | ||
1807 | bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); | 1816 | bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); |
1808 | 1817 | ||
@@ -1824,6 +1833,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) | |||
1824 | bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2); | 1833 | bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2); |
1825 | udelay(2); | 1834 | udelay(2); |
1826 | bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3); | 1835 | bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3); |
1836 | bcm43xx_voluntary_preempt(); | ||
1827 | } else | 1837 | } else |
1828 | bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0); | 1838 | bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0); |
1829 | bcm43xx_phy_lo_adjust(bcm, is_initializing); | 1839 | bcm43xx_phy_lo_adjust(bcm, is_initializing); |
@@ -2188,12 +2198,6 @@ int bcm43xx_phy_init(struct bcm43xx_private *bcm) | |||
2188 | { | 2198 | { |
2189 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); | 2199 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); |
2190 | int err = -ENODEV; | 2200 | int err = -ENODEV; |
2191 | unsigned long flags; | ||
2192 | |||
2193 | /* We do not want to be preempted while calibrating | ||
2194 | * the hardware. | ||
2195 | */ | ||
2196 | local_irq_save(flags); | ||
2197 | 2201 | ||
2198 | switch (phy->type) { | 2202 | switch (phy->type) { |
2199 | case BCM43xx_PHYTYPE_A: | 2203 | case BCM43xx_PHYTYPE_A: |
@@ -2227,7 +2231,6 @@ int bcm43xx_phy_init(struct bcm43xx_private *bcm) | |||
2227 | err = 0; | 2231 | err = 0; |
2228 | break; | 2232 | break; |
2229 | } | 2233 | } |
2230 | local_irq_restore(flags); | ||
2231 | if (err) | 2234 | if (err) |
2232 | printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n"); | 2235 | printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n"); |
2233 | 2236 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c index 574085c46152..c60c1743ea06 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c | |||
@@ -262,7 +262,7 @@ static void tx_tasklet(unsigned long d) | |||
262 | int err; | 262 | int err; |
263 | u16 txctl; | 263 | u16 txctl; |
264 | 264 | ||
265 | bcm43xx_lock_irqonly(bcm, flags); | 265 | spin_lock_irqsave(&bcm->irq_lock, flags); |
266 | 266 | ||
267 | if (queue->tx_frozen) | 267 | if (queue->tx_frozen) |
268 | goto out_unlock; | 268 | goto out_unlock; |
@@ -300,7 +300,7 @@ static void tx_tasklet(unsigned long d) | |||
300 | continue; | 300 | continue; |
301 | } | 301 | } |
302 | out_unlock: | 302 | out_unlock: |
303 | bcm43xx_unlock_irqonly(bcm, flags); | 303 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
304 | } | 304 | } |
305 | 305 | ||
306 | static void setup_txqueues(struct bcm43xx_pioqueue *queue) | 306 | static void setup_txqueues(struct bcm43xx_pioqueue *queue) |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index 6a23bdc75412..cc1ff3c6f140 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | |||
@@ -120,12 +120,14 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev, | |||
120 | GFP_KERNEL); | 120 | GFP_KERNEL); |
121 | if (!sprom) | 121 | if (!sprom) |
122 | return -ENOMEM; | 122 | return -ENOMEM; |
123 | bcm43xx_lock_irqsafe(bcm, flags); | 123 | mutex_lock(&bcm->mutex); |
124 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
124 | err = bcm43xx_sprom_read(bcm, sprom); | 125 | err = bcm43xx_sprom_read(bcm, sprom); |
125 | if (!err) | 126 | if (!err) |
126 | err = sprom2hex(sprom, buf, PAGE_SIZE); | 127 | err = sprom2hex(sprom, buf, PAGE_SIZE); |
127 | mmiowb(); | 128 | mmiowb(); |
128 | bcm43xx_unlock_irqsafe(bcm, flags); | 129 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
130 | mutex_unlock(&bcm->mutex); | ||
129 | kfree(sprom); | 131 | kfree(sprom); |
130 | 132 | ||
131 | return err; | 133 | return err; |
@@ -150,10 +152,14 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev, | |||
150 | err = hex2sprom(sprom, buf, count); | 152 | err = hex2sprom(sprom, buf, count); |
151 | if (err) | 153 | if (err) |
152 | goto out_kfree; | 154 | goto out_kfree; |
153 | bcm43xx_lock_irqsafe(bcm, flags); | 155 | mutex_lock(&bcm->mutex); |
156 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
157 | spin_lock(&bcm->leds_lock); | ||
154 | err = bcm43xx_sprom_write(bcm, sprom); | 158 | err = bcm43xx_sprom_write(bcm, sprom); |
155 | mmiowb(); | 159 | mmiowb(); |
156 | bcm43xx_unlock_irqsafe(bcm, flags); | 160 | spin_unlock(&bcm->leds_lock); |
161 | spin_unlock_irqrestore(&bcm->irq_lock, flags); | ||
162 | mutex_unlock(&bcm->mutex); | ||
157 | out_kfree: | 163 | out_kfree: |
158 | kfree(sprom); | 164 | kfree(sprom); |
159 | 165 | ||
@@ -176,7 +182,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, | |||
176 | if (!capable(CAP_NET_ADMIN)) | 182 | if (!capable(CAP_NET_ADMIN)) |
177 | return -EPERM; | 183 | return -EPERM; |
178 | 184 | ||
179 | bcm43xx_lock_noirq(bcm); | 185 | mutex_lock(&bcm->mutex); |
180 | 186 | ||
181 | switch (bcm43xx_current_radio(bcm)->interfmode) { | 187 | switch (bcm43xx_current_radio(bcm)->interfmode) { |
182 | case BCM43xx_RADIO_INTERFMODE_NONE: | 188 | case BCM43xx_RADIO_INTERFMODE_NONE: |
@@ -193,7 +199,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, | |||
193 | } | 199 | } |
194 | err = 0; | 200 | err = 0; |
195 | 201 | ||
196 | bcm43xx_unlock_noirq(bcm); | 202 | mutex_unlock(&bcm->mutex); |
197 | 203 | ||
198 | return err ? err : count; | 204 | return err ? err : count; |
199 | 205 | ||
@@ -229,7 +235,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, | |||
229 | return -EINVAL; | 235 | return -EINVAL; |
230 | } | 236 | } |
231 | 237 | ||
232 | bcm43xx_lock_irqsafe(bcm, flags); | 238 | mutex_lock(&bcm->mutex); |
239 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
233 | 240 | ||
234 | err = bcm43xx_radio_set_interference_mitigation(bcm, mode); | 241 | err = bcm43xx_radio_set_interference_mitigation(bcm, mode); |
235 | if (err) { | 242 | if (err) { |
@@ -237,7 +244,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, | |||
237 | "supported by device\n"); | 244 | "supported by device\n"); |
238 | } | 245 | } |
239 | mmiowb(); | 246 | mmiowb(); |
240 | bcm43xx_unlock_irqsafe(bcm, flags); | 247 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
248 | mutex_unlock(&bcm->mutex); | ||
241 | 249 | ||
242 | return err ? err : count; | 250 | return err ? err : count; |
243 | } | 251 | } |
@@ -257,7 +265,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, | |||
257 | if (!capable(CAP_NET_ADMIN)) | 265 | if (!capable(CAP_NET_ADMIN)) |
258 | return -EPERM; | 266 | return -EPERM; |
259 | 267 | ||
260 | bcm43xx_lock_noirq(bcm); | 268 | mutex_lock(&bcm->mutex); |
261 | 269 | ||
262 | if (bcm->short_preamble) | 270 | if (bcm->short_preamble) |
263 | count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); | 271 | count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); |
@@ -265,7 +273,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, | |||
265 | count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); | 273 | count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); |
266 | 274 | ||
267 | err = 0; | 275 | err = 0; |
268 | bcm43xx_unlock_noirq(bcm); | 276 | mutex_unlock(&bcm->mutex); |
269 | 277 | ||
270 | return err ? err : count; | 278 | return err ? err : count; |
271 | } | 279 | } |
@@ -285,12 +293,14 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, | |||
285 | value = get_boolean(buf, count); | 293 | value = get_boolean(buf, count); |
286 | if (value < 0) | 294 | if (value < 0) |
287 | return value; | 295 | return value; |
288 | bcm43xx_lock_irqsafe(bcm, flags); | 296 | mutex_lock(&bcm->mutex); |
297 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
289 | 298 | ||
290 | bcm->short_preamble = !!value; | 299 | bcm->short_preamble = !!value; |
291 | 300 | ||
292 | err = 0; | 301 | err = 0; |
293 | bcm43xx_unlock_irqsafe(bcm, flags); | 302 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
303 | mutex_unlock(&bcm->mutex); | ||
294 | 304 | ||
295 | return err ? err : count; | 305 | return err ? err : count; |
296 | } | 306 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 5c36e29efff7..8ffd760dc830 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
@@ -47,6 +47,9 @@ | |||
47 | #define BCM43xx_WX_VERSION 18 | 47 | #define BCM43xx_WX_VERSION 18 |
48 | 48 | ||
49 | #define MAX_WX_STRING 80 | 49 | #define MAX_WX_STRING 80 |
50 | /* FIXME: the next line is a guess as to what the maximum value of RX power | ||
51 | (in dBm) might be */ | ||
52 | #define RX_POWER_MAX -10 | ||
50 | 53 | ||
51 | 54 | ||
52 | static int bcm43xx_wx_get_name(struct net_device *net_dev, | 55 | static int bcm43xx_wx_get_name(struct net_device *net_dev, |
@@ -56,12 +59,11 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, | |||
56 | { | 59 | { |
57 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 60 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
58 | int i; | 61 | int i; |
59 | unsigned long flags; | ||
60 | struct bcm43xx_phyinfo *phy; | 62 | struct bcm43xx_phyinfo *phy; |
61 | char suffix[7] = { 0 }; | 63 | char suffix[7] = { 0 }; |
62 | int have_a = 0, have_b = 0, have_g = 0; | 64 | int have_a = 0, have_b = 0, have_g = 0; |
63 | 65 | ||
64 | bcm43xx_lock_irqsafe(bcm, flags); | 66 | mutex_lock(&bcm->mutex); |
65 | for (i = 0; i < bcm->nr_80211_available; i++) { | 67 | for (i = 0; i < bcm->nr_80211_available; i++) { |
66 | phy = &(bcm->core_80211_ext[i].phy); | 68 | phy = &(bcm->core_80211_ext[i].phy); |
67 | switch (phy->type) { | 69 | switch (phy->type) { |
@@ -77,7 +79,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, | |||
77 | assert(0); | 79 | assert(0); |
78 | } | 80 | } |
79 | } | 81 | } |
80 | bcm43xx_unlock_irqsafe(bcm, flags); | 82 | mutex_unlock(&bcm->mutex); |
81 | 83 | ||
82 | i = 0; | 84 | i = 0; |
83 | if (have_a) { | 85 | if (have_a) { |
@@ -111,7 +113,9 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, | |||
111 | int freq; | 113 | int freq; |
112 | int err = -EINVAL; | 114 | int err = -EINVAL; |
113 | 115 | ||
114 | bcm43xx_lock_irqsafe(bcm, flags); | 116 | mutex_lock(&bcm->mutex); |
117 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
118 | |||
115 | if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { | 119 | if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { |
116 | channel = data->freq.m; | 120 | channel = data->freq.m; |
117 | freq = bcm43xx_channel_to_freq(bcm, channel); | 121 | freq = bcm43xx_channel_to_freq(bcm, channel); |
@@ -131,7 +135,8 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, | |||
131 | err = 0; | 135 | err = 0; |
132 | } | 136 | } |
133 | out_unlock: | 137 | out_unlock: |
134 | bcm43xx_unlock_irqsafe(bcm, flags); | 138 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
139 | mutex_unlock(&bcm->mutex); | ||
135 | 140 | ||
136 | return err; | 141 | return err; |
137 | } | 142 | } |
@@ -143,11 +148,10 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, | |||
143 | { | 148 | { |
144 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 149 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
145 | struct bcm43xx_radioinfo *radio; | 150 | struct bcm43xx_radioinfo *radio; |
146 | unsigned long flags; | ||
147 | int err = -ENODEV; | 151 | int err = -ENODEV; |
148 | u16 channel; | 152 | u16 channel; |
149 | 153 | ||
150 | bcm43xx_lock_irqsafe(bcm, flags); | 154 | mutex_lock(&bcm->mutex); |
151 | radio = bcm43xx_current_radio(bcm); | 155 | radio = bcm43xx_current_radio(bcm); |
152 | channel = radio->channel; | 156 | channel = radio->channel; |
153 | if (channel == 0xFF) { | 157 | if (channel == 0xFF) { |
@@ -162,7 +166,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, | |||
162 | 166 | ||
163 | err = 0; | 167 | err = 0; |
164 | out_unlock: | 168 | out_unlock: |
165 | bcm43xx_unlock_irqsafe(bcm, flags); | 169 | mutex_unlock(&bcm->mutex); |
166 | 170 | ||
167 | return err; | 171 | return err; |
168 | } | 172 | } |
@@ -180,13 +184,15 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev, | |||
180 | if (mode == IW_MODE_AUTO) | 184 | if (mode == IW_MODE_AUTO) |
181 | mode = BCM43xx_INITIAL_IWMODE; | 185 | mode = BCM43xx_INITIAL_IWMODE; |
182 | 186 | ||
183 | bcm43xx_lock_irqsafe(bcm, flags); | 187 | mutex_lock(&bcm->mutex); |
188 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
184 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { | 189 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { |
185 | if (bcm->ieee->iw_mode != mode) | 190 | if (bcm->ieee->iw_mode != mode) |
186 | bcm43xx_set_iwmode(bcm, mode); | 191 | bcm43xx_set_iwmode(bcm, mode); |
187 | } else | 192 | } else |
188 | bcm->ieee->iw_mode = mode; | 193 | bcm->ieee->iw_mode = mode; |
189 | bcm43xx_unlock_irqsafe(bcm, flags); | 194 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
195 | mutex_unlock(&bcm->mutex); | ||
190 | 196 | ||
191 | return 0; | 197 | return 0; |
192 | } | 198 | } |
@@ -197,11 +203,10 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev, | |||
197 | char *extra) | 203 | char *extra) |
198 | { | 204 | { |
199 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 205 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
200 | unsigned long flags; | ||
201 | 206 | ||
202 | bcm43xx_lock_irqsafe(bcm, flags); | 207 | mutex_lock(&bcm->mutex); |
203 | data->mode = bcm->ieee->iw_mode; | 208 | data->mode = bcm->ieee->iw_mode; |
204 | bcm43xx_unlock_irqsafe(bcm, flags); | 209 | mutex_unlock(&bcm->mutex); |
205 | 210 | ||
206 | return 0; | 211 | return 0; |
207 | } | 212 | } |
@@ -214,7 +219,6 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, | |||
214 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 219 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
215 | struct iw_range *range = (struct iw_range *)extra; | 220 | struct iw_range *range = (struct iw_range *)extra; |
216 | const struct ieee80211_geo *geo; | 221 | const struct ieee80211_geo *geo; |
217 | unsigned long flags; | ||
218 | int i, j; | 222 | int i, j; |
219 | struct bcm43xx_phyinfo *phy; | 223 | struct bcm43xx_phyinfo *phy; |
220 | 224 | ||
@@ -227,14 +231,14 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, | |||
227 | 231 | ||
228 | range->max_qual.qual = 100; | 232 | range->max_qual.qual = 100; |
229 | /* TODO: Real max RSSI */ | 233 | /* TODO: Real max RSSI */ |
230 | range->max_qual.level = 3; | 234 | range->max_qual.level = 0; |
231 | range->max_qual.noise = 100; | 235 | range->max_qual.noise = 0; |
232 | range->max_qual.updated = 7; | 236 | range->max_qual.updated = IW_QUAL_ALL_UPDATED; |
233 | 237 | ||
234 | range->avg_qual.qual = 70; | 238 | range->avg_qual.qual = 50; |
235 | range->avg_qual.level = 2; | 239 | range->avg_qual.level = 0; |
236 | range->avg_qual.noise = 40; | 240 | range->avg_qual.noise = 0; |
237 | range->avg_qual.updated = 7; | 241 | range->avg_qual.updated = IW_QUAL_ALL_UPDATED; |
238 | 242 | ||
239 | range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; | 243 | range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; |
240 | range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; | 244 | range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; |
@@ -254,7 +258,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, | |||
254 | IW_ENC_CAPA_CIPHER_TKIP | | 258 | IW_ENC_CAPA_CIPHER_TKIP | |
255 | IW_ENC_CAPA_CIPHER_CCMP; | 259 | IW_ENC_CAPA_CIPHER_CCMP; |
256 | 260 | ||
257 | bcm43xx_lock_irqsafe(bcm, flags); | 261 | mutex_lock(&bcm->mutex); |
258 | phy = bcm43xx_current_phy(bcm); | 262 | phy = bcm43xx_current_phy(bcm); |
259 | 263 | ||
260 | range->num_bitrates = 0; | 264 | range->num_bitrates = 0; |
@@ -301,7 +305,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, | |||
301 | } | 305 | } |
302 | range->num_frequency = j; | 306 | range->num_frequency = j; |
303 | 307 | ||
304 | bcm43xx_unlock_irqsafe(bcm, flags); | 308 | mutex_unlock(&bcm->mutex); |
305 | 309 | ||
306 | return 0; | 310 | return 0; |
307 | } | 311 | } |
@@ -314,11 +318,11 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev, | |||
314 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 318 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
315 | size_t len; | 319 | size_t len; |
316 | 320 | ||
317 | bcm43xx_lock_noirq(bcm); | 321 | mutex_lock(&bcm->mutex); |
318 | len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); | 322 | len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); |
319 | memcpy(bcm->nick, extra, len); | 323 | memcpy(bcm->nick, extra, len); |
320 | bcm->nick[len] = '\0'; | 324 | bcm->nick[len] = '\0'; |
321 | bcm43xx_unlock_noirq(bcm); | 325 | mutex_unlock(&bcm->mutex); |
322 | 326 | ||
323 | return 0; | 327 | return 0; |
324 | } | 328 | } |
@@ -331,12 +335,12 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev, | |||
331 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 335 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
332 | size_t len; | 336 | size_t len; |
333 | 337 | ||
334 | bcm43xx_lock_noirq(bcm); | 338 | mutex_lock(&bcm->mutex); |
335 | len = strlen(bcm->nick) + 1; | 339 | len = strlen(bcm->nick) + 1; |
336 | memcpy(extra, bcm->nick, len); | 340 | memcpy(extra, bcm->nick, len); |
337 | data->data.length = (__u16)len; | 341 | data->data.length = (__u16)len; |
338 | data->data.flags = 1; | 342 | data->data.flags = 1; |
339 | bcm43xx_unlock_noirq(bcm); | 343 | mutex_unlock(&bcm->mutex); |
340 | 344 | ||
341 | return 0; | 345 | return 0; |
342 | } | 346 | } |
@@ -350,7 +354,8 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, | |||
350 | unsigned long flags; | 354 | unsigned long flags; |
351 | int err = -EINVAL; | 355 | int err = -EINVAL; |
352 | 356 | ||
353 | bcm43xx_lock_irqsafe(bcm, flags); | 357 | mutex_lock(&bcm->mutex); |
358 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
354 | if (data->rts.disabled) { | 359 | if (data->rts.disabled) { |
355 | bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; | 360 | bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; |
356 | err = 0; | 361 | err = 0; |
@@ -361,7 +366,8 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, | |||
361 | err = 0; | 366 | err = 0; |
362 | } | 367 | } |
363 | } | 368 | } |
364 | bcm43xx_unlock_irqsafe(bcm, flags); | 369 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
370 | mutex_unlock(&bcm->mutex); | ||
365 | 371 | ||
366 | return err; | 372 | return err; |
367 | } | 373 | } |
@@ -372,13 +378,12 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev, | |||
372 | char *extra) | 378 | char *extra) |
373 | { | 379 | { |
374 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 380 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
375 | unsigned long flags; | ||
376 | 381 | ||
377 | bcm43xx_lock_irqsafe(bcm, flags); | 382 | mutex_lock(&bcm->mutex); |
378 | data->rts.value = bcm->rts_threshold; | 383 | data->rts.value = bcm->rts_threshold; |
379 | data->rts.fixed = 0; | 384 | data->rts.fixed = 0; |
380 | data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); | 385 | data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); |
381 | bcm43xx_unlock_irqsafe(bcm, flags); | 386 | mutex_unlock(&bcm->mutex); |
382 | 387 | ||
383 | return 0; | 388 | return 0; |
384 | } | 389 | } |
@@ -392,7 +397,8 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, | |||
392 | unsigned long flags; | 397 | unsigned long flags; |
393 | int err = -EINVAL; | 398 | int err = -EINVAL; |
394 | 399 | ||
395 | bcm43xx_lock_irqsafe(bcm, flags); | 400 | mutex_lock(&bcm->mutex); |
401 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
396 | if (data->frag.disabled) { | 402 | if (data->frag.disabled) { |
397 | bcm->ieee->fts = MAX_FRAG_THRESHOLD; | 403 | bcm->ieee->fts = MAX_FRAG_THRESHOLD; |
398 | err = 0; | 404 | err = 0; |
@@ -403,7 +409,8 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, | |||
403 | err = 0; | 409 | err = 0; |
404 | } | 410 | } |
405 | } | 411 | } |
406 | bcm43xx_unlock_irqsafe(bcm, flags); | 412 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
413 | mutex_unlock(&bcm->mutex); | ||
407 | 414 | ||
408 | return err; | 415 | return err; |
409 | } | 416 | } |
@@ -414,13 +421,12 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev, | |||
414 | char *extra) | 421 | char *extra) |
415 | { | 422 | { |
416 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 423 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
417 | unsigned long flags; | ||
418 | 424 | ||
419 | bcm43xx_lock_irqsafe(bcm, flags); | 425 | mutex_lock(&bcm->mutex); |
420 | data->frag.value = bcm->ieee->fts; | 426 | data->frag.value = bcm->ieee->fts; |
421 | data->frag.fixed = 0; | 427 | data->frag.fixed = 0; |
422 | data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); | 428 | data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); |
423 | bcm43xx_unlock_irqsafe(bcm, flags); | 429 | mutex_unlock(&bcm->mutex); |
424 | 430 | ||
425 | return 0; | 431 | return 0; |
426 | } | 432 | } |
@@ -442,7 +448,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, | |||
442 | return -EOPNOTSUPP; | 448 | return -EOPNOTSUPP; |
443 | } | 449 | } |
444 | 450 | ||
445 | bcm43xx_lock_irqsafe(bcm, flags); | 451 | mutex_lock(&bcm->mutex); |
452 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
446 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) | 453 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) |
447 | goto out_unlock; | 454 | goto out_unlock; |
448 | radio = bcm43xx_current_radio(bcm); | 455 | radio = bcm43xx_current_radio(bcm); |
@@ -466,7 +473,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, | |||
466 | err = 0; | 473 | err = 0; |
467 | 474 | ||
468 | out_unlock: | 475 | out_unlock: |
469 | bcm43xx_unlock_irqsafe(bcm, flags); | 476 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
477 | mutex_unlock(&bcm->mutex); | ||
470 | 478 | ||
471 | return err; | 479 | return err; |
472 | } | 480 | } |
@@ -478,10 +486,9 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, | |||
478 | { | 486 | { |
479 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 487 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
480 | struct bcm43xx_radioinfo *radio; | 488 | struct bcm43xx_radioinfo *radio; |
481 | unsigned long flags; | ||
482 | int err = -ENODEV; | 489 | int err = -ENODEV; |
483 | 490 | ||
484 | bcm43xx_lock_irqsafe(bcm, flags); | 491 | mutex_lock(&bcm->mutex); |
485 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) | 492 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) |
486 | goto out_unlock; | 493 | goto out_unlock; |
487 | radio = bcm43xx_current_radio(bcm); | 494 | radio = bcm43xx_current_radio(bcm); |
@@ -493,7 +500,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, | |||
493 | 500 | ||
494 | err = 0; | 501 | err = 0; |
495 | out_unlock: | 502 | out_unlock: |
496 | bcm43xx_unlock_irqsafe(bcm, flags); | 503 | mutex_unlock(&bcm->mutex); |
497 | 504 | ||
498 | return err; | 505 | return err; |
499 | } | 506 | } |
@@ -580,7 +587,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, | |||
580 | return -EINVAL; | 587 | return -EINVAL; |
581 | } | 588 | } |
582 | 589 | ||
583 | bcm43xx_lock_irqsafe(bcm, flags); | 590 | mutex_lock(&bcm->mutex); |
591 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
584 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { | 592 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { |
585 | err = bcm43xx_radio_set_interference_mitigation(bcm, mode); | 593 | err = bcm43xx_radio_set_interference_mitigation(bcm, mode); |
586 | if (err) { | 594 | if (err) { |
@@ -595,7 +603,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, | |||
595 | } else | 603 | } else |
596 | bcm43xx_current_radio(bcm)->interfmode = mode; | 604 | bcm43xx_current_radio(bcm)->interfmode = mode; |
597 | } | 605 | } |
598 | bcm43xx_unlock_irqsafe(bcm, flags); | 606 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
607 | mutex_unlock(&bcm->mutex); | ||
599 | 608 | ||
600 | return err; | 609 | return err; |
601 | } | 610 | } |
@@ -606,12 +615,11 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, | |||
606 | char *extra) | 615 | char *extra) |
607 | { | 616 | { |
608 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 617 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
609 | unsigned long flags; | ||
610 | int mode; | 618 | int mode; |
611 | 619 | ||
612 | bcm43xx_lock_irqsafe(bcm, flags); | 620 | mutex_lock(&bcm->mutex); |
613 | mode = bcm43xx_current_radio(bcm)->interfmode; | 621 | mode = bcm43xx_current_radio(bcm)->interfmode; |
614 | bcm43xx_unlock_irqsafe(bcm, flags); | 622 | mutex_unlock(&bcm->mutex); |
615 | 623 | ||
616 | switch (mode) { | 624 | switch (mode) { |
617 | case BCM43xx_RADIO_INTERFMODE_NONE: | 625 | case BCM43xx_RADIO_INTERFMODE_NONE: |
@@ -641,9 +649,11 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, | |||
641 | int on; | 649 | int on; |
642 | 650 | ||
643 | on = *((int *)extra); | 651 | on = *((int *)extra); |
644 | bcm43xx_lock_irqsafe(bcm, flags); | 652 | mutex_lock(&bcm->mutex); |
653 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
645 | bcm->short_preamble = !!on; | 654 | bcm->short_preamble = !!on; |
646 | bcm43xx_unlock_irqsafe(bcm, flags); | 655 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
656 | mutex_unlock(&bcm->mutex); | ||
647 | 657 | ||
648 | return 0; | 658 | return 0; |
649 | } | 659 | } |
@@ -654,12 +664,11 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, | |||
654 | char *extra) | 664 | char *extra) |
655 | { | 665 | { |
656 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 666 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
657 | unsigned long flags; | ||
658 | int on; | 667 | int on; |
659 | 668 | ||
660 | bcm43xx_lock_irqsafe(bcm, flags); | 669 | mutex_lock(&bcm->mutex); |
661 | on = bcm->short_preamble; | 670 | on = bcm->short_preamble; |
662 | bcm43xx_unlock_irqsafe(bcm, flags); | 671 | mutex_unlock(&bcm->mutex); |
663 | 672 | ||
664 | if (on) | 673 | if (on) |
665 | strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); | 674 | strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); |
@@ -681,11 +690,13 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, | |||
681 | 690 | ||
682 | on = *((int *)extra); | 691 | on = *((int *)extra); |
683 | 692 | ||
684 | bcm43xx_lock_irqsafe(bcm, flags); | 693 | mutex_lock(&bcm->mutex); |
694 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
685 | bcm->ieee->host_encrypt = !!on; | 695 | bcm->ieee->host_encrypt = !!on; |
686 | bcm->ieee->host_decrypt = !!on; | 696 | bcm->ieee->host_decrypt = !!on; |
687 | bcm->ieee->host_build_iv = !on; | 697 | bcm->ieee->host_build_iv = !on; |
688 | bcm43xx_unlock_irqsafe(bcm, flags); | 698 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
699 | mutex_unlock(&bcm->mutex); | ||
689 | 700 | ||
690 | return 0; | 701 | return 0; |
691 | } | 702 | } |
@@ -696,12 +707,11 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, | |||
696 | char *extra) | 707 | char *extra) |
697 | { | 708 | { |
698 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 709 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
699 | unsigned long flags; | ||
700 | int on; | 710 | int on; |
701 | 711 | ||
702 | bcm43xx_lock_irqsafe(bcm, flags); | 712 | mutex_lock(&bcm->mutex); |
703 | on = bcm->ieee->host_encrypt; | 713 | on = bcm->ieee->host_encrypt; |
704 | bcm43xx_unlock_irqsafe(bcm, flags); | 714 | mutex_unlock(&bcm->mutex); |
705 | 715 | ||
706 | if (on) | 716 | if (on) |
707 | strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); | 717 | strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); |
@@ -764,11 +774,13 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, | |||
764 | if (!sprom) | 774 | if (!sprom) |
765 | goto out; | 775 | goto out; |
766 | 776 | ||
767 | bcm43xx_lock_irqsafe(bcm, flags); | 777 | mutex_lock(&bcm->mutex); |
778 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
768 | err = -ENODEV; | 779 | err = -ENODEV; |
769 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) | 780 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) |
770 | err = bcm43xx_sprom_read(bcm, sprom); | 781 | err = bcm43xx_sprom_read(bcm, sprom); |
771 | bcm43xx_unlock_irqsafe(bcm, flags); | 782 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
783 | mutex_unlock(&bcm->mutex); | ||
772 | if (!err) | 784 | if (!err) |
773 | data->data.length = sprom2hex(sprom, extra); | 785 | data->data.length = sprom2hex(sprom, extra); |
774 | kfree(sprom); | 786 | kfree(sprom); |
@@ -809,11 +821,15 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, | |||
809 | if (err) | 821 | if (err) |
810 | goto out_kfree; | 822 | goto out_kfree; |
811 | 823 | ||
812 | bcm43xx_lock_irqsafe(bcm, flags); | 824 | mutex_lock(&bcm->mutex); |
825 | spin_lock_irqsave(&bcm->irq_lock, flags); | ||
826 | spin_lock(&bcm->leds_lock); | ||
813 | err = -ENODEV; | 827 | err = -ENODEV; |
814 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) | 828 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) |
815 | err = bcm43xx_sprom_write(bcm, sprom); | 829 | err = bcm43xx_sprom_write(bcm, sprom); |
816 | bcm43xx_unlock_irqsafe(bcm, flags); | 830 | spin_unlock(&bcm->leds_lock); |
831 | spin_unlock_irqrestore(&bcm->irq_lock, flags); | ||
832 | mutex_unlock(&bcm->mutex); | ||
817 | out_kfree: | 833 | out_kfree: |
818 | kfree(sprom); | 834 | kfree(sprom); |
819 | out: | 835 | out: |
@@ -827,6 +843,9 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d | |||
827 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 843 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
828 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 844 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
829 | struct iw_statistics *wstats; | 845 | struct iw_statistics *wstats; |
846 | struct ieee80211_network *network = NULL; | ||
847 | static int tmp_level = 0; | ||
848 | unsigned long flags; | ||
830 | 849 | ||
831 | wstats = &bcm->stats.wstats; | 850 | wstats = &bcm->stats.wstats; |
832 | if (!mac->associated) { | 851 | if (!mac->associated) { |
@@ -844,16 +863,25 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d | |||
844 | wstats->qual.level = 0; | 863 | wstats->qual.level = 0; |
845 | wstats->qual.noise = 0; | 864 | wstats->qual.noise = 0; |
846 | wstats->qual.updated = 7; | 865 | wstats->qual.updated = 7; |
847 | wstats->qual.updated |= IW_QUAL_NOISE_INVALID | | 866 | wstats->qual.updated |= IW_QUAL_ALL_UPDATED; |
848 | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; | ||
849 | return wstats; | 867 | return wstats; |
850 | } | 868 | } |
851 | /* fill in the real statistics when iface associated */ | 869 | /* fill in the real statistics when iface associated */ |
852 | wstats->qual.qual = 100; // TODO: get the real signal quality | 870 | spin_lock_irqsave(&mac->ieee->lock, flags); |
853 | wstats->qual.level = 3 - bcm->stats.link_quality; | 871 | list_for_each_entry(network, &mac->ieee->network_list, list) { |
872 | if (!memcmp(mac->associnfo.bssid, network->bssid, ETH_ALEN)) { | ||
873 | if (!tmp_level) /* get initial value */ | ||
874 | tmp_level = network->stats.rssi; | ||
875 | else /* smooth results */ | ||
876 | tmp_level = (7 * tmp_level + network->stats.rssi)/8; | ||
877 | break; | ||
878 | } | ||
879 | } | ||
880 | spin_unlock_irqrestore(&mac->ieee->lock, flags); | ||
881 | wstats->qual.level = tmp_level; | ||
882 | wstats->qual.qual = 100 + tmp_level - RX_POWER_MAX; // TODO: get the real signal quality | ||
854 | wstats->qual.noise = bcm->stats.noise; | 883 | wstats->qual.noise = bcm->stats.noise; |
855 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | | 884 | wstats->qual.updated = IW_QUAL_ALL_UPDATED; |
856 | IW_QUAL_NOISE_UPDATED; | ||
857 | wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; | 885 | wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; |
858 | wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; | 886 | wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; |
859 | wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; | 887 | wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index b3300ffe4eec..758459e72f3d 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -2667,7 +2667,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv) | |||
2667 | 2667 | ||
2668 | IPW_DEBUG_FW(">> :\n"); | 2668 | IPW_DEBUG_FW(">> :\n"); |
2669 | 2669 | ||
2670 | //set the Stop and Abort bit | 2670 | /* set the Stop and Abort bit */ |
2671 | control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; | 2671 | control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; |
2672 | ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control); | 2672 | ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control); |
2673 | priv->sram_desc.last_cb_index = 0; | 2673 | priv->sram_desc.last_cb_index = 0; |
@@ -3002,8 +3002,6 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) | |||
3002 | if (rc < 0) | 3002 | if (rc < 0) |
3003 | return rc; | 3003 | return rc; |
3004 | 3004 | ||
3005 | // spin_lock_irqsave(&priv->lock, flags); | ||
3006 | |||
3007 | for (addr = IPW_SHARED_LOWER_BOUND; | 3005 | for (addr = IPW_SHARED_LOWER_BOUND; |
3008 | addr < IPW_REGISTER_DOMAIN1_END; addr += 4) { | 3006 | addr < IPW_REGISTER_DOMAIN1_END; addr += 4) { |
3009 | ipw_write32(priv, addr, 0); | 3007 | ipw_write32(priv, addr, 0); |
@@ -3097,8 +3095,6 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) | |||
3097 | firmware have problem getting alive resp. */ | 3095 | firmware have problem getting alive resp. */ |
3098 | ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0); | 3096 | ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0); |
3099 | 3097 | ||
3100 | // spin_unlock_irqrestore(&priv->lock, flags); | ||
3101 | |||
3102 | return rc; | 3098 | return rc; |
3103 | } | 3099 | } |
3104 | 3100 | ||
@@ -6387,13 +6383,6 @@ static int ipw_wx_set_genie(struct net_device *dev, | |||
6387 | (wrqu->data.length && extra == NULL)) | 6383 | (wrqu->data.length && extra == NULL)) |
6388 | return -EINVAL; | 6384 | return -EINVAL; |
6389 | 6385 | ||
6390 | //mutex_lock(&priv->mutex); | ||
6391 | |||
6392 | //if (!ieee->wpa_enabled) { | ||
6393 | // err = -EOPNOTSUPP; | ||
6394 | // goto out; | ||
6395 | //} | ||
6396 | |||
6397 | if (wrqu->data.length) { | 6386 | if (wrqu->data.length) { |
6398 | buf = kmalloc(wrqu->data.length, GFP_KERNEL); | 6387 | buf = kmalloc(wrqu->data.length, GFP_KERNEL); |
6399 | if (buf == NULL) { | 6388 | if (buf == NULL) { |
@@ -6413,7 +6402,6 @@ static int ipw_wx_set_genie(struct net_device *dev, | |||
6413 | 6402 | ||
6414 | ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); | 6403 | ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); |
6415 | out: | 6404 | out: |
6416 | //mutex_unlock(&priv->mutex); | ||
6417 | return err; | 6405 | return err; |
6418 | } | 6406 | } |
6419 | 6407 | ||
@@ -6426,13 +6414,6 @@ static int ipw_wx_get_genie(struct net_device *dev, | |||
6426 | struct ieee80211_device *ieee = priv->ieee; | 6414 | struct ieee80211_device *ieee = priv->ieee; |
6427 | int err = 0; | 6415 | int err = 0; |
6428 | 6416 | ||
6429 | //mutex_lock(&priv->mutex); | ||
6430 | |||
6431 | //if (!ieee->wpa_enabled) { | ||
6432 | // err = -EOPNOTSUPP; | ||
6433 | // goto out; | ||
6434 | //} | ||
6435 | |||
6436 | if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { | 6417 | if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { |
6437 | wrqu->data.length = 0; | 6418 | wrqu->data.length = 0; |
6438 | goto out; | 6419 | goto out; |
@@ -6447,7 +6428,6 @@ static int ipw_wx_get_genie(struct net_device *dev, | |||
6447 | memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); | 6428 | memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); |
6448 | 6429 | ||
6449 | out: | 6430 | out: |
6450 | //mutex_unlock(&priv->mutex); | ||
6451 | return err; | 6431 | return err; |
6452 | } | 6432 | } |
6453 | 6433 | ||
@@ -6558,7 +6538,6 @@ static int ipw_wx_set_auth(struct net_device *dev, | |||
6558 | ieee->ieee802_1x = param->value; | 6538 | ieee->ieee802_1x = param->value; |
6559 | break; | 6539 | break; |
6560 | 6540 | ||
6561 | //case IW_AUTH_ROAMING_CONTROL: | ||
6562 | case IW_AUTH_PRIVACY_INVOKED: | 6541 | case IW_AUTH_PRIVACY_INVOKED: |
6563 | ieee->privacy_invoked = param->value; | 6542 | ieee->privacy_invoked = param->value; |
6564 | break; | 6543 | break; |
@@ -6680,7 +6659,7 @@ static int ipw_wx_set_mlme(struct net_device *dev, | |||
6680 | 6659 | ||
6681 | switch (mlme->cmd) { | 6660 | switch (mlme->cmd) { |
6682 | case IW_MLME_DEAUTH: | 6661 | case IW_MLME_DEAUTH: |
6683 | // silently ignore | 6662 | /* silently ignore */ |
6684 | break; | 6663 | break; |
6685 | 6664 | ||
6686 | case IW_MLME_DISASSOC: | 6665 | case IW_MLME_DISASSOC: |
@@ -9766,7 +9745,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, | |||
9766 | return 0; | 9745 | return 0; |
9767 | } | 9746 | } |
9768 | 9747 | ||
9769 | #endif // CONFIG_IPW2200_MONITOR | 9748 | #endif /* CONFIG_IPW2200_MONITOR */ |
9770 | 9749 | ||
9771 | static int ipw_wx_reset(struct net_device *dev, | 9750 | static int ipw_wx_reset(struct net_device *dev, |
9772 | struct iw_request_info *info, | 9751 | struct iw_request_info *info, |
@@ -10009,7 +9988,7 @@ static void init_sys_config(struct ipw_sys_config *sys_config) | |||
10009 | sys_config->dot11g_auto_detection = 0; | 9988 | sys_config->dot11g_auto_detection = 0; |
10010 | sys_config->enable_cts_to_self = 0; | 9989 | sys_config->enable_cts_to_self = 0; |
10011 | sys_config->bt_coexist_collision_thr = 0; | 9990 | sys_config->bt_coexist_collision_thr = 0; |
10012 | sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 | 9991 | sys_config->pass_noise_stats_to_host = 1; /* 1 -- fix for 256 */ |
10013 | sys_config->silence_threshold = 0x1e; | 9992 | sys_config->silence_threshold = 0x1e; |
10014 | } | 9993 | } |
10015 | 9994 | ||
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 989599ad33ef..0c30fe7e8f7f 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -35,10 +35,14 @@ | |||
35 | 35 | ||
36 | #include <net/iw_handler.h> /* New driver API */ | 36 | #include <net/iw_handler.h> /* New driver API */ |
37 | 37 | ||
38 | #define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */ | ||
39 | #define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */ | ||
40 | /* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */ | ||
41 | #define KEY_SIZE_TKIP 32 /* TKIP keys */ | ||
38 | 42 | ||
39 | static void prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, | 43 | static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, |
40 | u8 *wpa_ie, size_t wpa_ie_len); | 44 | u8 *wpa_ie, size_t wpa_ie_len); |
41 | static size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie); | 45 | static size_t prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie); |
42 | static int prism54_set_wpa(struct net_device *, struct iw_request_info *, | 46 | static int prism54_set_wpa(struct net_device *, struct iw_request_info *, |
43 | __u32 *, char *); | 47 | __u32 *, char *); |
44 | 48 | ||
@@ -468,6 +472,9 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info, | |||
468 | range->event_capa[1] = IW_EVENT_CAPA_K_1; | 472 | range->event_capa[1] = IW_EVENT_CAPA_K_1; |
469 | range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM); | 473 | range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM); |
470 | 474 | ||
475 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | ||
476 | IW_ENC_CAPA_CIPHER_TKIP; | ||
477 | |||
471 | if (islpci_get_state(priv) < PRV_STATE_INIT) | 478 | if (islpci_get_state(priv) < PRV_STATE_INIT) |
472 | return 0; | 479 | return 0; |
473 | 480 | ||
@@ -567,6 +574,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
567 | struct iw_event iwe; /* Temporary buffer */ | 574 | struct iw_event iwe; /* Temporary buffer */ |
568 | short cap; | 575 | short cap; |
569 | islpci_private *priv = netdev_priv(ndev); | 576 | islpci_private *priv = netdev_priv(ndev); |
577 | u8 wpa_ie[MAX_WPA_IE_LEN]; | ||
578 | size_t wpa_ie_len; | ||
570 | 579 | ||
571 | /* The first entry must be the MAC address */ | 580 | /* The first entry must be the MAC address */ |
572 | memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); | 581 | memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); |
@@ -627,27 +636,13 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
627 | current_ev = | 636 | current_ev = |
628 | iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); | 637 | iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); |
629 | 638 | ||
630 | if (priv->wpa) { | 639 | /* Add WPA/RSN Information Element, if any */ |
631 | u8 wpa_ie[MAX_WPA_IE_LEN]; | 640 | wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie); |
632 | char *buf, *p; | 641 | if (wpa_ie_len > 0) { |
633 | size_t wpa_ie_len; | 642 | iwe.cmd = IWEVGENIE; |
634 | int i; | 643 | iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN); |
635 | 644 | current_ev = iwe_stream_add_point(current_ev, end_buf, | |
636 | wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie); | 645 | &iwe, wpa_ie); |
637 | if (wpa_ie_len > 0 && | ||
638 | (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) { | ||
639 | p = buf; | ||
640 | p += sprintf(p, "wpa_ie="); | ||
641 | for (i = 0; i < wpa_ie_len; i++) { | ||
642 | p += sprintf(p, "%02x", wpa_ie[i]); | ||
643 | } | ||
644 | memset(&iwe, 0, sizeof (iwe)); | ||
645 | iwe.cmd = IWEVCUSTOM; | ||
646 | iwe.u.data.length = strlen(buf); | ||
647 | current_ev = iwe_stream_add_point(current_ev, end_buf, | ||
648 | &iwe, buf); | ||
649 | kfree(buf); | ||
650 | } | ||
651 | } | 646 | } |
652 | return current_ev; | 647 | return current_ev; |
653 | } | 648 | } |
@@ -1051,12 +1046,24 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info, | |||
1051 | current_index = r.u; | 1046 | current_index = r.u; |
1052 | /* Verify that the key is not marked as invalid */ | 1047 | /* Verify that the key is not marked as invalid */ |
1053 | if (!(dwrq->flags & IW_ENCODE_NOKEY)) { | 1048 | if (!(dwrq->flags & IW_ENCODE_NOKEY)) { |
1054 | key.length = dwrq->length > sizeof (key.key) ? | 1049 | if (dwrq->length > KEY_SIZE_TKIP) { |
1055 | sizeof (key.key) : dwrq->length; | 1050 | /* User-provided key data too big */ |
1056 | memcpy(key.key, extra, key.length); | 1051 | return -EINVAL; |
1057 | if (key.length == 32) | 1052 | } |
1058 | /* we want WPA-PSK */ | 1053 | if (dwrq->length > KEY_SIZE_WEP104) { |
1054 | /* WPA-PSK TKIP */ | ||
1059 | key.type = DOT11_PRIV_TKIP; | 1055 | key.type = DOT11_PRIV_TKIP; |
1056 | key.length = KEY_SIZE_TKIP; | ||
1057 | } else if (dwrq->length > KEY_SIZE_WEP40) { | ||
1058 | /* WEP 104/128 */ | ||
1059 | key.length = KEY_SIZE_WEP104; | ||
1060 | } else { | ||
1061 | /* WEP 40/64 */ | ||
1062 | key.length = KEY_SIZE_WEP40; | ||
1063 | } | ||
1064 | memset(key.key, 0, sizeof (key.key)); | ||
1065 | memcpy(key.key, extra, dwrq->length); | ||
1066 | |||
1060 | if ((index < 0) || (index > 3)) | 1067 | if ((index < 0) || (index > 3)) |
1061 | /* no index provided use the current one */ | 1068 | /* no index provided use the current one */ |
1062 | index = current_index; | 1069 | index = current_index; |
@@ -1210,6 +1217,489 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info, | |||
1210 | } | 1217 | } |
1211 | } | 1218 | } |
1212 | 1219 | ||
1220 | static int prism54_set_genie(struct net_device *ndev, | ||
1221 | struct iw_request_info *info, | ||
1222 | struct iw_point *data, char *extra) | ||
1223 | { | ||
1224 | islpci_private *priv = netdev_priv(ndev); | ||
1225 | int alen, ret = 0; | ||
1226 | struct obj_attachment *attach; | ||
1227 | |||
1228 | if (data->length > MAX_WPA_IE_LEN || | ||
1229 | (data->length && extra == NULL)) | ||
1230 | return -EINVAL; | ||
1231 | |||
1232 | memcpy(priv->wpa_ie, extra, data->length); | ||
1233 | priv->wpa_ie_len = data->length; | ||
1234 | |||
1235 | alen = sizeof(*attach) + priv->wpa_ie_len; | ||
1236 | attach = kzalloc(alen, GFP_KERNEL); | ||
1237 | if (attach == NULL) | ||
1238 | return -ENOMEM; | ||
1239 | |||
1240 | #define WLAN_FC_TYPE_MGMT 0 | ||
1241 | #define WLAN_FC_STYPE_ASSOC_REQ 0 | ||
1242 | #define WLAN_FC_STYPE_REASSOC_REQ 2 | ||
1243 | |||
1244 | /* Note: endianness is covered by mgt_set_varlen */ | ||
1245 | attach->type = (WLAN_FC_TYPE_MGMT << 2) | | ||
1246 | (WLAN_FC_STYPE_ASSOC_REQ << 4); | ||
1247 | attach->id = -1; | ||
1248 | attach->size = priv->wpa_ie_len; | ||
1249 | memcpy(attach->data, extra, priv->wpa_ie_len); | ||
1250 | |||
1251 | ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, | ||
1252 | priv->wpa_ie_len); | ||
1253 | if (ret == 0) { | ||
1254 | attach->type = (WLAN_FC_TYPE_MGMT << 2) | | ||
1255 | (WLAN_FC_STYPE_REASSOC_REQ << 4); | ||
1256 | |||
1257 | ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, | ||
1258 | priv->wpa_ie_len); | ||
1259 | if (ret == 0) | ||
1260 | printk(KERN_DEBUG "%s: WPA IE Attachment was set\n", | ||
1261 | ndev->name); | ||
1262 | } | ||
1263 | |||
1264 | kfree(attach); | ||
1265 | return ret; | ||
1266 | } | ||
1267 | |||
1268 | |||
1269 | static int prism54_get_genie(struct net_device *ndev, | ||
1270 | struct iw_request_info *info, | ||
1271 | struct iw_point *data, char *extra) | ||
1272 | { | ||
1273 | islpci_private *priv = netdev_priv(ndev); | ||
1274 | int len = priv->wpa_ie_len; | ||
1275 | |||
1276 | if (len <= 0) { | ||
1277 | data->length = 0; | ||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1281 | if (data->length < len) | ||
1282 | return -E2BIG; | ||
1283 | |||
1284 | data->length = len; | ||
1285 | memcpy(extra, priv->wpa_ie, len); | ||
1286 | |||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | static int prism54_set_auth(struct net_device *ndev, | ||
1291 | struct iw_request_info *info, | ||
1292 | union iwreq_data *wrqu, char *extra) | ||
1293 | { | ||
1294 | islpci_private *priv = netdev_priv(ndev); | ||
1295 | struct iw_param *param = &wrqu->param; | ||
1296 | u32 mlmelevel = 0, authen = 0, dot1x = 0; | ||
1297 | u32 exunencrypt = 0, privinvoked = 0, wpa = 0; | ||
1298 | u32 old_wpa; | ||
1299 | int ret = 0; | ||
1300 | union oid_res_t r; | ||
1301 | |||
1302 | if (islpci_get_state(priv) < PRV_STATE_INIT) | ||
1303 | return 0; | ||
1304 | |||
1305 | /* first get the flags */ | ||
1306 | down_write(&priv->mib_sem); | ||
1307 | wpa = old_wpa = priv->wpa; | ||
1308 | up_write(&priv->mib_sem); | ||
1309 | ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); | ||
1310 | authen = r.u; | ||
1311 | ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); | ||
1312 | privinvoked = r.u; | ||
1313 | ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); | ||
1314 | exunencrypt = r.u; | ||
1315 | ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r); | ||
1316 | dot1x = r.u; | ||
1317 | ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r); | ||
1318 | mlmelevel = r.u; | ||
1319 | |||
1320 | if (ret < 0) | ||
1321 | goto out; | ||
1322 | |||
1323 | switch (param->flags & IW_AUTH_INDEX) { | ||
1324 | case IW_AUTH_CIPHER_PAIRWISE: | ||
1325 | case IW_AUTH_CIPHER_GROUP: | ||
1326 | case IW_AUTH_KEY_MGMT: | ||
1327 | break; | ||
1328 | |||
1329 | case IW_AUTH_WPA_ENABLED: | ||
1330 | /* Do the same thing as IW_AUTH_WPA_VERSION */ | ||
1331 | if (param->value) { | ||
1332 | wpa = 1; | ||
1333 | privinvoked = 1; /* For privacy invoked */ | ||
1334 | exunencrypt = 1; /* Filter out all unencrypted frames */ | ||
1335 | dot1x = 0x01; /* To enable eap filter */ | ||
1336 | mlmelevel = DOT11_MLME_EXTENDED; | ||
1337 | authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */ | ||
1338 | } else { | ||
1339 | wpa = 0; | ||
1340 | privinvoked = 0; | ||
1341 | exunencrypt = 0; /* Do not filter un-encrypted data */ | ||
1342 | dot1x = 0; | ||
1343 | mlmelevel = DOT11_MLME_AUTO; | ||
1344 | } | ||
1345 | break; | ||
1346 | |||
1347 | case IW_AUTH_WPA_VERSION: | ||
1348 | if (param->value & IW_AUTH_WPA_VERSION_DISABLED) { | ||
1349 | wpa = 0; | ||
1350 | privinvoked = 0; | ||
1351 | exunencrypt = 0; /* Do not filter un-encrypted data */ | ||
1352 | dot1x = 0; | ||
1353 | mlmelevel = DOT11_MLME_AUTO; | ||
1354 | } else { | ||
1355 | if (param->value & IW_AUTH_WPA_VERSION_WPA) | ||
1356 | wpa = 1; | ||
1357 | else if (param->value & IW_AUTH_WPA_VERSION_WPA2) | ||
1358 | wpa = 2; | ||
1359 | privinvoked = 1; /* For privacy invoked */ | ||
1360 | exunencrypt = 1; /* Filter out all unencrypted frames */ | ||
1361 | dot1x = 0x01; /* To enable eap filter */ | ||
1362 | mlmelevel = DOT11_MLME_EXTENDED; | ||
1363 | authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */ | ||
1364 | } | ||
1365 | break; | ||
1366 | |||
1367 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: | ||
1368 | dot1x = param->value ? 1 : 0; | ||
1369 | break; | ||
1370 | |||
1371 | case IW_AUTH_PRIVACY_INVOKED: | ||
1372 | privinvoked = param->value ? 1 : 0; | ||
1373 | |||
1374 | case IW_AUTH_DROP_UNENCRYPTED: | ||
1375 | exunencrypt = param->value ? 1 : 0; | ||
1376 | break; | ||
1377 | |||
1378 | case IW_AUTH_80211_AUTH_ALG: | ||
1379 | if (param->value & IW_AUTH_ALG_SHARED_KEY) { | ||
1380 | /* Only WEP uses _SK and _BOTH */ | ||
1381 | if (wpa > 0) { | ||
1382 | ret = -EINVAL; | ||
1383 | goto out; | ||
1384 | } | ||
1385 | authen = DOT11_AUTH_SK; | ||
1386 | } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { | ||
1387 | authen = DOT11_AUTH_OS; | ||
1388 | } else { | ||
1389 | ret = -EINVAL; | ||
1390 | goto out; | ||
1391 | } | ||
1392 | break; | ||
1393 | |||
1394 | default: | ||
1395 | return -EOPNOTSUPP; | ||
1396 | } | ||
1397 | |||
1398 | /* Set all the values */ | ||
1399 | down_write(&priv->mib_sem); | ||
1400 | priv->wpa = wpa; | ||
1401 | up_write(&priv->mib_sem); | ||
1402 | mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen); | ||
1403 | mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked); | ||
1404 | mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt); | ||
1405 | mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x); | ||
1406 | mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel); | ||
1407 | |||
1408 | out: | ||
1409 | return ret; | ||
1410 | } | ||
1411 | |||
1412 | static int prism54_get_auth(struct net_device *ndev, | ||
1413 | struct iw_request_info *info, | ||
1414 | union iwreq_data *wrqu, char *extra) | ||
1415 | { | ||
1416 | islpci_private *priv = netdev_priv(ndev); | ||
1417 | struct iw_param *param = &wrqu->param; | ||
1418 | u32 wpa = 0; | ||
1419 | int ret = 0; | ||
1420 | union oid_res_t r; | ||
1421 | |||
1422 | if (islpci_get_state(priv) < PRV_STATE_INIT) | ||
1423 | return 0; | ||
1424 | |||
1425 | /* first get the flags */ | ||
1426 | down_write(&priv->mib_sem); | ||
1427 | wpa = priv->wpa; | ||
1428 | up_write(&priv->mib_sem); | ||
1429 | |||
1430 | switch (param->flags & IW_AUTH_INDEX) { | ||
1431 | case IW_AUTH_CIPHER_PAIRWISE: | ||
1432 | case IW_AUTH_CIPHER_GROUP: | ||
1433 | case IW_AUTH_KEY_MGMT: | ||
1434 | /* | ||
1435 | * wpa_supplicant will control these internally | ||
1436 | */ | ||
1437 | ret = -EOPNOTSUPP; | ||
1438 | break; | ||
1439 | |||
1440 | case IW_AUTH_WPA_VERSION: | ||
1441 | switch (wpa) { | ||
1442 | case 1: | ||
1443 | param->value = IW_AUTH_WPA_VERSION_WPA; | ||
1444 | break; | ||
1445 | case 2: | ||
1446 | param->value = IW_AUTH_WPA_VERSION_WPA2; | ||
1447 | break; | ||
1448 | case 0: | ||
1449 | default: | ||
1450 | param->value = IW_AUTH_WPA_VERSION_DISABLED; | ||
1451 | break; | ||
1452 | } | ||
1453 | break; | ||
1454 | |||
1455 | case IW_AUTH_DROP_UNENCRYPTED: | ||
1456 | ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); | ||
1457 | if (ret >= 0) | ||
1458 | param->value = r.u > 0 ? 1 : 0; | ||
1459 | break; | ||
1460 | |||
1461 | case IW_AUTH_80211_AUTH_ALG: | ||
1462 | ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); | ||
1463 | if (ret >= 0) { | ||
1464 | switch (r.u) { | ||
1465 | case DOT11_AUTH_OS: | ||
1466 | param->value = IW_AUTH_ALG_OPEN_SYSTEM; | ||
1467 | break; | ||
1468 | case DOT11_AUTH_BOTH: | ||
1469 | case DOT11_AUTH_SK: | ||
1470 | param->value = IW_AUTH_ALG_SHARED_KEY; | ||
1471 | case DOT11_AUTH_NONE: | ||
1472 | default: | ||
1473 | param->value = 0; | ||
1474 | break; | ||
1475 | } | ||
1476 | } | ||
1477 | break; | ||
1478 | |||
1479 | case IW_AUTH_WPA_ENABLED: | ||
1480 | param->value = wpa > 0 ? 1 : 0; | ||
1481 | break; | ||
1482 | |||
1483 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: | ||
1484 | ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r); | ||
1485 | if (ret >= 0) | ||
1486 | param->value = r.u > 0 ? 1 : 0; | ||
1487 | break; | ||
1488 | |||
1489 | case IW_AUTH_PRIVACY_INVOKED: | ||
1490 | ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); | ||
1491 | if (ret >= 0) | ||
1492 | param->value = r.u > 0 ? 1 : 0; | ||
1493 | break; | ||
1494 | |||
1495 | default: | ||
1496 | return -EOPNOTSUPP; | ||
1497 | } | ||
1498 | return ret; | ||
1499 | } | ||
1500 | |||
1501 | static int prism54_set_encodeext(struct net_device *ndev, | ||
1502 | struct iw_request_info *info, | ||
1503 | union iwreq_data *wrqu, | ||
1504 | char *extra) | ||
1505 | { | ||
1506 | islpci_private *priv = netdev_priv(ndev); | ||
1507 | struct iw_point *encoding = &wrqu->encoding; | ||
1508 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | ||
1509 | int idx, alg = ext->alg, set_key = 1; | ||
1510 | union oid_res_t r; | ||
1511 | int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0; | ||
1512 | int ret = 0; | ||
1513 | |||
1514 | if (islpci_get_state(priv) < PRV_STATE_INIT) | ||
1515 | return 0; | ||
1516 | |||
1517 | /* Determine and validate the key index */ | ||
1518 | idx = (encoding->flags & IW_ENCODE_INDEX) - 1; | ||
1519 | if (idx) { | ||
1520 | if (idx < 0 || idx > 3) | ||
1521 | return -EINVAL; | ||
1522 | } else { | ||
1523 | ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); | ||
1524 | if (ret < 0) | ||
1525 | goto out; | ||
1526 | idx = r.u; | ||
1527 | } | ||
1528 | |||
1529 | if (encoding->flags & IW_ENCODE_DISABLED) | ||
1530 | alg = IW_ENCODE_ALG_NONE; | ||
1531 | |||
1532 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { | ||
1533 | /* Only set transmit key index here, actual | ||
1534 | * key is set below if needed. | ||
1535 | */ | ||
1536 | ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx); | ||
1537 | set_key = ext->key_len > 0 ? 1 : 0; | ||
1538 | } | ||
1539 | |||
1540 | if (set_key) { | ||
1541 | struct obj_key key = { DOT11_PRIV_WEP, 0, "" }; | ||
1542 | switch (alg) { | ||
1543 | case IW_ENCODE_ALG_NONE: | ||
1544 | break; | ||
1545 | case IW_ENCODE_ALG_WEP: | ||
1546 | if (ext->key_len > KEY_SIZE_WEP104) { | ||
1547 | ret = -EINVAL; | ||
1548 | goto out; | ||
1549 | } | ||
1550 | if (ext->key_len > KEY_SIZE_WEP40) | ||
1551 | key.length = KEY_SIZE_WEP104; | ||
1552 | else | ||
1553 | key.length = KEY_SIZE_WEP40; | ||
1554 | break; | ||
1555 | case IW_ENCODE_ALG_TKIP: | ||
1556 | if (ext->key_len > KEY_SIZE_TKIP) { | ||
1557 | ret = -EINVAL; | ||
1558 | goto out; | ||
1559 | } | ||
1560 | key.type = DOT11_PRIV_TKIP; | ||
1561 | key.length = KEY_SIZE_TKIP; | ||
1562 | default: | ||
1563 | return -EINVAL; | ||
1564 | } | ||
1565 | |||
1566 | if (key.length) { | ||
1567 | memset(key.key, 0, sizeof(key.key)); | ||
1568 | memcpy(key.key, ext->key, ext->key_len); | ||
1569 | ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx, | ||
1570 | &key); | ||
1571 | if (ret < 0) | ||
1572 | goto out; | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | /* Read the flags */ | ||
1577 | if (encoding->flags & IW_ENCODE_DISABLED) { | ||
1578 | /* Encoding disabled, | ||
1579 | * authen = DOT11_AUTH_OS; | ||
1580 | * invoke = 0; | ||
1581 | * exunencrypt = 0; */ | ||
1582 | } | ||
1583 | if (encoding->flags & IW_ENCODE_OPEN) { | ||
1584 | /* Encode but accept non-encoded packets. No auth */ | ||
1585 | invoke = 1; | ||
1586 | } | ||
1587 | if (encoding->flags & IW_ENCODE_RESTRICTED) { | ||
1588 | /* Refuse non-encoded packets. Auth */ | ||
1589 | authen = DOT11_AUTH_BOTH; | ||
1590 | invoke = 1; | ||
1591 | exunencrypt = 1; | ||
1592 | } | ||
1593 | |||
1594 | /* do the change if requested */ | ||
1595 | if (encoding->flags & IW_ENCODE_MODE) { | ||
1596 | ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, | ||
1597 | &authen); | ||
1598 | ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, | ||
1599 | &invoke); | ||
1600 | ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, | ||
1601 | &exunencrypt); | ||
1602 | } | ||
1603 | |||
1604 | out: | ||
1605 | return ret; | ||
1606 | } | ||
1607 | |||
1608 | |||
1609 | static int prism54_get_encodeext(struct net_device *ndev, | ||
1610 | struct iw_request_info *info, | ||
1611 | union iwreq_data *wrqu, | ||
1612 | char *extra) | ||
1613 | { | ||
1614 | islpci_private *priv = netdev_priv(ndev); | ||
1615 | struct iw_point *encoding = &wrqu->encoding; | ||
1616 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | ||
1617 | int idx, max_key_len; | ||
1618 | union oid_res_t r; | ||
1619 | int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0; | ||
1620 | int ret = 0; | ||
1621 | |||
1622 | if (islpci_get_state(priv) < PRV_STATE_INIT) | ||
1623 | return 0; | ||
1624 | |||
1625 | /* first get the flags */ | ||
1626 | ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); | ||
1627 | authen = r.u; | ||
1628 | ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); | ||
1629 | invoke = r.u; | ||
1630 | ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); | ||
1631 | exunencrypt = r.u; | ||
1632 | if (ret < 0) | ||
1633 | goto out; | ||
1634 | |||
1635 | max_key_len = encoding->length - sizeof(*ext); | ||
1636 | if (max_key_len < 0) | ||
1637 | return -EINVAL; | ||
1638 | |||
1639 | idx = (encoding->flags & IW_ENCODE_INDEX) - 1; | ||
1640 | if (idx) { | ||
1641 | if (idx < 0 || idx > 3) | ||
1642 | return -EINVAL; | ||
1643 | } else { | ||
1644 | ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); | ||
1645 | if (ret < 0) | ||
1646 | goto out; | ||
1647 | idx = r.u; | ||
1648 | } | ||
1649 | |||
1650 | encoding->flags = idx + 1; | ||
1651 | memset(ext, 0, sizeof(*ext)); | ||
1652 | |||
1653 | switch (authen) { | ||
1654 | case DOT11_AUTH_BOTH: | ||
1655 | case DOT11_AUTH_SK: | ||
1656 | wrqu->encoding.flags |= IW_ENCODE_RESTRICTED; | ||
1657 | case DOT11_AUTH_OS: | ||
1658 | default: | ||
1659 | wrqu->encoding.flags |= IW_ENCODE_OPEN; | ||
1660 | break; | ||
1661 | } | ||
1662 | |||
1663 | down_write(&priv->mib_sem); | ||
1664 | wpa = priv->wpa; | ||
1665 | up_write(&priv->mib_sem); | ||
1666 | |||
1667 | if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) { | ||
1668 | /* No encryption */ | ||
1669 | ext->alg = IW_ENCODE_ALG_NONE; | ||
1670 | ext->key_len = 0; | ||
1671 | wrqu->encoding.flags |= IW_ENCODE_DISABLED; | ||
1672 | } else { | ||
1673 | struct obj_key *key; | ||
1674 | |||
1675 | ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r); | ||
1676 | if (ret < 0) | ||
1677 | goto out; | ||
1678 | key = r.ptr; | ||
1679 | if (max_key_len < key->length) { | ||
1680 | ret = -E2BIG; | ||
1681 | goto out; | ||
1682 | } | ||
1683 | memcpy(ext->key, key->key, key->length); | ||
1684 | ext->key_len = key->length; | ||
1685 | |||
1686 | switch (key->type) { | ||
1687 | case DOT11_PRIV_TKIP: | ||
1688 | ext->alg = IW_ENCODE_ALG_TKIP; | ||
1689 | break; | ||
1690 | default: | ||
1691 | case DOT11_PRIV_WEP: | ||
1692 | ext->alg = IW_ENCODE_ALG_WEP; | ||
1693 | break; | ||
1694 | } | ||
1695 | wrqu->encoding.flags |= IW_ENCODE_ENABLED; | ||
1696 | } | ||
1697 | |||
1698 | out: | ||
1699 | return ret; | ||
1700 | } | ||
1701 | |||
1702 | |||
1213 | static int | 1703 | static int |
1214 | prism54_reset(struct net_device *ndev, struct iw_request_info *info, | 1704 | prism54_reset(struct net_device *ndev, struct iw_request_info *info, |
1215 | __u32 * uwrq, char *extra) | 1705 | __u32 * uwrq, char *extra) |
@@ -1591,8 +2081,8 @@ static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 }; | |||
1591 | #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" | 2081 | #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" |
1592 | 2082 | ||
1593 | static void | 2083 | static void |
1594 | prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, | 2084 | prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, |
1595 | u8 *wpa_ie, size_t wpa_ie_len) | 2085 | u8 *wpa_ie, size_t wpa_ie_len) |
1596 | { | 2086 | { |
1597 | struct list_head *ptr; | 2087 | struct list_head *ptr; |
1598 | struct islpci_bss_wpa_ie *bss = NULL; | 2088 | struct islpci_bss_wpa_ie *bss = NULL; |
@@ -1658,7 +2148,7 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, | |||
1658 | } | 2148 | } |
1659 | 2149 | ||
1660 | static size_t | 2150 | static size_t |
1661 | prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) | 2151 | prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) |
1662 | { | 2152 | { |
1663 | struct list_head *ptr; | 2153 | struct list_head *ptr; |
1664 | struct islpci_bss_wpa_ie *bss = NULL; | 2154 | struct islpci_bss_wpa_ie *bss = NULL; |
@@ -1683,14 +2173,14 @@ prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) | |||
1683 | } | 2173 | } |
1684 | 2174 | ||
1685 | void | 2175 | void |
1686 | prism54_wpa_ie_init(islpci_private *priv) | 2176 | prism54_wpa_bss_ie_init(islpci_private *priv) |
1687 | { | 2177 | { |
1688 | INIT_LIST_HEAD(&priv->bss_wpa_list); | 2178 | INIT_LIST_HEAD(&priv->bss_wpa_list); |
1689 | sema_init(&priv->wpa_sem, 1); | 2179 | sema_init(&priv->wpa_sem, 1); |
1690 | } | 2180 | } |
1691 | 2181 | ||
1692 | void | 2182 | void |
1693 | prism54_wpa_ie_clean(islpci_private *priv) | 2183 | prism54_wpa_bss_ie_clean(islpci_private *priv) |
1694 | { | 2184 | { |
1695 | struct list_head *ptr, *n; | 2185 | struct list_head *ptr, *n; |
1696 | 2186 | ||
@@ -1722,7 +2212,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr, | |||
1722 | } | 2212 | } |
1723 | if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 && | 2213 | if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 && |
1724 | memcmp(pos + 2, wpa_oid, 4) == 0) { | 2214 | memcmp(pos + 2, wpa_oid, 4) == 0) { |
1725 | prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2); | 2215 | prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2); |
1726 | return; | 2216 | return; |
1727 | } | 2217 | } |
1728 | pos += 2 + pos[1]; | 2218 | pos += 2 + pos[1]; |
@@ -1879,7 +2369,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, | |||
1879 | send_formatted_event(priv, "Associate request (ex)", mlme, 1); | 2369 | send_formatted_event(priv, "Associate request (ex)", mlme, 1); |
1880 | 2370 | ||
1881 | if (priv->iw_mode != IW_MODE_MASTER | 2371 | if (priv->iw_mode != IW_MODE_MASTER |
1882 | && mlmeex->state != DOT11_STATE_AUTHING) | 2372 | && mlmeex->state != DOT11_STATE_ASSOCING) |
1883 | break; | 2373 | break; |
1884 | 2374 | ||
1885 | confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC); | 2375 | confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC); |
@@ -1893,7 +2383,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, | |||
1893 | confirm->state = 0; /* not used */ | 2383 | confirm->state = 0; /* not used */ |
1894 | confirm->code = 0; | 2384 | confirm->code = 0; |
1895 | 2385 | ||
1896 | wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie); | 2386 | wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie); |
1897 | 2387 | ||
1898 | if (!wpa_ie_len) { | 2388 | if (!wpa_ie_len) { |
1899 | printk(KERN_DEBUG "No WPA IE found from " | 2389 | printk(KERN_DEBUG "No WPA IE found from " |
@@ -1937,7 +2427,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, | |||
1937 | confirm->state = 0; /* not used */ | 2427 | confirm->state = 0; /* not used */ |
1938 | confirm->code = 0; | 2428 | confirm->code = 0; |
1939 | 2429 | ||
1940 | wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie); | 2430 | wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie); |
1941 | 2431 | ||
1942 | if (!wpa_ie_len) { | 2432 | if (!wpa_ie_len) { |
1943 | printk(KERN_DEBUG "No WPA IE found from " | 2433 | printk(KERN_DEBUG "No WPA IE found from " |
@@ -2553,6 +3043,15 @@ static const iw_handler prism54_handler[] = { | |||
2553 | (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */ | 3043 | (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */ |
2554 | (iw_handler) NULL, /* SIOCSIWPOWER */ | 3044 | (iw_handler) NULL, /* SIOCSIWPOWER */ |
2555 | (iw_handler) NULL, /* SIOCGIWPOWER */ | 3045 | (iw_handler) NULL, /* SIOCGIWPOWER */ |
3046 | NULL, /* -- hole -- */ | ||
3047 | NULL, /* -- hole -- */ | ||
3048 | (iw_handler) prism54_set_genie, /* SIOCSIWGENIE */ | ||
3049 | (iw_handler) prism54_get_genie, /* SIOCGIWGENIE */ | ||
3050 | (iw_handler) prism54_set_auth, /* SIOCSIWAUTH */ | ||
3051 | (iw_handler) prism54_get_auth, /* SIOCGIWAUTH */ | ||
3052 | (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */ | ||
3053 | (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */ | ||
3054 | NULL, /* SIOCSIWPMKSA */ | ||
2556 | }; | 3055 | }; |
2557 | 3056 | ||
2558 | /* The low order bit identify a SET (0) or a GET (1) ioctl. */ | 3057 | /* The low order bit identify a SET (0) or a GET (1) ioctl. */ |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h index 46d5cde80c85..65f33acd0a42 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.h +++ b/drivers/net/wireless/prism54/isl_ioctl.h | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #include <net/iw_handler.h> /* New driver API */ | 28 | #include <net/iw_handler.h> /* New driver API */ |
29 | 29 | ||
30 | #define SUPPORTED_WIRELESS_EXT 16 | 30 | #define SUPPORTED_WIRELESS_EXT 19 |
31 | 31 | ||
32 | void prism54_mib_init(islpci_private *); | 32 | void prism54_mib_init(islpci_private *); |
33 | 33 | ||
@@ -39,8 +39,8 @@ void prism54_acl_clean(struct islpci_acl *); | |||
39 | 39 | ||
40 | void prism54_process_trap(void *); | 40 | void prism54_process_trap(void *); |
41 | 41 | ||
42 | void prism54_wpa_ie_init(islpci_private *priv); | 42 | void prism54_wpa_bss_ie_init(islpci_private *priv); |
43 | void prism54_wpa_ie_clean(islpci_private *priv); | 43 | void prism54_wpa_bss_ie_clean(islpci_private *priv); |
44 | 44 | ||
45 | int prism54_set_mac_address(struct net_device *, void *); | 45 | int prism54_set_mac_address(struct net_device *, void *); |
46 | 46 | ||
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 5ddf29599032..ab3c5a27efd9 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -715,7 +715,7 @@ islpci_alloc_memory(islpci_private *priv) | |||
715 | } | 715 | } |
716 | 716 | ||
717 | prism54_acl_init(&priv->acl); | 717 | prism54_acl_init(&priv->acl); |
718 | prism54_wpa_ie_init(priv); | 718 | prism54_wpa_bss_ie_init(priv); |
719 | if (mgt_init(priv)) | 719 | if (mgt_init(priv)) |
720 | goto out_free; | 720 | goto out_free; |
721 | 721 | ||
@@ -774,7 +774,7 @@ islpci_free_memory(islpci_private *priv) | |||
774 | 774 | ||
775 | /* Free the acces control list and the WPA list */ | 775 | /* Free the acces control list and the WPA list */ |
776 | prism54_acl_clean(&priv->acl); | 776 | prism54_acl_clean(&priv->acl); |
777 | prism54_wpa_ie_clean(priv); | 777 | prism54_wpa_bss_ie_clean(priv); |
778 | mgt_clean(priv); | 778 | mgt_clean(priv); |
779 | 779 | ||
780 | return 0; | 780 | return 0; |
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index 07053165e4c5..5049f37455b1 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h | |||
@@ -179,6 +179,8 @@ typedef struct { | |||
179 | struct list_head bss_wpa_list; | 179 | struct list_head bss_wpa_list; |
180 | int num_bss_wpa; | 180 | int num_bss_wpa; |
181 | struct semaphore wpa_sem; | 181 | struct semaphore wpa_sem; |
182 | u8 wpa_ie[MAX_WPA_IE_LEN]; | ||
183 | size_t wpa_ie_len; | ||
182 | 184 | ||
183 | struct work_struct reset_task; | 185 | struct work_struct reset_task; |
184 | int reset_task_pending; | 186 | int reset_task_pending; |
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c index 9df232c2c863..440ef24b5fd1 100644 --- a/drivers/net/wireless/zd1211rw/zd_netdev.c +++ b/drivers/net/wireless/zd1211rw/zd_netdev.c | |||
@@ -72,10 +72,18 @@ static int iw_get_name(struct net_device *netdev, | |||
72 | struct iw_request_info *info, | 72 | struct iw_request_info *info, |
73 | union iwreq_data *req, char *extra) | 73 | union iwreq_data *req, char *extra) |
74 | { | 74 | { |
75 | /* FIXME: check whether 802.11a will also supported, add also | 75 | /* FIXME: check whether 802.11a will also supported */ |
76 | * zd1211B, if we support it. | 76 | strlcpy(req->name, "IEEE 802.11b/g", IFNAMSIZ); |
77 | */ | 77 | return 0; |
78 | strlcpy(req->name, "802.11g zd1211", IFNAMSIZ); | 78 | } |
79 | |||
80 | static int iw_get_nick(struct net_device *netdev, | ||
81 | struct iw_request_info *info, | ||
82 | union iwreq_data *req, char *extra) | ||
83 | { | ||
84 | strcpy(extra, "zd1211"); | ||
85 | req->data.length = strlen(extra) + 1; | ||
86 | req->data.flags = 1; | ||
79 | return 0; | 87 | return 0; |
80 | } | 88 | } |
81 | 89 | ||
@@ -181,6 +189,7 @@ static int iw_get_encodeext(struct net_device *netdev, | |||
181 | 189 | ||
182 | static const iw_handler zd_standard_iw_handlers[] = { | 190 | static const iw_handler zd_standard_iw_handlers[] = { |
183 | WX(SIOCGIWNAME) = iw_get_name, | 191 | WX(SIOCGIWNAME) = iw_get_name, |
192 | WX(SIOCGIWNICKN) = iw_get_nick, | ||
184 | WX(SIOCSIWFREQ) = iw_set_freq, | 193 | WX(SIOCSIWFREQ) = iw_set_freq, |
185 | WX(SIOCGIWFREQ) = iw_get_freq, | 194 | WX(SIOCGIWFREQ) = iw_get_freq, |
186 | WX(SIOCSIWMODE) = iw_set_mode, | 195 | WX(SIOCSIWMODE) = iw_set_mode, |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 6320984126c7..96551da769fc 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -39,9 +39,11 @@ static struct usb_device_id usb_ids[] = { | |||
39 | { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, | 39 | { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, |
40 | { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, | 40 | { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, |
41 | { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 }, | 41 | { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 }, |
42 | { USB_DEVICE(0x079b, 0x004a), .driver_info = DEVICE_ZD1211 }, | ||
42 | /* ZD1211B */ | 43 | /* ZD1211B */ |
43 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, | 44 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, |
44 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, | 45 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, |
46 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, | ||
45 | {} | 47 | {} |
46 | }; | 48 | }; |
47 | 49 | ||