2009-07-31 18:08:08

by Nick Kossifidis

[permalink] [raw]
Subject: [PATCH 3/4] ath5k: Wakeup fixes

* Don't put chip to full sleep because there are problems during
wakeup. Instead hold MAC/Baseband on warm reset state via a new
function ath5k_hw_on_hold.

* Durring attach preserve pcicfg bits when enabling pci core
sw retry fix.

* Minor cleanups

---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/attach.c | 4 +-
drivers/net/wireless/ath/ath5k/base.c | 44 +++++----
drivers/net/wireless/ath/ath5k/reset.c | 155 +++++++++++++++++++++++--------
4 files changed, 141 insertions(+), 63 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 9137511..1047a6c 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1157,6 +1157,7 @@ extern void ath5k_unregister_leds(struct ath5k_softc *sc);

/* Reset Functions */
extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+extern int ath5k_hw_on_hold(struct ath5k_hw *ah);
extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
/* Power management functions */
extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 6263065..65d438b 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -145,7 +145,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free;

/* Bring device out of sleep and reset it's units */
- ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
+ ret = ath5k_hw_nic_wakeup(ah, 0, true);
if (ret)
goto err_free;

@@ -261,7 +261,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)

/* Enable pci core retry fix on Hainan (5213A) and later chips */
if (srev >= AR5K_SREV_AR5213A)
- ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX);

/*
* Get card capabilities, calibration values etc
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7db32ce..b64731b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2448,27 +2448,29 @@ ath5k_stop_hw(struct ath5k_softc *sc)
ret = ath5k_stop_locked(sc);
if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
/*
- * Set the chip in full sleep mode. Note that we are
- * careful to do this only when bringing the interface
- * completely to a stop. When the chip is in this state
- * it must be carefully woken up or references to
- * registers in the PCI clock domain may freeze the bus
- * (and system). This varies by chip and is mostly an
- * issue with newer parts that go to sleep more quickly.
- */
- if (sc->ah->ah_mac_srev >= 0x78) {
- /*
- * XXX
- * don't put newer MAC revisions > 7.8 to sleep because
- * of the above mentioned problems
- */
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
- "not putting device to sleep\n");
- } else {
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
- "putting device to full sleep\n");
- ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
- }
+ * Don't set the card in full sleep mode!
+ *
+ * a) When the device is in this state it must be carefully
+ * woken up or references to registers in the PCI clock
+ * domain may freeze the bus (and system). This varies
+ * by chip and is mostly an issue with newer parts
+ * (madwifi sources mentioned srev >= 0x78) that go to
+ * sleep more quickly.
+ *
+ * b) On older chips full sleep results a weird behaviour
+ * during wakeup. I tested various cards with srev < 0x78
+ * and they don't wake up after module reload, a second
+ * module reload is needed to bring the card up again.
+ *
+ * Until we figure out what's going on don't enable
+ * full chip reset on any chip (this is what Legacy HAL
+ * and Sam's HAL do anyway). Instead Perform a full reset
+ * on the device (same as initial state after attach) and
+ * leave it idle (keep MAC/BB on warm reset) */
+ ret = ath5k_hw_on_hold(sc->ah);
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+ "putting device to sleep\n");
}
ath5k_txbuf_free(sc, sc->bbuf);

diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 86733fd..34e13c7 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -258,29 +258,35 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
if (!set_chip)
goto commit;

- /* Preserve sleep duration */
data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
+
+ /* If card is down we 'll get 0xffff... so we
+ * need to clean this up before we write the register
+ */
if (data & 0xffc00000)
data = 0;
else
- data = data & 0xfffcffff;
+ /* Preserve sleep duration etc */
+ data = data & ~AR5K_SLEEP_CTL_SLE;

- ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+ ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
+ AR5K_SLEEP_CTL);
udelay(15);

- for (i = 50; i > 0; i--) {
+ for (i = 200; i > 0; i--) {
/* Check if the chip did wake up */
if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
AR5K_PCICFG_SPWR_DN) == 0)
break;

/* Wait a bit and retry */
- udelay(200);
- ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+ udelay(50);
+ ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
+ AR5K_SLEEP_CTL);
}

/* Fail if the chip didn't wake up */
- if (i <= 0)
+ if (i == 0)
return -EIO;

break;
@@ -296,6 +302,64 @@ commit:
}

/*
+ * Put device on hold
+ *
+ * Put MAC and Baseband on warm reset and
+ * keep that state (don't clean sleep control
+ * register). After this MAC and Baseband are
+ * disabled and a full reset is needed to come
+ * back. This way we save as much power as possible
+ * without puting the card on full sleep.
+ */
+int ath5k_hw_on_hold(struct ath5k_hw *ah)
+{
+ struct pci_dev *pdev = ah->ah_sc->pdev;
+ u32 bus_flags;
+ int ret;
+
+ /* Make sure device is awake */
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+ return ret;
+ }
+
+ /*
+ * Put chipset on warm reset...
+ *
+ * Note: puting PCI core on warm reset on PCI-E cards
+ * results card to hang and always return 0xffff... so
+ * we ingore that flag for PCI-E cards. On PCI cards
+ * this flag gets cleared after 64 PCI clocks.
+ */
+ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+ if (ah->ah_version == AR5K_AR5210) {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+ AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+ mdelay(2);
+ } else {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND | bus_flags);
+ }
+
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to put device on warm reset\n");
+ return -EIO;
+ }
+
+ /* ...wakeup again!*/
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to put device on hold\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+/*
* Bring up MAC + PHY Chips and program PLL
* TODO: Half/Quarter rate support
*/
@@ -318,6 +382,50 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return ret;
}

