diff options
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 86 |
1 files changed, 69 insertions, 17 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 704dd3551fff..9d2eb273b726 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev, | |||
373 | b43_write32(dev, B43_MMIO_SHM_CONTROL, control); | 373 | b43_write32(dev, B43_MMIO_SHM_CONTROL, control); |
374 | } | 374 | } |
375 | 375 | ||
376 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) | 376 | u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) |
377 | { | 377 | { |
378 | struct b43_wl *wl = dev->wl; | ||
379 | unsigned long flags; | ||
380 | u32 ret; | 378 | u32 ret; |
381 | 379 | ||
382 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
383 | if (routing == B43_SHM_SHARED) { | 380 | if (routing == B43_SHM_SHARED) { |
384 | B43_WARN_ON(offset & 0x0001); | 381 | B43_WARN_ON(offset & 0x0001); |
385 | if (offset & 0x0003) { | 382 | if (offset & 0x0003) { |
@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) | |||
397 | b43_shm_control_word(dev, routing, offset); | 394 | b43_shm_control_word(dev, routing, offset); |
398 | ret = b43_read32(dev, B43_MMIO_SHM_DATA); | 395 | ret = b43_read32(dev, B43_MMIO_SHM_DATA); |
399 | out: | 396 | out: |
400 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
401 | |||
402 | return ret; | 397 | return ret; |
403 | } | 398 | } |
404 | 399 | ||
405 | u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) | 400 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) |
406 | { | 401 | { |
407 | struct b43_wl *wl = dev->wl; | 402 | struct b43_wl *wl = dev->wl; |
408 | unsigned long flags; | 403 | unsigned long flags; |
409 | u16 ret; | 404 | u32 ret; |
410 | 405 | ||
411 | spin_lock_irqsave(&wl->shm_lock, flags); | 406 | spin_lock_irqsave(&wl->shm_lock, flags); |
407 | ret = __b43_shm_read32(dev, routing, offset); | ||
408 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
409 | |||
410 | return ret; | ||
411 | } | ||
412 | |||
413 | u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset) | ||
414 | { | ||
415 | u16 ret; | ||
416 | |||
412 | if (routing == B43_SHM_SHARED) { | 417 | if (routing == B43_SHM_SHARED) { |
413 | B43_WARN_ON(offset & 0x0001); | 418 | B43_WARN_ON(offset & 0x0001); |
414 | if (offset & 0x0003) { | 419 | if (offset & 0x0003) { |
@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) | |||
423 | b43_shm_control_word(dev, routing, offset); | 428 | b43_shm_control_word(dev, routing, offset); |
424 | ret = b43_read16(dev, B43_MMIO_SHM_DATA); | 429 | ret = b43_read16(dev, B43_MMIO_SHM_DATA); |
425 | out: | 430 | out: |
426 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
427 | |||
428 | return ret; | 431 | return ret; |
429 | } | 432 | } |
430 | 433 | ||
431 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | 434 | u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset) |
432 | { | 435 | { |
433 | struct b43_wl *wl = dev->wl; | 436 | struct b43_wl *wl = dev->wl; |
434 | unsigned long flags; | 437 | unsigned long flags; |
438 | u16 ret; | ||
435 | 439 | ||
436 | spin_lock_irqsave(&wl->shm_lock, flags); | 440 | spin_lock_irqsave(&wl->shm_lock, flags); |
441 | ret = __b43_shm_read16(dev, routing, offset); | ||
442 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
443 | |||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | ||
448 | { | ||
437 | if (routing == B43_SHM_SHARED) { | 449 | if (routing == B43_SHM_SHARED) { |
438 | B43_WARN_ON(offset & 0x0001); | 450 | B43_WARN_ON(offset & 0x0001); |
439 | if (offset & 0x0003) { | 451 | if (offset & 0x0003) { |
@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | |||
443 | (value >> 16) & 0xffff); | 455 | (value >> 16) & 0xffff); |
444 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); | 456 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); |
445 | b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); | 457 | b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); |
446 | goto out; | 458 | return; |
447 | } | 459 | } |
448 | offset >>= 2; | 460 | offset >>= 2; |
449 | } | 461 | } |
450 | b43_shm_control_word(dev, routing, offset); | 462 | b43_shm_control_word(dev, routing, offset); |
451 | b43_write32(dev, B43_MMIO_SHM_DATA, value); | 463 | b43_write32(dev, B43_MMIO_SHM_DATA, value); |
452 | out: | ||
453 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
454 | } | 464 | } |
455 | 465 | ||
456 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | 466 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) |
457 | { | 467 | { |
458 | struct b43_wl *wl = dev->wl; | 468 | struct b43_wl *wl = dev->wl; |
459 | unsigned long flags; | 469 | unsigned long flags; |
460 | 470 | ||
461 | spin_lock_irqsave(&wl->shm_lock, flags); | 471 | spin_lock_irqsave(&wl->shm_lock, flags); |
472 | __b43_shm_write32(dev, routing, offset, value); | ||
473 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
474 | } | ||
475 | |||
476 | void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | ||
477 | { | ||
462 | if (routing == B43_SHM_SHARED) { | 478 | if (routing == B43_SHM_SHARED) { |
463 | B43_WARN_ON(offset & 0x0001); | 479 | B43_WARN_ON(offset & 0x0001); |
464 | if (offset & 0x0003) { | 480 | if (offset & 0x0003) { |
465 | /* Unaligned access */ | 481 | /* Unaligned access */ |
466 | b43_shm_control_word(dev, routing, offset >> 2); | 482 | b43_shm_control_word(dev, routing, offset >> 2); |
467 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); | 483 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); |
468 | goto out; | 484 | return; |
469 | } | 485 | } |
470 | offset >>= 2; | 486 | offset >>= 2; |
471 | } | 487 | } |
472 | b43_shm_control_word(dev, routing, offset); | 488 | b43_shm_control_word(dev, routing, offset); |
473 | b43_write16(dev, B43_MMIO_SHM_DATA, value); | 489 | b43_write16(dev, B43_MMIO_SHM_DATA, value); |
474 | out: | 490 | } |
491 | |||
492 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | ||
493 | { | ||
494 | struct b43_wl *wl = dev->wl; | ||
495 | unsigned long flags; | ||
496 | |||
497 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
498 | __b43_shm_write16(dev, routing, offset, value); | ||
475 | spin_unlock_irqrestore(&wl->shm_lock, flags); | 499 | spin_unlock_irqrestore(&wl->shm_lock, flags); |
476 | } | 500 | } |
477 | 501 | ||
@@ -2463,6 +2487,19 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) | |||
2463 | /* http://bcm-specs.sipsolutions.net/EnableMac */ | 2487 | /* http://bcm-specs.sipsolutions.net/EnableMac */ |
2464 | void b43_mac_enable(struct b43_wldev *dev) | 2488 | void b43_mac_enable(struct b43_wldev *dev) |
2465 | { | 2489 | { |
2490 | if (b43_debug(dev, B43_DBG_FIRMWARE)) { | ||
2491 | u16 fwstate; | ||
2492 | |||
2493 | fwstate = b43_shm_read16(dev, B43_SHM_SHARED, | ||
2494 | B43_SHM_SH_UCODESTAT); | ||
2495 | if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) && | ||
2496 | (fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) { | ||
2497 | b43err(dev->wl, "b43_mac_enable(): The firmware " | ||
2498 | "should be suspended, but current state is %u\n", | ||
2499 | fwstate); | ||
2500 | } | ||
2501 | } | ||
2502 | |||
2466 | dev->mac_suspended--; | 2503 | dev->mac_suspended--; |
2467 | B43_WARN_ON(dev->mac_suspended < 0); | 2504 | B43_WARN_ON(dev->mac_suspended < 0); |
2468 | if (dev->mac_suspended == 0) { | 2505 | if (dev->mac_suspended == 0) { |
@@ -2783,6 +2820,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev) | |||
2783 | static void b43_periodic_every15sec(struct b43_wldev *dev) | 2820 | static void b43_periodic_every15sec(struct b43_wldev *dev) |
2784 | { | 2821 | { |
2785 | struct b43_phy *phy = &dev->phy; | 2822 | struct b43_phy *phy = &dev->phy; |
2823 | u16 wdr; | ||
2824 | |||
2825 | if (dev->fw.opensource) { | ||
2826 | /* Check if the firmware is still alive. | ||
2827 | * It will reset the watchdog counter to 0 in its idle loop. */ | ||
2828 | wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG); | ||
2829 | if (unlikely(wdr)) { | ||
2830 | b43err(dev->wl, "Firmware watchdog: The firmware died!\n"); | ||
2831 | b43_controller_restart(dev, "Firmware watchdog"); | ||
2832 | return; | ||
2833 | } else { | ||
2834 | b43_shm_write16(dev, B43_SHM_SCRATCH, | ||
2835 | B43_WATCHDOG_REG, 1); | ||
2836 | } | ||
2837 | } | ||
2786 | 2838 | ||
2787 | if (phy->type == B43_PHYTYPE_G) { | 2839 | if (phy->type == B43_PHYTYPE_G) { |
2788 | //TODO: update_aci_moving_average | 2840 | //TODO: update_aci_moving_average |