diff options
Diffstat (limited to 'drivers/net/wireless/bcm43xx/bcm43xx.h')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index e66fdb1f3cfd..d8f917c21ea4 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -636,6 +636,17 @@ struct bcm43xx_key { | |||
636 | u8 algorithm; | 636 | u8 algorithm; |
637 | }; | 637 | }; |
638 | 638 | ||
639 | /* Driver initialization status. */ | ||
640 | enum { | ||
641 | BCM43xx_STAT_UNINIT, /* Uninitialized. */ | ||
642 | BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */ | ||
643 | BCM43xx_STAT_INITIALIZED, /* Fully operational. */ | ||
644 | BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */ | ||
645 | BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ | ||
646 | }; | ||
647 | #define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) | ||
648 | #define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) | ||
649 | |||
639 | struct bcm43xx_private { | 650 | struct bcm43xx_private { |
640 | struct ieee80211_device *ieee; | 651 | struct ieee80211_device *ieee; |
641 | struct ieee80211softmac_device *softmac; | 652 | struct ieee80211softmac_device *softmac; |
@@ -646,18 +657,17 @@ struct bcm43xx_private { | |||
646 | 657 | ||
647 | void __iomem *mmio_addr; | 658 | void __iomem *mmio_addr; |
648 | 659 | ||
649 | /* Do not use the lock directly. Use the bcm43xx_lock* helper | 660 | /* Locking, see "theory of locking" text below. */ |
650 | * functions, to be MMIO-safe. */ | 661 | spinlock_t irq_lock; |
651 | spinlock_t _lock; | 662 | struct mutex mutex; |
652 | 663 | ||
653 | /* Driver status flags. */ | 664 | /* Driver initialization status BCM43xx_STAT_*** */ |
654 | u32 initialized:1, /* init_board() succeed */ | 665 | atomic_t init_status; |
655 | was_initialized:1, /* for PCI suspend/resume. */ | 666 | |
656 | shutting_down:1, /* free_board() in progress */ | 667 | u16 was_initialized:1, /* for PCI suspend/resume. */ |
657 | __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ | 668 | __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ |
658 | bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ | 669 | bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ |
659 | reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ | 670 | reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ |
660 | powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */ | ||
661 | short_preamble:1, /* TRUE, if short preamble is enabled. */ | 671 | short_preamble:1, /* TRUE, if short preamble is enabled. */ |
662 | firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ | 672 | firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ |
663 | 673 | ||
@@ -721,7 +731,7 @@ struct bcm43xx_private { | |||
721 | struct tasklet_struct isr_tasklet; | 731 | struct tasklet_struct isr_tasklet; |
722 | 732 | ||
723 | /* Periodic tasks */ | 733 | /* Periodic tasks */ |
724 | struct timer_list periodic_tasks; | 734 | struct work_struct periodic_work; |
725 | unsigned int periodic_state; | 735 | unsigned int periodic_state; |
726 | 736 | ||
727 | struct work_struct restart_work; | 737 | struct work_struct restart_work; |
@@ -746,21 +756,55 @@ struct bcm43xx_private { | |||
746 | #endif | 756 | #endif |
747 | }; | 757 | }; |
748 | 758 | ||
749 | /* bcm43xx_(un)lock() protect struct bcm43xx_private. | 759 | |
750 | * Note that _NO_ MMIO writes are allowed. If you want to | 760 | /* *** THEORY OF LOCKING *** |
751 | * write to the device through MMIO in the critical section, use | 761 | * |
752 | * the *_mmio lock functions. | 762 | * We have two different locks in the bcm43xx driver. |
753 | * MMIO read-access is allowed, though. | 763 | * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private |
754 | */ | 764 | * and the device registers. |
755 | #define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) | 765 | * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. |
756 | #define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) | 766 | * |
757 | /* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. | 767 | * We have three types of helper function pairs to utilize these locks. |
758 | * MMIO write-access to the device is allowed. | 768 | * (Always use the helper functions.) |
759 | * All MMIO writes are flushed on unlock, so it is guaranteed to not | 769 | * 1) bcm43xx_{un}lock_noirq(): |
760 | * interfere with other threads writing MMIO registers. | 770 | * Takes bcm->mutex. Does _not_ protect against IRQ concurrency, |
771 | * so it is almost always unsafe, if device IRQs are enabled. | ||
772 | * So only use this, if device IRQs are masked. | ||
773 | * Locking may sleep. | ||
774 | * You can sleep within the critical section. | ||
775 | * 2) bcm43xx_{un}lock_irqonly(): | ||
776 | * Takes bcm->irq_lock. Does _not_ protect against | ||
777 | * bcm43xx_lock_noirq() critical sections. | ||
778 | * Does only protect against the IRQ handler path and other | ||
779 | * irqonly() critical sections. | ||
780 | * Locking does not sleep. | ||
781 | * You must not sleep within the critical section. | ||
782 | * 3) bcm43xx_{un}lock_irqsafe(): | ||
783 | * This is the cummulative lock and takes both, mutex and irq_lock. | ||
784 | * Protects against noirq() and irqonly() critical sections (and | ||
785 | * the IRQ handler path). | ||
786 | * Locking may sleep. | ||
787 | * You must not sleep within the critical section. | ||
761 | */ | 788 | */ |
762 | #define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) | 789 | |
763 | #define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) | 790 | /* Lock type 1 */ |
791 | #define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex) | ||
792 | #define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex) | ||
793 | /* Lock type 2 */ | ||
794 | #define bcm43xx_lock_irqonly(bcm, flags) \ | ||
795 | spin_lock_irqsave(&(bcm)->irq_lock, flags) | ||
796 | #define bcm43xx_unlock_irqonly(bcm, flags) \ | ||
797 | spin_unlock_irqrestore(&(bcm)->irq_lock, flags) | ||
798 | /* Lock type 3 */ | ||
799 | #define bcm43xx_lock_irqsafe(bcm, flags) do { \ | ||
800 | bcm43xx_lock_noirq(bcm); \ | ||
801 | bcm43xx_lock_irqonly(bcm, flags); \ | ||
802 | } while (0) | ||
803 | #define bcm43xx_unlock_irqsafe(bcm, flags) do { \ | ||
804 | bcm43xx_unlock_irqonly(bcm, flags); \ | ||
805 | bcm43xx_unlock_noirq(bcm); \ | ||
806 | } while (0) | ||
807 | |||
764 | 808 | ||
765 | static inline | 809 | static inline |
766 | struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) | 810 | struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) |
@@ -843,16 +887,6 @@ struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) | |||
843 | return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); | 887 | return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); |
844 | } | 888 | } |
845 | 889 | ||
846 | /* Are we running in init_board() context? */ | ||
847 | static inline | ||
848 | int bcm43xx_is_initializing(struct bcm43xx_private *bcm) | ||
849 | { | ||
850 | if (bcm->initialized) | ||
851 | return 0; | ||
852 | if (bcm->shutting_down) | ||
853 | return 0; | ||
854 | return 1; | ||
855 | } | ||
856 | 890 | ||
857 | static inline | 891 | static inline |
858 | struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, | 892 | struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, |