+ /*
+ * Put chipset on warm reset...
+ *
+ * Note: puting PCI core on warm reset on PCI-E cards
+ * results card to hang and always return 0xffff... so
+ * we ingore that flag for PCI-E cards. On PCI cards
+ * this flag gets cleared after 64 PCI clocks.
+ */
+ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+ if (ah->ah_version == AR5K_AR5210) {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+ AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+ mdelay(2);
+ } else {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND | bus_flags);
+ }
+
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+ return -EIO;
+ }
+
+ /* ...wakeup again!...*/
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+ return ret;
+ }
+
+ /* ...clear reset control register and pull device out of
+ * warm reset */
+ if (ath5k_hw_nic_reset(ah, 0)) {
+ ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+ return -EIO;
+ }
+
+ /* On initialization skip PLL programming since we don't have
+ * a channel / mode set yet */
+ if (initial)
+ return 0;
+
if (ah->ah_version != AR5K_AR5210) {
/*
* Get channel mode flags
@@ -383,39 +491,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
AR5K_PHY_TURBO);
}

- /* reseting PCI on PCI-E cards results card to hang
- * and always return 0xffff... so we ingore that flag
- * for PCI-E cards */
- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
-
- /* Reset chipset */
- if (ah->ah_version == AR5K_AR5210) {
- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
- AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
- AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
- mdelay(2);
- } else {
- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
- AR5K_RESET_CTL_BASEBAND | bus_flags);
- }
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
- return -EIO;
- }
-
- /* ...wakeup again!*/
- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
- return ret;
- }
-
- /* ...final warm reset */
- if (ath5k_hw_nic_reset(ah, 0)) {
- ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
- return -EIO;
- }
-
if (ah->ah_version != AR5K_AR5210) {

/* ...update PLL if needed */


2009-07-31 18:15:17

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath5k: Wakeup fixes

T24gRnJpLCBKdWwgMzEsIDIwMDkgYXQgMTE6MDggQU0sIE5pY2sKS29zc2lmaWRpczxtaWNrQG1h
ZHdpZmktcHJvamVjdC5vcmc+IHdyb3RlOgo+IMKgKiBEb24ndCBwdXQgY2hpcCB0byBmdWxsIHNs
ZWVwIGJlY2F1c2UgdGhlcmUgYXJlIHByb2JsZW1zIGR1cmluZwo+IMKgIHdha2V1cC4gSW5zdGVh
ZCBob2xkIE1BQy9CYXNlYmFuZCBvbiB3YXJtIHJlc2V0IHN0YXRlIHZpYSBhIG5ldwo+IMKgIGZ1
bmN0aW9uIGF0aDVrX2h3X29uX2hvbGQuCj4KPiDCoCogRHVycmluZyBhdHRhY2ggcHJlc2VydmUg
cGNpY2ZnIGJpdHMgd2hlbiBlbmFibGluZyBwY2kgY29yZQo+IMKgIHN3IHJldHJ5IGZpeC4KPgo+
IMKgKiBNaW5vciBjbGVhbnVwcwoKQ2FuIHlvdSBhZGRyZXNzIHRoZXNlIGNoYW5nZXMgc2VwYXJh
dGVseT8gSSBzZWUgeW91IHRlbmQgdG8gaXRlbWl6ZQp0aGUgdGhpbmdzIHlvdSBjaGFuZ2UsIGV2
ZW4gd2hlbiB5b3UganVzdCBtYWtlIG9uZSBjaGFuZ2UuIFBsZWFzZQpjb25zaWRlciBhZGRyZXNz
aW5nIG9uZSBjaGFuZ2UgcGVyIGNvbW1pdCBhbmQganVzdCBlbnN1cmUgdGhlIHdoeSBpcwpjcnlz
dGFsIGNsZWFyLgoKICBMdWlzCgo+IC0tLQo+IMKgZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0
aDVrL2F0aDVrLmggwqB8IMKgIMKgMSArCj4gwqBkcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRo
NWsvYXR0YWNoLmMgfCDCoCDCoDQgKy0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1
ay9iYXNlLmMgwqAgfCDCoCA0NCArKysrKy0tLS0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0
aC9hdGg1ay9yZXNldC5jIMKgfCDCoDE1NSArKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0t
Cj4gwqA0IGZpbGVzIGNoYW5nZWQsIDE0MSBpbnNlcnRpb25zKCspLCA2MyBkZWxldGlvbnMoLSkK
Pgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvYXRoNWsuaCBi
L2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9hdGg1ay5oCj4gaW5kZXggOTEzNzUxMS4u
MTA0N2E2YyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvYXRo
NWsuaAo+ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9hdGg1ay5oCj4gQEAg
LTExNTcsNiArMTE1Nyw3IEBAIGV4dGVybiB2b2lkIGF0aDVrX3VucmVnaXN0ZXJfbGVkcyhzdHJ1
Y3QgYXRoNWtfc29mdGMgKnNjKTsKPgo+IMKgLyogUmVzZXQgRnVuY3Rpb25zICovCj4gwqBleHRl
cm4gaW50IGF0aDVrX2h3X25pY193YWtldXAoc3RydWN0IGF0aDVrX2h3ICphaCwgaW50IGZsYWdz
LCBib29sIGluaXRpYWwpOwo+ICtleHRlcm4gaW50IGF0aDVrX2h3X29uX2hvbGQoc3RydWN0IGF0
aDVrX2h3ICphaCk7Cj4gwqBleHRlcm4gaW50IGF0aDVrX2h3X3Jlc2V0KHN0cnVjdCBhdGg1a19o
dyAqYWgsIGVudW0gbmw4MDIxMV9pZnR5cGUgb3BfbW9kZSwgc3RydWN0IGllZWU4MDIxMV9jaGFu
bmVsICpjaGFubmVsLCBib29sIGNoYW5nZV9jaGFubmVsKTsKPiDCoC8qIFBvd2VyIG1hbmFnZW1l
bnQgZnVuY3Rpb25zICovCj4gwqBleHRlcm4gaW50IGF0aDVrX2h3X3NldF9wb3dlcihzdHJ1Y3Qg
YXRoNWtfaHcgKmFoLCBlbnVtIGF0aDVrX3Bvd2VyX21vZGUgbW9kZSwgYm9vbCBzZXRfY2hpcCwg
dTE2IHNsZWVwX2R1cmF0aW9uKTsKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2lyZWxlc3Mv
YXRoL2F0aDVrL2F0dGFjaC5jIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2F0dGFj
aC5jCj4gaW5kZXggNjI2MzA2NS4uNjVkNDM4YiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL25ldC93
aXJlbGVzcy9hdGgvYXRoNWsvYXR0YWNoLmMKPiArKysgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9h
dGgvYXRoNWsvYXR0YWNoLmMKPiBAQCAtMTQ1LDcgKzE0NSw3IEBAIHN0cnVjdCBhdGg1a19odyAq
YXRoNWtfaHdfYXR0YWNoKHN0cnVjdCBhdGg1a19zb2Z0YyAqc2MsIHU4IG1hY192ZXJzaW9uKQo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZ290byBlcnJfZnJlZTsKPgo+IMKgIMKgIMKgIMKgLyog
QnJpbmcgZGV2aWNlIG91dCBvZiBzbGVlcCBhbmQgcmVzZXQgaXQncyB1bml0cyAqLwo+IC0gwqAg
wqAgwqAgcmV0ID0gYXRoNWtfaHdfbmljX3dha2V1cChhaCwgQ0hBTk5FTF9CLCB0cnVlKTsKPiAr
IMKgIMKgIMKgIHJldCA9IGF0aDVrX2h3X25pY193YWtldXAoYWgsIDAsIHRydWUpOwo+IMKgIMKg
IMKgIMKgaWYgKHJldCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGdvdG8gZXJyX2ZyZWU7Cj4K
PiBAQCAtMjYxLDcgKzI2MSw3IEBAIHN0cnVjdCBhdGg1a19odyAqYXRoNWtfaHdfYXR0YWNoKHN0
cnVjdCBhdGg1a19zb2Z0YyAqc2MsIHU4IG1hY192ZXJzaW9uKQo+Cj4gwqAgwqAgwqAgwqAvKiBF
bmFibGUgcGNpIGNvcmUgcmV0cnkgZml4IG9uIEhhaW5hbiAoNTIxM0EpIGFuZCBsYXRlciBjaGlw
cyAqLwo+IMKgIMKgIMKgIMKgaWYgKHNyZXYgPj0gQVI1S19TUkVWX0FSNTIxM0EpCj4gLSDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBhdGg1a19od19yZWdfd3JpdGUoYWgsIEFSNUtfUENJQ0ZHX1JFVFJZ
X0ZJWCwgQVI1S19QQ0lDRkcpOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgQVI1S19SRUdfRU5B
QkxFX0JJVFMoYWgsIEFSNUtfUENJQ0ZHLCBBUjVLX1BDSUNGR19SRVRSWV9GSVgpOwo+Cj4gwqAg
wqAgwqAgwqAvKgo+IMKgIMKgIMKgIMKgICogR2V0IGNhcmQgY2FwYWJpbGl0aWVzLCBjYWxpYnJh
dGlvbiB2YWx1ZXMgZXRjCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9h
dGg1ay9iYXNlLmMgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvYmFzZS5jCj4gaW5k
ZXggN2RiMzJjZS4uYjY0NzMxYiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9h
dGgvYXRoNWsvYmFzZS5jCj4gKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2Jh
c2UuYwo+IEBAIC0yNDQ4LDI3ICsyNDQ4LDI5IEBAIGF0aDVrX3N0b3BfaHcoc3RydWN0IGF0aDVr
X3NvZnRjICpzYykKPiDCoCDCoCDCoCDCoHJldCA9IGF0aDVrX3N0b3BfbG9ja2VkKHNjKTsKPiDC
oCDCoCDCoCDCoGlmIChyZXQgPT0gMCAmJiAhdGVzdF9iaXQoQVRIX1NUQVRfSU5WQUxJRCwgc2Mt
PnN0YXR1cykpIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qCj4gLSDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCogU2V0IHRoZSBjaGlwIGluIGZ1bGwgc2xlZXAgbW9kZS4gwqBOb3RlIHRoYXQg
d2UgYXJlCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogY2FyZWZ1bCB0byBkbyB0aGlzIG9u
bHkgd2hlbiBicmluZ2luZyB0aGUgaW50ZXJmYWNlCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCogY29tcGxldGVseSB0byBhIHN0b3AuIMKgV2hlbiB0aGUgY2hpcCBpcyBpbiB0aGlzIHN0YXRl
Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogaXQgbXVzdCBiZSBjYXJlZnVsbHkgd29rZW4g
dXAgb3IgcmVmZXJlbmNlcyB0bwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqIHJlZ2lzdGVy
cyBpbiB0aGUgUENJIGNsb2NrIGRvbWFpbiBtYXkgZnJlZXplIHRoZSBidXMKPiAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgKiAoYW5kIHN5c3RlbSkuIMKgVGhpcyB2YXJpZXMgYnkgY2hpcCBhbmQg
aXMgbW9zdGx5IGFuCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogaXNzdWUgd2l0aCBuZXdl
ciBwYXJ0cyB0aGF0IGdvIHRvIHNsZWVwIG1vcmUgcXVpY2tseS4KPiAtIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgKi8KPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChzYy0+YWgtPmFoX21hY19z
cmV2ID49IDB4NzgpIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC8qCj4g
LSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogWFhYCj4gLSDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogZG9uJ3QgcHV0IG5ld2VyIE1BQyByZXZpc2lvbnMg
PiA3LjggdG8gc2xlZXAgYmVjYXVzZQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAqIG9mIHRoZSBhYm92ZSBtZW50aW9uZWQgcHJvYmxlbXMKPiAtIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgKi8KPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIEFUSDVLX0RCRyhzYywgQVRINUtfREVCVUdfUkVTRVQsICJtYWMgdmVyc2lvbiA+IDcuOCwg
Igo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgIm5vdCBw
dXR0aW5nIGRldmljZSB0byBzbGVlcFxuIik7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9IGVs
c2Ugewo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgQVRINUtfREJHKHNjLCBB
VEg1S19ERUJVR19SRVNFVCwKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgICJwdXR0aW5nIGRldmljZSB0byBmdWxsIHNsZWVwXG4iKTsKPiAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGF0aDVrX2h3X3NldF9wb3dlcihzYy0+YWgsIEFSNUtf
UE1fRlVMTF9TTEVFUCwgdHJ1ZSwgMCk7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogRG9uJ3Qgc2V0IHRoZSBjYXJkIGluIGZ1bGwgc2xlZXAg
bW9kZSEKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKgo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAqIGEpIFdoZW4gdGhlIGRldmljZSBpcyBpbiB0aGlzIHN0YXRlIGl0IG11c3QgYmUgY2Fy
ZWZ1bGx5Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogd29rZW4gdXAgb3IgcmVmZXJlbmNl
cyB0byByZWdpc3RlcnMgaW4gdGhlIFBDSSBjbG9jawo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAqIGRvbWFpbiBtYXkgZnJlZXplIHRoZSBidXMgKGFuZCBzeXN0ZW0pLiDCoFRoaXMgdmFyaWVz
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogYnkgY2hpcCBhbmQgaXMgbW9zdGx5IGFuIGlz
c3VlIHdpdGggbmV3ZXIgcGFydHMKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKiAobWFkd2lm
aSBzb3VyY2VzIG1lbnRpb25lZCBzcmV2ID49IDB4NzgpIHRoYXQgZ28gdG8KPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgKiBzbGVlcCBtb3JlIHF1aWNrbHkuCj4gKyDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCoKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKiBiKSBPbiBvbGRlciBjaGlwcyBm
dWxsIHNsZWVwIHJlc3VsdHMgYSB3ZWlyZCBiZWhhdmlvdXIKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgKiBkdXJpbmcgd2FrZXVwLiBJIHRlc3RlZCB2YXJpb3VzIGNhcmRzIHdpdGggc3JldiA8
IDB4NzgKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKiBhbmQgdGhleSBkb24ndCB3YWtlIHVw
IGFmdGVyIG1vZHVsZSByZWxvYWQsIGEgc2Vjb25kCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCogbW9kdWxlIHJlbG9hZCBpcyBuZWVkZWQgdG8gYnJpbmcgdGhlIGNhcmQgdXAgYWdhaW4uCj4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCoKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKiBV
bnRpbCB3ZSBmaWd1cmUgb3V0IHdoYXQncyBnb2luZyBvbiBkb24ndCBlbmFibGUKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgKiBmdWxsIGNoaXAgcmVzZXQgb24gYW55IGNoaXAgKHRoaXMgaXMg
d2hhdCBMZWdhY3kgSEFMCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogYW5kIFNhbSdzIEhB
TCBkbyBhbnl3YXkpLiBJbnN0ZWFkIFBlcmZvcm0gYSBmdWxsIHJlc2V0Cj4gKyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCogb24gdGhlIGRldmljZSAoc2FtZSBhcyBpbml0aWFsIHN0YXRlIGFmdGVy
IGF0dGFjaCkgYW5kCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogbGVhdmUgaXQgaWRsZSAo
a2VlcCBNQUMvQkIgb24gd2FybSByZXNldCkgKi8KPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJl
dCA9IGF0aDVrX2h3X29uX2hvbGQoc2MtPmFoKTsKPiArCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBBVEg1S19EQkcoc2MsIEFUSDVLX0RFQlVHX1JFU0VULAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgInB1dHRpbmcgZGV2aWNlIHRvIHNsZWVwXG4iKTsK
PiDCoCDCoCDCoCDCoH0KPiDCoCDCoCDCoCDCoGF0aDVrX3R4YnVmX2ZyZWUoc2MsIHNjLT5iYnVm
KTsKPgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvcmVzZXQu
YyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jCj4gaW5kZXggODY3MzNm
ZC4uMzRlMTNjNyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsv
cmVzZXQuYwo+ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jCj4g
QEAgLTI1OCwyOSArMjU4LDM1IEBAIGludCBhdGg1a19od19zZXRfcG93ZXIoc3RydWN0IGF0aDVr
X2h3ICphaCwgZW51bSBhdGg1a19wb3dlcl9tb2RlIG1vZGUsCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBpZiAoIXNldF9jaGlwKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
Z290byBjb21taXQ7Cj4KPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC8qIFByZXNlcnZlIHNsZWVw
IGR1cmF0aW9uICovCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkYXRhID0gYXRoNWtfaHdfcmVn
X3JlYWQoYWgsIEFSNUtfU0xFRVBfQ1RMKTsKPiArCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCAv
KiBJZiBjYXJkIGlzIGRvd24gd2UgJ2xsIGdldCAweGZmZmYuLi4gc28gd2UKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgKiBuZWVkIHRvIGNsZWFuIHRoaXMgdXAgYmVmb3JlIHdlIHdyaXRlIHRo
ZSByZWdpc3Rlcgo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqLwo+IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgaWYgKGRhdGEgJiAweGZmYzAwMDAwKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgZGF0YSA9IDA7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlbHNlCj4gLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkYXRhID0gZGF0YSAmIDB4ZmZmY2ZmZmY7
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAvKiBQcmVzZXJ2ZSBzbGVlcCBk
dXJhdGlvbiBldGMgKi8KPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRhdGEg
PSBkYXRhICYgfkFSNUtfU0xFRVBfQ1RMX1NMRTsKPgo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
YXRoNWtfaHdfcmVnX3dyaXRlKGFoLCBkYXRhLCBBUjVLX1NMRUVQX0NUTCk7Cj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBhdGg1a19od19yZWdfd3JpdGUoYWgsIGRhdGEgfCBBUjVLX1NMRUVQX0NU
TF9TTEVfV0FLRSwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFSNUtfU0xFRVBfQ1RMKTsK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVkZWxheSgxNSk7Cj4KPiAtIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIGZvciAoaSA9IDUwOyBpID4gMDsgaS0tKSB7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBmb3IgKGkgPSAyMDA7IGkgPiAwOyBpLS0pIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoC8qIENoZWNrIGlmIHRoZSBjaGlwIGRpZCB3YWtlIHVwICovCj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoKGF0aDVrX2h3X3JlZ19yZWFkKGFoLCBBUjVL
X1BDSUNGRykgJgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgQVI1S19QQ0lDRkdfU1BXUl9ETikgPT0gMCkKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBXYWl0IGEgYml0IGFuZCByZXRyeSAqLwo+IC0gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdWRlbGF5KDIwMCk7Cj4gLSDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBhdGg1a19od19yZWdfd3JpdGUoYWgsIGRhdGEsIEFSNUtf
U0xFRVBfQ1RMKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHVkZWxheSg1
MCk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBhdGg1a19od19yZWdfd3Jp
dGUoYWgsIGRhdGEgfCBBUjVLX1NMRUVQX0NUTF9TTEVfV0FLRSwKPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIEFSNUtfU0xFRVBfQ1RMKTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0KPgo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogRmFpbCBpZiB0aGUgY2hpcCBkaWRuJ3Qgd2FrZSB1
cCAqLwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGkgPD0gMCkKPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIGlmIChpID09IDApCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqByZXR1cm4gLUVJTzsKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7Cj4gQEAgLTI5
Niw2ICszMDIsNjQgQEAgY29tbWl0Ogo+IMKgfQo+Cj4gwqAvKgo+ICsgKiBQdXQgZGV2aWNlIG9u
IGhvbGQKPiArICoKPiArICogUHV0IE1BQyBhbmQgQmFzZWJhbmQgb24gd2FybSByZXNldCBhbmQK
PiArICoga2VlcCB0aGF0IHN0YXRlIChkb24ndCBjbGVhbiBzbGVlcCBjb250cm9sCj4gKyAqIHJl
Z2lzdGVyKS4gQWZ0ZXIgdGhpcyBNQUMgYW5kIEJhc2ViYW5kIGFyZQo+ICsgKiBkaXNhYmxlZCBh
bmQgYSBmdWxsIHJlc2V0IGlzIG5lZWRlZCB0byBjb21lCj4gKyAqIGJhY2suIFRoaXMgd2F5IHdl
IHNhdmUgYXMgbXVjaCBwb3dlciBhcyBwb3NzaWJsZQo+ICsgKiB3aXRob3V0IHB1dGluZyB0aGUg
Y2FyZCBvbiBmdWxsIHNsZWVwLgo+ICsgKi8KPiAraW50IGF0aDVrX2h3X29uX2hvbGQoc3RydWN0
IGF0aDVrX2h3ICphaCkKPiArewo+ICsgwqAgwqAgwqAgc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBh
aC0+YWhfc2MtPnBkZXY7Cj4gKyDCoCDCoCDCoCB1MzIgYnVzX2ZsYWdzOwo+ICsgwqAgwqAgwqAg
aW50IHJldDsKPiArCj4gKyDCoCDCoCDCoCAvKiBNYWtlIHN1cmUgZGV2aWNlIGlzIGF3YWtlICov
Cj4gKyDCoCDCoCDCoCByZXQgPSBhdGg1a19od19zZXRfcG93ZXIoYWgsIEFSNUtfUE1fQVdBS0Us
IHRydWUsIDApOwo+ICsgwqAgwqAgwqAgaWYgKHJldCkgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgQVRINUtfRVJSKGFoLT5haF9zYywgImZhaWxlZCB0byB3YWtldXAgdGhlIE1BQyBDaGlwXG4i
KTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiByZXQ7Cj4gKyDCoCDCoCDCoCB9Cj4g
Kwo+ICsgwqAgwqAgwqAgLyoKPiArIMKgIMKgIMKgIMKgKiBQdXQgY2hpcHNldCBvbiB3YXJtIHJl
c2V0Li4uCj4gKyDCoCDCoCDCoCDCoCoKPiArIMKgIMKgIMKgIMKgKiBOb3RlOiBwdXRpbmcgUENJ
IGNvcmUgb24gd2FybSByZXNldCBvbiBQQ0ktRSBjYXJkcwo+ICsgwqAgwqAgwqAgwqAqIHJlc3Vs
dHMgY2FyZCB0byBoYW5nIGFuZCBhbHdheXMgcmV0dXJuIDB4ZmZmZi4uLiBzbwo+ICsgwqAgwqAg
wqAgwqAqIHdlIGluZ29yZSB0aGF0IGZsYWcgZm9yIFBDSS1FIGNhcmRzLiBPbiBQQ0kgY2FyZHMK
PiArIMKgIMKgIMKgIMKgKiB0aGlzIGZsYWcgZ2V0cyBjbGVhcmVkIGFmdGVyIDY0IFBDSSBjbG9j
a3MuCj4gKyDCoCDCoCDCoCDCoCovCj4gKyDCoCDCoCDCoCBidXNfZmxhZ3MgPSAocGRldi0+aXNf
cGNpZSkgPyAwIDogQVI1S19SRVNFVF9DVExfUENJOwo+ICsKPiArIMKgIMKgIMKgIGlmIChhaC0+
YWhfdmVyc2lvbiA9PSBBUjVLX0FSNTIxMCkgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0
ID0gYXRoNWtfaHdfbmljX3Jlc2V0KGFoLCBBUjVLX1JFU0VUX0NUTF9QQ1UgfAo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgQVI1S19SRVNFVF9DVExfTUFDIHwgQVI1S19SRVNF
VF9DVExfRE1BIHwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFSNUtfUkVT
RVRfQ1RMX1BIWSB8IEFSNUtfUkVTRVRfQ1RMX1BDSSk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBtZGVsYXkoMik7Cj4gKyDCoCDCoCDCoCB9IGVsc2Ugewo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfbmljX3Jlc2V0KGFoLCBBUjVLX1JFU0VUX0NU
TF9QQ1UgfAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgQVI1S19SRVNFVF9D
VExfQkFTRUJBTkQgfCBidXNfZmxhZ3MpOwo+ICsgwqAgwqAgwqAgfQo+ICsKPiArIMKgIMKgIMKg
IGlmIChyZXQpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaC0+YWhfc2Ms
ICJmYWlsZWQgdG8gcHV0IGRldmljZSBvbiB3YXJtIHJlc2V0XG4iKTsKPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHJldHVybiAtRUlPOwo+ICsgwqAgwqAgwqAgfQo+ICsKPiArIMKgIMKgIMKgIC8q
IC4uLndha2V1cCBhZ2FpbiEqLwo+ICsgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfc2V0X3Bvd2Vy
KGFoLCBBUjVLX1BNX0FXQUtFLCB0cnVlLCAwKTsKPiArIMKgIMKgIMKgIGlmIChyZXQpIHsKPiAr
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaC0+YWhfc2MsICJmYWlsZWQgdG8gcHV0
IGRldmljZSBvbiBob2xkXG4iKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiByZXQ7
Cj4gKyDCoCDCoCDCoCB9Cj4gKwo+ICsgwqAgwqAgwqAgcmV0dXJuIHJldDsKPiArfQo+ICsKPiAr
LyoKPiDCoCogQnJpbmcgdXAgTUFDICsgUEhZIENoaXBzIGFuZCBwcm9ncmFtIFBMTAo+IMKgKiBU
T0RPOiBIYWxmL1F1YXJ0ZXIgcmF0ZSBzdXBwb3J0Cj4gwqAqLwo+IEBAIC0zMTgsNiArMzgyLDUw
IEBAIGludCBhdGg1a19od19uaWNfd2FrZXVwKHN0cnVjdCBhdGg1a19odyAqYWgsIGludCBmbGFn
cywgYm9vbCBpbml0aWFsKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIHJldDsKPiDC
oCDCoCDCoCDCoH0KPgo+ICsgwqAgwqAgwqAgLyoKPiArIMKgIMKgIMKgIMKgKiBQdXQgY2hpcHNl
dCBvbiB3YXJtIHJlc2V0Li4uCj4gKyDCoCDCoCDCoCDCoCoKPiArIMKgIMKgIMKgIMKgKiBOb3Rl
OiBwdXRpbmcgUENJIGNvcmUgb24gd2FybSByZXNldCBvbiBQQ0ktRSBjYXJkcwo+ICsgwqAgwqAg
wqAgwqAqIHJlc3VsdHMgY2FyZCB0byBoYW5nIGFuZCBhbHdheXMgcmV0dXJuIDB4ZmZmZi4uLiBz
bwo+ICsgwqAgwqAgwqAgwqAqIHdlIGluZ29yZSB0aGF0IGZsYWcgZm9yIFBDSS1FIGNhcmRzLiBP
biBQQ0kgY2FyZHMKPiArIMKgIMKgIMKgIMKgKiB0aGlzIGZsYWcgZ2V0cyBjbGVhcmVkIGFmdGVy
IDY0IFBDSSBjbG9ja3MuCj4gKyDCoCDCoCDCoCDCoCovCj4gKyDCoCDCoCDCoCBidXNfZmxhZ3Mg
PSAocGRldi0+aXNfcGNpZSkgPyAwIDogQVI1S19SRVNFVF9DVExfUENJOwo+ICsKPiArIMKgIMKg
IMKgIGlmIChhaC0+YWhfdmVyc2lvbiA9PSBBUjVLX0FSNTIxMCkgewo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfbmljX3Jlc2V0KGFoLCBBUjVLX1JFU0VUX0NUTF9QQ1Ug
fAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgQVI1S19SRVNFVF9DVExfTUFD
IHwgQVI1S19SRVNFVF9DVExfRE1BIHwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIEFSNUtfUkVTRVRfQ1RMX1BIWSB8IEFSNUtfUkVTRVRfQ1RMX1BDSSk7Cj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBtZGVsYXkoMik7Cj4gKyDCoCDCoCDCoCB9IGVsc2Ug
ewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfbmljX3Jlc2V0KGFoLCBB
UjVLX1JFU0VUX0NUTF9QQ1UgfAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
QVI1S19SRVNFVF9DVExfQkFTRUJBTkQgfCBidXNfZmxhZ3MpOwo+ICsgwqAgwqAgwqAgfQo+ICsK
PiArIMKgIMKgIMKgIGlmIChyZXQpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VS
UihhaC0+YWhfc2MsICJmYWlsZWQgdG8gcmVzZXQgdGhlIE1BQyBDaGlwXG4iKTsKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRUlPOwo+ICsgwqAgwqAgwqAgfQo+ICsKPiArIMKgIMKg
IMKgIC8qIC4uLndha2V1cCBhZ2FpbiEuLi4qLwo+ICsgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdf
c2V0X3Bvd2VyKGFoLCBBUjVLX1BNX0FXQUtFLCB0cnVlLCAwKTsKPiArIMKgIMKgIMKgIGlmIChy
ZXQpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaC0+YWhfc2MsICJmYWls
ZWQgdG8gcmVzdW1lIHRoZSBNQUMgQ2hpcFxuIik7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy
ZXR1cm4gcmV0Owo+ICsgwqAgwqAgwqAgfQo+ICsKPiArIMKgIMKgIMKgIC8qIC4uLmNsZWFyIHJl
c2V0IGNvbnRyb2wgcmVnaXN0ZXIgYW5kIHB1bGwgZGV2aWNlIG91dCBvZgo+ICsgwqAgwqAgwqAg
wqAqIHdhcm0gcmVzZXQgKi8KPiArIMKgIMKgIMKgIGlmIChhdGg1a19od19uaWNfcmVzZXQoYWgs
IDApKSB7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBBVEg1S19FUlIoYWgtPmFoX3NjLCAiZmFp
bGVkIHRvIHdhcm0gcmVzZXQgdGhlIE1BQyBDaGlwXG4iKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIHJldHVybiAtRUlPOwo+ICsgwqAgwqAgwqAgfQo+ICsKPiArIMKgIMKgIMKgIC8qIE9uIGlu
aXRpYWxpemF0aW9uIHNraXAgUExMIHByb2dyYW1taW5nIHNpbmNlIHdlIGRvbid0IGhhdmUKPiAr
IMKgIMKgIMKgIMKgKiBhIGNoYW5uZWwgLyBtb2RlIHNldCB5ZXQgKi8KPiArIMKgIMKgIMKgIGlm
IChpbml0aWFsKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIDA7Cj4gKwo+IMKgIMKg
IMKgIMKgaWYgKGFoLT5haF92ZXJzaW9uICE9IEFSNUtfQVI1MjEwKSB7Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAvKgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICogR2V0IGNoYW5uZWwgbW9k
ZSBmbGFncwo+IEBAIC0zODMsMzkgKzQ5MSw2IEBAIGludCBhdGg1a19od19uaWNfd2FrZXVwKHN0
cnVjdCBhdGg1a19odyAqYWgsIGludCBmbGFncywgYm9vbCBpbml0aWFsKQo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19QSFlf
VFVSQk8pOwo+IMKgIMKgIMKgIMKgfQo+Cj4gLSDCoCDCoCDCoCAvKiByZXNldGluZyBQQ0kgb24g
UENJLUUgY2FyZHMgcmVzdWx0cyBjYXJkIHRvIGhhbmcKPiAtIMKgIMKgIMKgIMKgKiBhbmQgYWx3
YXlzIHJldHVybiAweGZmZmYuLi4gc28gd2UgaW5nb3JlIHRoYXQgZmxhZwo+IC0gwqAgwqAgwqAg
wqAqIGZvciBQQ0ktRSBjYXJkcyAqLwo+IC0gwqAgwqAgwqAgYnVzX2ZsYWdzID0gKHBkZXYtPmlz
X3BjaWUpID8gMCA6IEFSNUtfUkVTRVRfQ1RMX1BDSTsKPiAtCj4gLSDCoCDCoCDCoCAvKiBSZXNl
dCBjaGlwc2V0ICovCj4gLSDCoCDCoCDCoCBpZiAoYWgtPmFoX3ZlcnNpb24gPT0gQVI1S19BUjUy
MTApIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldCA9IGF0aDVrX2h3X25pY19yZXNldChh
aCwgQVI1S19SRVNFVF9DVExfUENVIHwKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIEFSNUtfUkVTRVRfQ1RMX01BQyB8IEFSNUtfUkVTRVRfQ1RMX0RNQSB8Cj4gLSDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBBUjVLX1JFU0VUX0NUTF9QSFkgfCBBUjVLX1JFU0VU
X0NUTF9QQ0kpOwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgbWRlbGF5KDIp
Owo+IC0gwqAgwqAgwqAgfSBlbHNlIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldCA9IGF0
aDVrX2h3X25pY19yZXNldChhaCwgQVI1S19SRVNFVF9DVExfUENVIHwKPiAtIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFSNUtfUkVTRVRfQ1RMX0JBU0VCQU5EIHwgYnVzX2ZsYWdz
KTsKPiAtIMKgIMKgIMKgIH0KPiAtIMKgIMKgIMKgIGlmIChyZXQpIHsKPiAtIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIEFUSDVLX0VSUihhaC0+YWhfc2MsICJmYWlsZWQgdG8gcmVzZXQgdGhlIE1BQyBD
aGlwXG4iKTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRUlPOwo+IC0gwqAgwqAg
wqAgfQo+IC0KPiAtIMKgIMKgIMKgIC8qIC4uLndha2V1cCBhZ2FpbiEqLwo+IC0gwqAgwqAgwqAg
cmV0ID0gYXRoNWtfaHdfc2V0X3Bvd2VyKGFoLCBBUjVLX1BNX0FXQUtFLCB0cnVlLCAwKTsKPiAt
IMKgIMKgIMKgIGlmIChyZXQpIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihh
aC0+YWhfc2MsICJmYWlsZWQgdG8gcmVzdW1lIHRoZSBNQUMgQ2hpcFxuIik7Cj4gLSDCoCDCoCDC
oCDCoCDCoCDCoCDCoCByZXR1cm4gcmV0Owo+IC0gwqAgwqAgwqAgfQo+IC0KPiAtIMKgIMKgIMKg
IC8qIC4uLmZpbmFsIHdhcm0gcmVzZXQgKi8KPiAtIMKgIMKgIMKgIGlmIChhdGg1a19od19uaWNf
cmVzZXQoYWgsIDApKSB7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBBVEg1S19FUlIoYWgtPmFo
X3NjLCAiZmFpbGVkIHRvIHdhcm0gcmVzZXQgdGhlIE1BQyBDaGlwXG4iKTsKPiAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIHJldHVybiAtRUlPOwo+IC0gwqAgwqAgwqAgfQo+IC0KPiDCoCDCoCDCoCDC
oGlmIChhaC0+YWhfdmVyc2lvbiAhPSBBUjVLX0FSNTIxMCkgewo+Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAvKiAuLi51cGRhdGUgUExMIGlmIG5lZWRlZCAqLwo+Cg==

2009-07-31 19:06:11

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [ath5k-devel] [PATCH 3/4] ath5k: Wakeup fixes

On Fri, Jul 31, 2009 at 12:03 PM, Ben Greear<[email protected]> wrote:
> On 07/31/2009 11:08 AM, Nick Kossifidis wrote:
>>
>>  * Don't put chip to full sleep because there are problems during
>>    wakeup. Instead hold MAC/Baseband on warm reset state via a new
>>    function ath5k_hw_on_hold.
>>
>>  * Durring attach preserve pcicfg bits when enabling pci core
>>    sw retry fix.
>>
>>  * Minor cleanups
>
> I patched just this patch (not your other 3) into 2.6.31-rc4 and it seems
> to fix the wakeup problems I was seeing on module unload/load.

And now you can throw in a Tested-by in the commit log. The commit log
will make more sense as if you refer to the issue we can refer to it
later in the future and see it was tested perhaps by the same user who
reported the issue.

Luis

2009-07-31 19:02:16

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath5k: Wakeup fixes

On Fri, Jul 31, 2009 at 11:39 AM, Nick Kossifidis<[email protected]> wrote:
> 2009/7/31 Luis R. Rodriguez <[email protected]>:
>> On Fri, Jul 31, 2009 at 11:08 AM, Nick
>> Kossifidis<[email protected]> wrote:
>>>  * Don't put chip to full sleep because there are problems during
>>>   wakeup. Instead hold MAC/Baseband on warm reset state via a new
>>>   function ath5k_hw_on_hold.
>>>
>>>  * Durring attach preserve pcicfg bits when enabling pci core
>>>   sw retry fix.
>>>
>>>  * Minor cleanups
>>
>> Can you address these changes separately? I see you tend to itemize
>> the things you change, even when you just make one change. Please
>> consider addressing one change per commit and just ensure the why is
>> crystal clear.
>>
>>  Luis
>>
>
> Cleanup doesn't count as a change, the only real change is the first one.
> I 'm trying not to pollute the logs.

The purpose of the patch review cycle is to make it very easy to
review code changes, the more you split your work the easier it is to
review, that is not polluting the logs in any way.

> This patch fixes an issue reported when
> card doesn't wake up.

This is not mentioned in the commit log, please add that to the commit
log and refer to a URL if possible.

Luis

2009-07-31 18:33:06

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath5k: Wakeup fixes

* Don't put chip to full sleep because there are problems during
wakeup. Instead hold MAC/Baseband on warm reset state via a new
function ath5k_hw_on_hold.

* Durring attach preserve pcicfg bits when enabling pci core
sw retry fix.

* Minor cleanups

Signed-off-by: Nick Kossifidis <[email protected]>

---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/attach.c | 4 +-
drivers/net/wireless/ath/ath5k/base.c | 44 +++++----
drivers/net/wireless/ath/ath5k/reset.c | 155 +++++++++++++++++++++++--------
4 files changed, 141 insertions(+), 63 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 9137511..1047a6c 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1157,6 +1157,7 @@ extern void ath5k_unregister_leds(struct ath5k_softc *sc);

/* Reset Functions */
extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+extern int ath5k_hw_on_hold(struct ath5k_hw *ah);
extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
/* Power management functions */
extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 6263065..65d438b 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -145,7 +145,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free;

/* Bring device out of sleep and reset it's units */
- ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
+ ret = ath5k_hw_nic_wakeup(ah, 0, true);
if (ret)
goto err_free;

@@ -261,7 +261,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)

