Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / drivers / net / wireless / bcm43xx / bcm43xx.h
index 6d4ea36..2e83083 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef BCM43xx_H_
 #define BCM43xx_H_
 
-#include <linux/hw_random.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #define BCM43xx_PCICFG_ICR             0x94
 
 /* MMIO offsets */
-#define BCM43xx_MMIO_DMA0_REASON       0x20
-#define BCM43xx_MMIO_DMA0_IRQ_MASK     0x24
-#define BCM43xx_MMIO_DMA1_REASON       0x28
-#define BCM43xx_MMIO_DMA1_IRQ_MASK     0x2C
-#define BCM43xx_MMIO_DMA2_REASON       0x30
-#define BCM43xx_MMIO_DMA2_IRQ_MASK     0x34
-#define BCM43xx_MMIO_DMA3_REASON       0x38
-#define BCM43xx_MMIO_DMA3_IRQ_MASK     0x3C
-#define BCM43xx_MMIO_DMA4_REASON       0x40
-#define BCM43xx_MMIO_DMA4_IRQ_MASK     0x44
-#define BCM43xx_MMIO_DMA5_REASON       0x48
-#define BCM43xx_MMIO_DMA5_IRQ_MASK     0x4C
+#define BCM43xx_MMIO_DMA1_REASON       0x20
+#define BCM43xx_MMIO_DMA1_IRQ_MASK     0x24
+#define BCM43xx_MMIO_DMA2_REASON       0x28
+#define BCM43xx_MMIO_DMA2_IRQ_MASK     0x2C
+#define BCM43xx_MMIO_DMA3_REASON       0x30
+#define BCM43xx_MMIO_DMA3_IRQ_MASK     0x34
+#define BCM43xx_MMIO_DMA4_REASON       0x38
+#define BCM43xx_MMIO_DMA4_IRQ_MASK     0x3C
 #define BCM43xx_MMIO_STATUS_BITFIELD   0x120
 #define BCM43xx_MMIO_STATUS2_BITFIELD  0x124
 #define BCM43xx_MMIO_GEN_IRQ_REASON    0x128
 #define BCM43xx_MMIO_XMITSTAT_1                0x174
 #define BCM43xx_MMIO_REV3PLUS_TSF_LOW  0x180 /* core rev >= 3 only */
 #define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
-
-/* 32-bit DMA */
-#define BCM43xx_MMIO_DMA32_BASE0       0x200
-#define BCM43xx_MMIO_DMA32_BASE1       0x220
-#define BCM43xx_MMIO_DMA32_BASE2       0x240
-#define BCM43xx_MMIO_DMA32_BASE3       0x260
-#define BCM43xx_MMIO_DMA32_BASE4       0x280
-#define BCM43xx_MMIO_DMA32_BASE5       0x2A0
-/* 64-bit DMA */
-#define BCM43xx_MMIO_DMA64_BASE0       0x200
-#define BCM43xx_MMIO_DMA64_BASE1       0x240
-#define BCM43xx_MMIO_DMA64_BASE2       0x280
-#define BCM43xx_MMIO_DMA64_BASE3       0x2C0
-#define BCM43xx_MMIO_DMA64_BASE4       0x300
-#define BCM43xx_MMIO_DMA64_BASE5       0x340
-/* PIO */
+#define BCM43xx_MMIO_DMA1_BASE         0x200
+#define BCM43xx_MMIO_DMA2_BASE         0x220
+#define BCM43xx_MMIO_DMA3_BASE         0x240
+#define BCM43xx_MMIO_DMA4_BASE         0x260
 #define BCM43xx_MMIO_PIO1_BASE         0x300
 #define BCM43xx_MMIO_PIO2_BASE         0x310
 #define BCM43xx_MMIO_PIO3_BASE         0x320
 #define BCM43xx_MMIO_PIO4_BASE         0x330
-
 #define BCM43xx_MMIO_PHY_VER           0x3E0
 #define BCM43xx_MMIO_PHY_RADIO         0x3E2
 #define BCM43xx_MMIO_ANTENNA           0x3E8
 #define BCM43xx_MMIO_TSF_1             0x634 /* core rev < 3 only */
 #define BCM43xx_MMIO_TSF_2             0x636 /* core rev < 3 only */
 #define BCM43xx_MMIO_TSF_3             0x638 /* core rev < 3 only */
-#define BCM43xx_MMIO_RNG               0x65A
 #define BCM43xx_MMIO_POWERUP_DELAY     0x6A8
 
 /* SPROM offsets. */
 #define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK  0x20000
 
 /* sbtmstatehigh state flags */
