aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-12-26 12:26:17 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:45 -0500
commit280d0e16bcbf5893505a0d0897f3ca1ddc0764fa (patch)
treeefa557090ba744de7736c1c6576bf4a67c11795c /drivers/net/wireless/b43/main.c
parentd4df6f1a9edb80c99913548467397617ccee7855 (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.c42
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
255static inline 255static 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
268u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) 267u32 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);
290out:
291 spin_unlock_irqrestore(&wl->shm_lock, flags);
288 292
289 return ret; 293 return ret;
290} 294}
291 295
292u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) 296u16 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);
316out:
317 spin_unlock_irqrestore(&wl->shm_lock, flags);
309 318
310 return ret; 319 return ret;
311} 320}
312 321
313void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) 322void 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);
343out:
344 spin_unlock_irqrestore(&wl->shm_lock, flags);
334} 345}
335 346
336void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) 347void 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);
365out:
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