/* Enable pci core retry fix on Hainan (5213A) and later chips */
if (srev >= AR5K_SREV_AR5213A)
- ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX);

/*
* Get card capabilities, calibration values etc
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7db32ce..b64731b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2448,27 +2448,29 @@ ath5k_stop_hw(struct ath5k_softc *sc)
ret = ath5k_stop_locked(sc);
if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
/*
- * Set the chip in full sleep mode. Note that we are
- * careful to do this only when bringing the interface
- * completely to a stop. When the chip is in this state
- * it must be carefully woken up or references to
- * registers in the PCI clock domain may freeze the bus
- * (and system). This varies by chip and is mostly an
- * issue with newer parts that go to sleep more quickly.
- */
- if (sc->ah->ah_mac_srev >= 0x78) {
- /*
- * XXX
- * don't put newer MAC revisions > 7.8 to sleep because
- * of the above mentioned problems
- */
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
- "not putting device to sleep\n");
- } else {
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
- "putting device to full sleep\n");
- ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
- }
+ * Don't set the card in full sleep mode!
+ *
+ * a) When the device is in this state it must be carefully
+ * woken up or references to registers in the PCI clock
+ * domain may freeze the bus (and system). This varies
+ * by chip and is mostly an issue with newer parts
+ * (madwifi sources mentioned srev >= 0x78) that go to
+ * sleep more quickly.
+ *
+ * b) On older chips full sleep results a weird behaviour
+ * during wakeup. I tested various cards with srev < 0x78
+ * and they don't wake up after module reload, a second
+ * module reload is needed to bring the card up again.
+ *
+ * Until we figure out what's going on don't enable
+ * full chip reset on any chip (this is what Legacy HAL
+ * and Sam's HAL do anyway). Instead Perform a full reset
+ * on the device (same as initial state after attach) and
+ * leave it idle (keep MAC/BB on warm reset) */
+ ret = ath5k_hw_on_hold(sc->ah);
+
+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+ "putting device to sleep\n");
}
ath5k_txbuf_free(sc, sc->bbuf);

diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 86733fd..34e13c7 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -258,29 +258,35 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
if (!set_chip)
goto commit;

- /* Preserve sleep duration */
data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
+
+ /* If card is down we 'll get 0xffff... so we
+ * need to clean this up before we write the register
+ */
if (data & 0xffc00000)
data = 0;
else
- data = data & 0xfffcffff;
+ /* Preserve sleep duration etc */
+ data = data & ~AR5K_SLEEP_CTL_SLE;

- ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+ ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
+ AR5K_SLEEP_CTL);
udelay(15);

- for (i = 50; i > 0; i--) {
+ for (i = 200; i > 0; i--) {
/* Check if the chip did wake up */
if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
AR5K_PCICFG_SPWR_DN) == 0)
break;

/* Wait a bit and retry */
- udelay(200);
- ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+ udelay(50);
+ ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
+ AR5K_SLEEP_CTL);
}

/* Fail if the chip didn't wake up */
- if (i <= 0)
+ if (i == 0)
return -EIO;

break;
@@ -296,6 +302,64 @@ commit:
}

/*
+ * Put device on hold
+ *
+ * Put MAC and Baseband on warm reset and
+ * keep that state (don't clean sleep control
+ * register). After this MAC and Baseband are
+ * disabled and a full reset is needed to come
+ * back. This way we save as much power as possible
+ * without puting the card on full sleep.
+ */
+int ath5k_hw_on_hold(struct ath5k_hw *ah)
+{
+ struct pci_dev *pdev = ah->ah_sc->pdev;
+ u32 bus_flags;
+ int ret;
+
+ /* Make sure device is awake */
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+ return ret;
+ }
+
+ /*
+ * Put chipset on warm reset...
+ *
+ * Note: puting PCI core on warm reset on PCI-E cards
+ * results card to hang and always return 0xffff... so
+ * we ingore that flag for PCI-E cards. On PCI cards
+ * this flag gets cleared after 64 PCI clocks.
+ */
+ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+ if (ah->ah_version == AR5K_AR5210) {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+ AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+ mdelay(2);
+ } else {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND | bus_flags);
+ }
+
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to put device on warm reset\n");
+ return -EIO;
+ }
+
+ /* ...wakeup again!*/
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to put device on hold\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+/*
* Bring up MAC + PHY Chips and program PLL
* TODO: Half/Quarter rate support
*/
@@ -318,6 +382,50 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return ret;
}