-#define BCM43xx_SBTMSTATEHIGH_SERROR           0x00000001
-#define BCM43xx_SBTMSTATEHIGH_BUSY             0x00000004
-#define BCM43xx_SBTMSTATEHIGH_TIMEOUT          0x00000020
-#define BCM43xx_SBTMSTATEHIGH_COREFLAGS                0x1FFF0000
-#define BCM43xx_SBTMSTATEHIGH_DMA64BIT         0x10000000
-#define BCM43xx_SBTMSTATEHIGH_GATEDCLK         0x20000000
-#define BCM43xx_SBTMSTATEHIGH_BISTFAILED       0x40000000
-#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE     0x80000000
+#define BCM43xx_SBTMSTATEHIGH_SERROR           0x1
+#define BCM43xx_SBTMSTATEHIGH_BUSY             0x4
 
 /* sbimstate flags */
 #define BCM43xx_SBIMSTATE_IB_ERROR             0x20000
 #define BCM43xx_SBF_TIME_UPDATE                0x10000000
 #define BCM43xx_SBF_80000000           0x80000000 /*FIXME: fix name*/
 
-/* Microcode */
-#define BCM43xx_UCODE_REVISION         0x0000
-#define BCM43xx_UCODE_PATCHLEVEL       0x0002
-#define BCM43xx_UCODE_DATE             0x0004
-#define BCM43xx_UCODE_TIME             0x0006
-#define BCM43xx_UCODE_STATUS           0x0040
-
 /* MicrocodeFlagsBitfield (addr + lo-word values?)*/
 #define BCM43xx_UCODEFLAGS_OFFSET      0x005E
 
@@ -534,12 +502,6 @@ struct bcm43xx_phyinfo {
         * This lock is only used by bcm43xx_phy_{un}lock()
         */
        spinlock_t lock;
-
-       /* Firmware. */
-       const struct firmware *ucode;
-       const struct firmware *pcm;
-       const struct firmware *initvals0;
-       const struct firmware *initvals1;
 };
 
 
@@ -604,11 +566,8 @@ struct bcm43xx_dma {
        struct bcm43xx_dmaring *tx_ring1;
        struct bcm43xx_dmaring *tx_ring2;
        struct bcm43xx_dmaring *tx_ring3;
-       struct bcm43xx_dmaring *tx_ring4;
-       struct bcm43xx_dmaring *tx_ring5;
-
        struct bcm43xx_dmaring *rx_ring0;
-       struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
+       struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
 };
 
 /* Data structures for PIO transmission, per 80211 core. */
@@ -632,14 +591,12 @@ struct bcm43xx_coreinfo {
        u8 available:1,
           enabled:1,
           initialized:1;
+       /** core_id ID number */
+       u16 id;
        /** core_rev revision number */
        u8 rev;
        /** Index number for _switch_core() */
        u8 index;
-       /** core_id ID number */
-       u16 id;
-       /** Core-specific data. */
-       void *priv;
 };
 
 /* Additional information for each 80211 core. */
@@ -679,33 +636,6 @@ struct bcm43xx_key {
        u8 algorithm;
 };
 
