diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2009-04-11 12:25:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:54:45 -0400 |
commit | 7858e07b7ccf1d2fd5898a405c93d022d3f1f42d (patch) | |
tree | eff92b4181f0eef3e9e389dc0cb5ff9798657886 /drivers/net/wireless/b43legacy | |
parent | 7edfab7adef45a09b459cb7f5957f476108f5e77 (diff) |
b43legacy: Fixes for beaconing
This patch ports the beaconing fixes from commit a82d992261f "b43: Beaconing
fixes" to b43legacy. Basically it prevents the card from triggering the beacon
IRQ over and over again.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Acked-by: Michael Buesch <mb@bu3sch.de>
Tested-by: David Ellingsworth <david@identd.dyndns.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43legacy')
-rw-r--r-- | drivers/net/wireless/b43legacy/b43legacy.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 47 |
2 files changed, 43 insertions, 8 deletions
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 4cdde4ad17c0..ad4794a0a327 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -59,7 +59,8 @@ | |||
59 | #define B43legacy_MMIO_XMITSTAT_1 0x174 | 59 | #define B43legacy_MMIO_XMITSTAT_1 0x174 |
60 | #define B43legacy_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ | 60 | #define B43legacy_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ |
61 | #define B43legacy_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ | 61 | #define B43legacy_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ |
62 | 62 | #define B43legacy_MMIO_TSF_CFP_REP 0x188 | |
63 | #define B43legacy_MMIO_TSF_CFP_START 0x18C | ||
63 | /* 32-bit DMA */ | 64 | /* 32-bit DMA */ |
64 | #define B43legacy_MMIO_DMA32_BASE0 0x200 | 65 | #define B43legacy_MMIO_DMA32_BASE0 0x200 |
65 | #define B43legacy_MMIO_DMA32_BASE1 0x220 | 66 | #define B43legacy_MMIO_DMA32_BASE1 0x220 |
@@ -616,6 +617,7 @@ struct b43legacy_wl { | |||
616 | struct sk_buff *current_beacon; | 617 | struct sk_buff *current_beacon; |
617 | bool beacon0_uploaded; | 618 | bool beacon0_uploaded; |
618 | bool beacon1_uploaded; | 619 | bool beacon1_uploaded; |
620 | struct work_struct beacon_update_trigger; | ||
619 | }; | 621 | }; |
620 | 622 | ||
621 | /* Pointers to the firmware data and meta information about it. */ | 623 | /* Pointers to the firmware data and meta information about it. */ |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 81dbbc1c591a..4f3f01629465 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1013,7 +1013,8 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, | |||
1013 | b43legacywarn(dev->wl, "Did not find a valid TIM IE in the " | 1013 | b43legacywarn(dev->wl, "Did not find a valid TIM IE in the " |
1014 | "beacon template packet. AP or IBSS operation " | 1014 | "beacon template packet. AP or IBSS operation " |
1015 | "may be broken.\n"); | 1015 | "may be broken.\n"); |
1016 | } | 1016 | } else |
1017 | b43legacydbg(dev->wl, "Updated beacon template\n"); | ||
1017 | } | 1018 | } |
1018 | 1019 | ||
1019 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | 1020 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, |
@@ -1133,6 +1134,27 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | |||
1133 | kfree(probe_resp_data); | 1134 | kfree(probe_resp_data); |
1134 | } | 1135 | } |
1135 | 1136 | ||
1137 | static void b43legacy_beacon_update_trigger_work(struct work_struct *work) | ||
1138 | { | ||
1139 | struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl, | ||
1140 | beacon_update_trigger); | ||
1141 | struct b43legacy_wldev *dev; | ||
1142 | |||
1143 | mutex_lock(&wl->mutex); | ||
1144 | dev = wl->current_dev; | ||
1145 | if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) { | ||
1146 | /* Force the microcode to trigger the | ||
1147 | * beacon update bottom-half IRQ. */ | ||
1148 | spin_lock_irq(&wl->irq_lock); | ||
1149 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | ||
1150 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) | ||
1151 | | B43legacy_MACCMD_BEACON0_VALID | ||
1152 | | B43legacy_MACCMD_BEACON1_VALID); | ||
1153 | spin_unlock_irq(&wl->irq_lock); | ||
1154 | } | ||
1155 | mutex_unlock(&wl->mutex); | ||
1156 | } | ||
1157 | |||
1136 | /* Asynchronously update the packet templates in template RAM. | 1158 | /* Asynchronously update the packet templates in template RAM. |
1137 | * Locking: Requires wl->irq_lock to be locked. */ | 1159 | * Locking: Requires wl->irq_lock to be locked. */ |
1138 | static void b43legacy_update_templates(struct b43legacy_wl *wl) | 1160 | static void b43legacy_update_templates(struct b43legacy_wl *wl) |
@@ -1156,25 +1178,31 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl) | |||
1156 | wl->current_beacon = beacon; | 1178 | wl->current_beacon = beacon; |
1157 | wl->beacon0_uploaded = 0; | 1179 | wl->beacon0_uploaded = 0; |
1158 | wl->beacon1_uploaded = 0; | 1180 | wl->beacon1_uploaded = 0; |
1181 | queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); | ||
1159 | } | 1182 | } |
1160 | 1183 | ||
1161 | static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, | 1184 | static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, |
1162 | u16 beacon_int) | 1185 | u16 beacon_int) |
1163 | { | 1186 | { |
1164 | b43legacy_time_lock(dev); | 1187 | b43legacy_time_lock(dev); |
1165 | if (dev->dev->id.revision >= 3) | 1188 | if (dev->dev->id.revision >= 3) { |
1166 | b43legacy_write32(dev, 0x188, (beacon_int << 16)); | 1189 | b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_REP, |
1167 | else { | 1190 | (beacon_int << 16)); |
1191 | b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_START, | ||
1192 | (beacon_int << 10)); | ||
1193 | } else { | ||
1168 | b43legacy_write16(dev, 0x606, (beacon_int >> 6)); | 1194 | b43legacy_write16(dev, 0x606, (beacon_int >> 6)); |
1169 | b43legacy_write16(dev, 0x610, beacon_int); | 1195 | b43legacy_write16(dev, 0x610, beacon_int); |
1170 | } | 1196 | } |
1171 | b43legacy_time_unlock(dev); | 1197 | b43legacy_time_unlock(dev); |
1198 | b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int); | ||
1172 | } | 1199 | } |
1173 | 1200 | ||
1174 | static void handle_irq_beacon(struct b43legacy_wldev *dev) | 1201 | static void handle_irq_beacon(struct b43legacy_wldev *dev) |
1175 | { | 1202 | { |
1176 | struct b43legacy_wl *wl = dev->wl; | 1203 | struct b43legacy_wl *wl = dev->wl; |
1177 | u32 cmd; | 1204 | u32 cmd; |
1205 | u32 beacon0_valid, beacon1_valid; | ||
1178 | 1206 | ||
1179 | if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) | 1207 | if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) |
1180 | return; | 1208 | return; |
@@ -1182,7 +1210,11 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) | |||
1182 | /* This is the bottom half of the asynchronous beacon update. */ | 1210 | /* This is the bottom half of the asynchronous beacon update. */ |
1183 | 1211 | ||
1184 | cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | 1212 | cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); |
1185 | if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) { | 1213 | beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID); |
1214 | beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID); | ||
1215 | cmd &= ~(B43legacy_MACCMD_BEACON0_VALID | B43legacy_MACCMD_BEACON1_VALID); | ||
1216 | |||
1217 | if (!beacon0_valid) { | ||
1186 | if (!wl->beacon0_uploaded) { | 1218 | if (!wl->beacon0_uploaded) { |
1187 | b43legacy_write_beacon_template(dev, 0x68, | 1219 | b43legacy_write_beacon_template(dev, 0x68, |
1188 | B43legacy_SHM_SH_BTL0, | 1220 | B43legacy_SHM_SH_BTL0, |
@@ -1193,8 +1225,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) | |||
1193 | wl->beacon0_uploaded = 1; | 1225 | wl->beacon0_uploaded = 1; |
1194 | } | 1226 | } |
1195 | cmd |= B43legacy_MACCMD_BEACON0_VALID; | 1227 | cmd |= B43legacy_MACCMD_BEACON0_VALID; |
1196 | } | 1228 | } else if (!beacon1_valid) { |
1197 | if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) { | ||
1198 | if (!wl->beacon1_uploaded) { | 1229 | if (!wl->beacon1_uploaded) { |
1199 | b43legacy_write_beacon_template(dev, 0x468, | 1230 | b43legacy_write_beacon_template(dev, 0x468, |
1200 | B43legacy_SHM_SH_BTL1, | 1231 | B43legacy_SHM_SH_BTL1, |
@@ -3435,6 +3466,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) | |||
3435 | struct b43legacy_wldev *dev = wl->current_dev; | 3466 | struct b43legacy_wldev *dev = wl->current_dev; |
3436 | 3467 | ||
3437 | b43legacy_rfkill_exit(dev); | 3468 | b43legacy_rfkill_exit(dev); |
3469 | cancel_work_sync(&(wl->beacon_update_trigger)); | ||
3438 | 3470 | ||
3439 | mutex_lock(&wl->mutex); | 3471 | mutex_lock(&wl->mutex); |
3440 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) | 3472 | if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) |
@@ -3766,6 +3798,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3766 | spin_lock_init(&wl->leds_lock); | 3798 | spin_lock_init(&wl->leds_lock); |
3767 | mutex_init(&wl->mutex); | 3799 | mutex_init(&wl->mutex); |
3768 | INIT_LIST_HEAD(&wl->devlist); | 3800 | INIT_LIST_HEAD(&wl->devlist); |
3801 | INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work); | ||
3769 | 3802 | ||
3770 | ssb_set_devtypedata(dev, wl); | 3803 | ssb_set_devtypedata(dev, wl); |
3771 | b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); | 3804 | b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); |