+ /*
+ * Put chipset on warm reset...
+ *
+ * Note: puting PCI core on warm reset on PCI-E cards
+ * results card to hang and always return 0xffff... so
+ * we ingore that flag for PCI-E cards. On PCI cards
+ * this flag gets cleared after 64 PCI clocks.
+ */
+ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+ if (ah->ah_version == AR5K_AR5210) {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+ AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+ mdelay(2);
+ } else {
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND | bus_flags);
+ }
+
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+ return -EIO;
+ }
+
+ /* ...wakeup again!...*/
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+ return ret;
+ }
+
+ /* ...clear reset control register and pull device out of
+ * warm reset */
+ if (ath5k_hw_nic_reset(ah, 0)) {
+ ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+ return -EIO;
+ }
+
+ /* On initialization skip PLL programming since we don't have
+ * a channel / mode set yet */
+ if (initial)
+ return 0;
+
if (ah->ah_version != AR5K_AR5210) {
/*
* Get channel mode flags
@@ -383,39 +491,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
AR5K_PHY_TURBO);
}

- /* reseting PCI on PCI-E cards results card to hang
- * and always return 0xffff... so we ingore that flag
- * for PCI-E cards */
- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
-
- /* Reset chipset */
- if (ah->ah_version == AR5K_AR5210) {
- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
- AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
- AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
- mdelay(2);
- } else {
- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
- AR5K_RESET_CTL_BASEBAND | bus_flags);
- }
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
- return -EIO;
- }
-
- /* ...wakeup again!*/
- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
- return ret;
- }
-
- /* ...final warm reset */
- if (ath5k_hw_nic_reset(ah, 0)) {
- ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
- return -EIO;
- }
-
if (ah->ah_version != AR5K_AR5210) {

/* ...update PLL if needed */

2009-07-31 18:39:32

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath5k: Wakeup fixes

2009/7/31 Luis R. Rodriguez <[email protected]>:
> On Fri, Jul 31, 2009 at 11:08 AM, Nick
> Kossifidis<[email protected]> wrote:
>>  * Don't put chip to full sleep because there are problems during
>>   wakeup. Instead hold MAC/Baseband on warm reset state via a new
>>   function ath5k_hw_on_hold.
>>
>>  * Durring attach preserve pcicfg bits when enabling pci core
>>   sw retry fix.
>>
>>  * Minor cleanups
>
> Can you address these changes separately? I see you tend to itemize
> the things you change, even when you just make one change. Please
> consider addressing one change per commit and just ensure the why is
> crystal clear.
>
>  Luis
>

Cleanup doesn't count as a change, the only real change is the first one.
I 'm trying not to pollute the logs. This patch fixes an issue reported when
card doesn't wake up.

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2009-07-31 19:04:27

by Ben Greear

[permalink] [raw]
Subject: Re: [ath5k-devel] [PATCH 3/4] ath5k: Wakeup fixes

On 07/31/2009 11:08 AM, Nick Kossifidis wrote:
> * Don't put chip to full sleep because there are problems during
> wakeup. Instead hold MAC/Baseband on warm reset state via a new
> function ath5k_hw_on_hold.
>
> * Durring attach preserve pcicfg bits when enabling pci core
> sw retry fix.
>
> * Minor cleanups

I patched just this patch (not your other 3) into 2.6.31-rc4 and it seems
to fix the wakeup problems I was seeing on module unload/load.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com