This fixes beacon updating in the bottomhalf.
In case the device is busy, we will defer to later in the IRQ handler.

Signed-off-by: Michael Buesch <[EMAIL PROTECTED]>

---

John, this is for 2.6.26 in addition to the beacon patch I sent yesterday.


 drivers/net/wireless/b43/main.c |   98 +++++++++++++++++++++++-----------------
 1 file changed, 57 insertions(+), 41 deletions(-)

Index: wireless-testing/drivers/net/wireless/b43/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/main.c       2008-04-05 
14:09:33.000000000 +0200
+++ wireless-testing/drivers/net/wireless/b43/main.c    2008-04-05 
14:48:01.000000000 +0200
@@ -1445,28 +1445,76 @@ static void b43_write_probe_resp_templat
        b43_write_template_common(dev, probe_resp_data,
                                  size, ram_offset, shm_size_offset,
                                  rate->hw_value);
        kfree(probe_resp_data);
 }
 
+static void handle_irq_beacon(struct b43_wldev *dev)
+{
+       struct b43_wl *wl = dev->wl;
+       u32 cmd, beacon0_valid, beacon1_valid;
+
+       if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
+               return;
+
+       /* This is the bottom half of the asynchronous beacon update. */
+
+       /* Ignore interrupt in the future. */
+       dev->irq_savedstate &= ~B43_IRQ_BEACON;
+
+       cmd = b43_read32(dev, B43_MMIO_MACCMD);
+       beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
+       beacon1_valid = (cmd & B43_MACCMD_BEACON1_VALID);
+
+       /* Schedule interrupt manually, if busy. */
+       if (beacon0_valid && beacon1_valid) {
+               b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
+               dev->irq_savedstate |= B43_IRQ_BEACON;
+               return;
+       }
+
+       if (!beacon0_valid) {
+               if (!wl->beacon0_uploaded) {
+                       b43_write_beacon_template(dev, 0x68, 0x18,
+                                                 B43_CCK_RATE_1MB);
+                       b43_write_probe_resp_template(dev, 0x268, 0x4A,
+                                                     &__b43_ratetable[3]);
+                       wl->beacon0_uploaded = 1;
+               }
+               cmd = b43_read32(dev, B43_MMIO_MACCMD);
+               cmd |= B43_MACCMD_BEACON0_VALID;
+               b43_write32(dev, B43_MMIO_MACCMD, cmd);
+       } else if (!beacon1_valid) {
+               if (!wl->beacon1_uploaded) {
+                       b43_write_beacon_template(dev, 0x468, 0x1A,
+                                                 B43_CCK_RATE_1MB);
+                       wl->beacon1_uploaded = 1;
+               }
+               cmd = b43_read32(dev, B43_MMIO_MACCMD);
+               cmd |= B43_MACCMD_BEACON1_VALID;
+               b43_write32(dev, B43_MMIO_MACCMD, cmd);
+       }
+}
+
 static void b43_beacon_update_trigger_work(struct work_struct *work)
 {
        struct b43_wl *wl = container_of(work, struct b43_wl,
                                         beacon_update_trigger);
        struct b43_wldev *dev;
 
        mutex_lock(&wl->mutex);
        dev = wl->current_dev;
        if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
-               /* Force the microcode to trigger the
-                * beacon update bottom-half IRQ. */
                spin_lock_irq(&wl->irq_lock);
-               b43_write32(dev, B43_MMIO_MACCMD,
-                           b43_read32(dev, B43_MMIO_MACCMD)
-                           | B43_MACCMD_BEACON0_VALID
-                           | B43_MACCMD_BEACON1_VALID);
+               /* update beacon right away or defer to irq */
+               dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+               handle_irq_beacon(dev);
+               /* The handler might have updated the IRQ mask. */
+               b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
+                           dev->irq_savedstate);
+               mmiowb();
                spin_unlock_irq(&wl->irq_lock);
        }
        mutex_unlock(&wl->mutex);
 }
 
 /* Asynchronously update the packet templates in template RAM.
@@ -1517,47 +1565,12 @@ static void b43_set_beacon_int(struct b4
                b43_write16(dev, 0x610, beacon_int);
        }
        b43_time_unlock(dev);
        b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
 }
 
-static void handle_irq_beacon(struct b43_wldev *dev)
-{
-       struct b43_wl *wl = dev->wl;
-       u32 cmd, beacon0_valid, beacon1_valid;
-
-       if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
-               return;
-
-       /* This is the bottom half of the asynchronous beacon update. */
-
-       cmd = b43_read32(dev, B43_MMIO_MACCMD);
-       beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
-       beacon1_valid = (cmd & B43_MACCMD_BEACON1_VALID);
-       cmd &= ~(B43_MACCMD_BEACON0_VALID | B43_MACCMD_BEACON1_VALID);
-
-       if (!beacon0_valid) {
-               if (!wl->beacon0_uploaded) {
-                       b43_write_beacon_template(dev, 0x68, 0x18,
-                                                 B43_CCK_RATE_1MB);
-                       b43_write_probe_resp_template(dev, 0x268, 0x4A,
-                                                     &__b43_ratetable[3]);
-                       wl->beacon0_uploaded = 1;
-               }
-               cmd |= B43_MACCMD_BEACON0_VALID;
-       } else if (!beacon1_valid) {
-               if (!wl->beacon1_uploaded) {
-                       b43_write_beacon_template(dev, 0x468, 0x1A,
-                                                 B43_CCK_RATE_1MB);
-                       wl->beacon1_uploaded = 1;
-               }
-               cmd |= B43_MACCMD_BEACON1_VALID;
-       }
-       b43_write32(dev, B43_MMIO_MACCMD, cmd);
-}
-
 static void handle_irq_ucode_debug(struct b43_wldev *dev)
 {
        //TODO
 }
 
 /* Interrupt handler bottom-half */
Index: wireless-testing/drivers/net/wireless/b43/b43.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/b43/b43.h        2008-04-05 
14:41:57.000000000 +0200
+++ wireless-testing/drivers/net/wireless/b43/b43.h     2008-04-05 
14:45:06.000000000 +0200
@@ -408,13 +408,12 @@ enum {
 #define B43_IRQ_TX_OK                  0x20000000
 #define B43_IRQ_PHY_G_CHANGED          0x40000000
 #define B43_IRQ_TIMEOUT                        0x80000000
 
 #define B43_IRQ_ALL                    0xFFFFFFFF
 #define B43_IRQ_MASKTEMPLATE           (B43_IRQ_MAC_SUSPENDED | \
-                                        B43_IRQ_BEACON | \
                                         B43_IRQ_TBTT_INDI | \
                                         B43_IRQ_ATIM_END | \
                                         B43_IRQ_PMQ | \
                                         B43_IRQ_MAC_TXERR | \
                                         B43_IRQ_PHY_TXERR | \
                                         B43_IRQ_DMA | \
_______________________________________________
Bcm43xx-dev mailing list
Bcm43xx-dev@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to