diff options
author | Michael Buesch <mb@bu3sch.de> | 2007-12-26 12:26:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:09:45 -0500 |
commit | 280d0e16bcbf5893505a0d0897f3ca1ddc0764fa (patch) | |
tree | efa557090ba744de7736c1c6576bf4a67c11795c /drivers/net/wireless/b43/main.c | |
parent | d4df6f1a9edb80c99913548467397617ccee7855 (diff) |
b43: Put multicast frames on the mcast queue
This queues frames flagged as "send after DTIM" by mac80211
on the special multicast queue. The firmware will take care
to send the packet after the DTIM.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 84b291144c37..345ac3862e11 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -252,13 +252,12 @@ static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val) | |||
252 | b43_write32(dev, B43_MMIO_RAM_DATA, val); | 252 | b43_write32(dev, B43_MMIO_RAM_DATA, val); |
253 | } | 253 | } |
254 | 254 | ||
255 | static inline | 255 | static inline void b43_shm_control_word(struct b43_wldev *dev, |
256 | void b43_shm_control_word(struct b43_wldev *dev, u16 routing, u16 offset) | 256 | u16 routing, u16 offset) |
257 | { | 257 | { |
258 | u32 control; | 258 | u32 control; |
259 | 259 | ||
260 | /* "offset" is the WORD offset. */ | 260 | /* "offset" is the WORD offset. */ |
261 | |||
262 | control = routing; | 261 | control = routing; |
263 | control <<= 16; | 262 | control <<= 16; |
264 | control |= offset; | 263 | control |= offset; |
@@ -267,8 +266,11 @@ static inline | |||
267 | 266 | ||
268 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) | 267 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) |
269 | { | 268 | { |
269 | struct b43_wl *wl = dev->wl; | ||
270 | unsigned long flags; | ||
270 | u32 ret; | 271 | u32 ret; |
271 | 272 | ||
273 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
272 | if (routing == B43_SHM_SHARED) { | 274 | if (routing == B43_SHM_SHARED) { |
273 | B43_WARN_ON(offset & 0x0001); | 275 | B43_WARN_ON(offset & 0x0001); |
274 | if (offset & 0x0003) { | 276 | if (offset & 0x0003) { |
@@ -279,20 +281,25 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) | |||
279 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); | 281 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); |
280 | ret |= b43_read16(dev, B43_MMIO_SHM_DATA); | 282 | ret |= b43_read16(dev, B43_MMIO_SHM_DATA); |
281 | 283 | ||
282 | return ret; | 284 | goto out; |
283 | } | 285 | } |
284 | offset >>= 2; | 286 | offset >>= 2; |
285 | } | 287 | } |
286 | b43_shm_control_word(dev, routing, offset); | 288 | b43_shm_control_word(dev, routing, offset); |
287 | ret = b43_read32(dev, B43_MMIO_SHM_DATA); | 289 | ret = b43_read32(dev, B43_MMIO_SHM_DATA); |
290 | out: | ||
291 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
288 | 292 | ||
289 | return ret; | 293 | return ret; |
290 | } | 294 | } |
291 | 295 | ||
292 | u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) | 296 | u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) |
293 | { | 297 | { |
298 | struct b43_wl *wl = dev->wl; | ||
299 | unsigned long flags; | ||
294 | u16 ret; | 300 | u16 ret; |
295 | 301 | ||
302 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
296 | if (routing == B43_SHM_SHARED) { | 303 | if (routing == B43_SHM_SHARED) { |
297 | B43_WARN_ON(offset & 0x0001); | 304 | B43_WARN_ON(offset & 0x0001); |
298 | if (offset & 0x0003) { | 305 | if (offset & 0x0003) { |
@@ -300,55 +307,63 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) | |||
300 | b43_shm_control_word(dev, routing, offset >> 2); | 307 | b43_shm_control_word(dev, routing, offset >> 2); |
301 | ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED); | 308 | ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED); |
302 | 309 | ||
303 | return ret; | 310 | goto out; |
304 | } | 311 | } |
305 | offset >>= 2; | 312 | offset >>= 2; |
306 | } | 313 | } |
307 | b43_shm_control_word(dev, routing, offset); | 314 | b43_shm_control_word(dev, routing, offset); |
308 | ret = b43_read16(dev, B43_MMIO_SHM_DATA); | 315 | ret = b43_read16(dev, B43_MMIO_SHM_DATA); |
316 | out: | ||
317 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
309 | 318 | ||
310 | return ret; | 319 | return ret; |
311 | } | 320 | } |
312 | 321 | ||
313 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | 322 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) |
314 | { | 323 | { |
324 | struct b43_wl *wl = dev->wl; | ||
325 | unsigned long flags; | ||
326 | |||
327 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
315 | if (routing == B43_SHM_SHARED) { | 328 | if (routing == B43_SHM_SHARED) { |
316 | B43_WARN_ON(offset & 0x0001); | 329 | B43_WARN_ON(offset & 0x0001); |
317 | if (offset & 0x0003) { | 330 | if (offset & 0x0003) { |
318 | /* Unaligned access */ | 331 | /* Unaligned access */ |
319 | b43_shm_control_word(dev, routing, offset >> 2); | 332 | b43_shm_control_word(dev, routing, offset >> 2); |
320 | mmiowb(); | ||
321 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, | 333 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, |
322 | (value >> 16) & 0xffff); | 334 | (value >> 16) & 0xffff); |
323 | mmiowb(); | ||
324 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); | 335 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); |
325 | mmiowb(); | ||
326 | b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); | 336 | b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); |
327 | return; | 337 | goto out; |
328 | } | 338 | } |
329 | offset >>= 2; | 339 | offset >>= 2; |
330 | } | 340 | } |
331 | b43_shm_control_word(dev, routing, offset); | 341 | b43_shm_control_word(dev, routing, offset); |
332 | mmiowb(); | ||
333 | b43_write32(dev, B43_MMIO_SHM_DATA, value); | 342 | b43_write32(dev, B43_MMIO_SHM_DATA, value); |
343 | out: | ||
344 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
334 | } | 345 | } |
335 | 346 | ||
336 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | 347 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) |
337 | { | 348 | { |
349 | struct b43_wl *wl = dev->wl; | ||
350 | unsigned long flags; | ||
351 | |||
352 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
338 | if (routing == B43_SHM_SHARED) { | 353 | if (routing == B43_SHM_SHARED) { |
339 | B43_WARN_ON(offset & 0x0001); | 354 | B43_WARN_ON(offset & 0x0001); |
340 | if (offset & 0x0003) { | 355 | if (offset & 0x0003) { |
341 | /* Unaligned access */ | 356 | /* Unaligned access */ |
342 | b43_shm_control_word(dev, routing, offset >> 2); | 357 | b43_shm_control_word(dev, routing, offset >> 2); |
343 | mmiowb(); | ||
344 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); | 358 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); |
345 | return; | 359 | goto out; |
346 | } | 360 | } |
347 | offset >>= 2; | 361 | offset >>= 2; |
348 | } | 362 | } |
349 | b43_shm_control_word(dev, routing, offset); | 363 | b43_shm_control_word(dev, routing, offset); |
350 | mmiowb(); | ||
351 | b43_write16(dev, B43_MMIO_SHM_DATA, value); | 364 | b43_write16(dev, B43_MMIO_SHM_DATA, value); |
365 | out: | ||
366 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
352 | } | 367 | } |
353 | 368 | ||
354 | /* Read HostFlags */ | 369 | /* Read HostFlags */ |
@@ -3931,6 +3946,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
3931 | wl->hw = hw; | 3946 | wl->hw = hw; |
3932 | spin_lock_init(&wl->irq_lock); | 3947 | spin_lock_init(&wl->irq_lock); |
3933 | spin_lock_init(&wl->leds_lock); | 3948 | spin_lock_init(&wl->leds_lock); |
3949 | spin_lock_init(&wl->shm_lock); | ||
3934 | mutex_init(&wl->mutex); | 3950 | mutex_init(&wl->mutex); |
3935 | INIT_LIST_HEAD(&wl->devlist); | 3951 | INIT_LIST_HEAD(&wl->devlist); |
3936 | 3952 | ||