-/* Driver initialization status. */
-enum {
-       BCM43xx_STAT_UNINIT,            /* Uninitialized. */
-       BCM43xx_STAT_INITIALIZING,      /* init_board() in progress. */
-       BCM43xx_STAT_INITIALIZED,       /* Fully operational. */
-       BCM43xx_STAT_SHUTTINGDOWN,      /* free_board() in progress. */
-       BCM43xx_STAT_RESTARTING,        /* controller_restart() called. */
-};
-#define bcm43xx_status(bcm)            atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat)  do {                    \
-               atomic_set(&(bcm)->init_status, (stat));        \
-               smp_wmb();                                      \
-                                       } while (0)
-
-/*    *** THEORY OF LOCKING ***
- *
- * We have two different locks in the bcm43xx driver.
- * => bcm->mutex:    General sleeping mutex. Protects struct bcm43xx_private
- *                   and the device registers. This mutex does _not_ protect
- *                   against concurrency from the IRQ handler.
- * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
- *
- * Please note that, if you only take the irq_lock, you are not protected
- * against concurrency from the periodic work handlers.
- * Most times you want to take _both_ locks.
- */
-
 struct bcm43xx_private {
        struct ieee80211_device *ieee;
        struct ieee80211softmac_device *softmac;
@@ -715,17 +645,20 @@ struct bcm43xx_private {
        unsigned int irq;
 
        void __iomem *mmio_addr;
+       unsigned int mmio_len;
 
-       spinlock_t irq_lock;
-       struct mutex mutex;
-
-       /* Driver initialization status BCM43xx_STAT_*** */
-       atomic_t init_status;
+       /* Do not use the lock directly. Use the bcm43xx_lock* helper
+        * functions, to be MMIO-safe. */
+       spinlock_t _lock;
 
-       u16 was_initialized:1,          /* for PCI suspend/resume. */
+       /* Driver status flags. */
+       u32 initialized:1,              /* init_board() succeed */
+           was_initialized:1,          /* for PCI suspend/resume. */
+           shutting_down:1,            /* free_board() in progress */
            __using_pio:1,              /* Internal, use bcm43xx_using_pio(). */
            bad_frames_preempt:1,       /* Use "Bad Frames Preemption" (default off) */
            reg124_set_0x4:1,           /* Some variable to keep track of IRQ stuff. */
+           powersaving:1,              /* TRUE if we are in PowerSaving mode. FALSE otherwise. */
            short_preamble:1,           /* TRUE, if short preamble is enabled. */
            firmware_norelease:1;       /* Do not release the firmware. Used on suspend. */
 
@@ -747,7 +680,6 @@ struct bcm43xx_private {
        struct bcm43xx_sprominfo sprom;
 #define BCM43xx_NR_LEDS                4
        struct bcm43xx_led leds[BCM43xx_NR_LEDS];
-       spinlock_t leds_lock;
 
        /* The currently active core. */
        struct bcm43xx_coreinfo *current_core;
@@ -765,6 +697,10 @@ struct bcm43xx_private {
        struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
        /* Additional information, specific to the 80211 cores. */
        struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
+       /* Index of the current 80211 core. If current_core is not
+        * an 80211 core, this is -1.
+        */
+       int current_80211_core_idx;
        /* Number of available 80211 cores. */
        int nr_80211_available;
 
@@ -772,13 +708,11 @@ struct bcm43xx_private {
 
        /* Reason code of the last interrupt. */
        u32 irq_reason;
-       u32 dma_reason[6];
+       u32 dma_reason[4];
        /* saved irq enable/disable state bitfield. */
        u32 irq_savedstate;
        /* Link Quality calculation context. */
        struct bcm43xx_noise_calculation noisecalc;
-       /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
-       int mac_suspended;
 
        /* Threshold values. */
        //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
@@ -788,7 +722,7 @@ struct bcm43xx_private {
        struct tasklet_struct isr_tasklet;
 
        /* Periodic tasks */
-       struct work_struct periodic_work;
+       struct timer_list periodic_tasks;
        unsigned int periodic_state;
 
        struct work_struct restart_work;
@@ -801,9 +735,11 @@ struct bcm43xx_private {
        struct bcm43xx_key key[54];
        u8 default_key_idx;
 
-       /* Random Number Generator. */
-       struct hwrng rng;
-       char rng_name[20 + 1];
+       /* Firmware. */
+       const struct firmware *ucode;
+       const struct firmware *pcm;
+       const struct firmware *initvals0;
+       const struct firmware *initvals1;
 
        /* Debugging stuff follows. */
 #ifdef CONFIG_BCM43XX_DEBUG
@@ -811,6 +747,21 @@ struct bcm43xx_private {
 #endif
 };
 
+/* bcm43xx_(un)lock() protect struct bcm43xx_private.
+ * Note that _NO_ MMIO writes are allowed. If you want to
+ * write to the device through MMIO in the critical section, use
+ * the *_mmio lock functions.
+ * MMIO read-access is allowed, though.
+ */
+#define bcm43xx_lock(bcm, flags)       spin_lock_irqsave(&(bcm)->_lock, flags)
+#define bcm43xx_unlock(bcm, flags)     spin_unlock_irqrestore(&(bcm)->_lock, flags)
+/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO.
+ * MMIO write-access to the device is allowed.
+ * All MMIO writes are flushed on unlock, so it is guaranteed to not
+ * interfere with other threads writing MMIO registers.
+ */
+#define bcm43xx_lock_mmio(bcm, flags)  bcm43xx_lock(bcm, flags)
+#define bcm43xx_unlock_mmio(bcm, flags)        do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0)
 
 static inline
 struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
@@ -863,35 +814,46 @@ int bcm43xx_using_pio(struct bcm43xx_private *bcm)
  * any of these functions.
  */
 static inline
-struct bcm43xx_coreinfo_80211 *
-bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
-{
-       assert(bcm->current_core->id == BCM43xx_COREID_80211);
-       return bcm->current_core->priv;
-}
-static inline
 struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
 {
        assert(bcm43xx_using_pio(bcm));
-       return &(bcm43xx_current_80211_priv(bcm)->pio);
+       assert(bcm->current_80211_core_idx >= 0);
+       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
+       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
 }
 static inline
 struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
 {
        assert(!bcm43xx_using_pio(bcm));
-       return &(bcm43xx_current_80211_priv(bcm)->dma);
+       assert(bcm->current_80211_core_idx >= 0);
+       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
+       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
 }
 static inline
 struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
 {
-       return &(bcm43xx_current_80211_priv(bcm)->phy);
+       assert(bcm->current_80211_core_idx >= 0);
+       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
+       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
 }
 static inline
 struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
 {
-       return &(bcm43xx_current_80211_priv(bcm)->radio);
+       assert(bcm->current_80211_core_idx >= 0);
+       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
+       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
 }
 
+/* Are we running in init_board() context? */
+static inline
+int bcm43xx_is_initializing(struct bcm43xx_private *bcm)
+{
+       if (bcm->initialized)
+               return 0;
+       if (bcm->shutting_down)
+               return 0;
+       return 1;
+}
 
 static inline
 struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,