All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices.
       [not found] <28511431.361290765324515.JavaMail.wlan@CHBU500181>
@ 2010-11-26  9:57 ` Wojciech Dubowik
  2010-11-27  0:29   ` Nick Kossifidis
  0 siblings, 1 reply; 3+ messages in thread
From: Wojciech Dubowik @ 2010-11-26  9:57 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, nbd, ath5k-devel

From: Felix Fietkau <nbd@openwrt.org>

On WiSoc we cannot access mac register before it is resetted.
It will crash hardware otherwise.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
---
 drivers/net/wireless/ath/ath5k/base.c  |    7 ++-
 drivers/net/wireless/ath/ath5k/reset.c |  114 ++++++++++++++++++++++++-------
 2 files changed, 94 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4d5ac71..87a4bb6 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2169,7 +2169,8 @@ ath5k_intr(int irq, void *dev_id)
 	unsigned int counter = 1000;
 
 	if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
-				!ath5k_hw_is_intr_pending(ah)))
+		((ath5k_get_bus_type(ah) != ATH_AHB) &&
+				!ath5k_hw_is_intr_pending(ah))))
 		return IRQ_NONE;
 
 	do {
@@ -2235,6 +2236,10 @@ ath5k_intr(int irq, void *dev_id)
 				tasklet_schedule(&sc->rf_kill.toggleq);
 
 		}
+
+		if (ath5k_get_bus_type(ah) == ATH_AHB)
+			break;
+
 	} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
 
 	if (unlikely(!counter))
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 198a146..4f54655 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -27,6 +27,7 @@
 
 #include <linux/pci.h> 		/* To determine if a card is pci-e */
 #include <linux/log2.h>
+#include <linux/platform_device.h>
 #include "ath5k.h"
 #include "reg.h"
 #include "base.h"
@@ -198,31 +199,74 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
  */
 static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
 {
-	int ret;
+	int ret = 0;
 	u32 mask = val ? val : ~0U;
 
 	/* Read-and-clear RX Descriptor Pointer*/
-	ath5k_hw_reg_read(ah, AR5K_RXDP);
+	if (!(mask & AR5K_RESET_CTL_MAC))
+		ath5k_hw_reg_read(ah, AR5K_RXDP);
 
 	/*
 	 * Reset the device and wait until success
 	 */
-	ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
+	if (ath5k_get_bus_type(ah) == ATH_AHB) {
+		volatile u32 *reg;
+		u32 regval;
+		val = 0;
+
+		/* ah->ah_mac_srev is not available at this point yet */
+		if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
+			reg = (u32 *) AR5K_AR2315_RESET;
+			if (mask & AR5K_RESET_CTL_MAC)
+				val |= AR5K_AR2315_RESET_WMAC;
+			if (mask & AR5K_RESET_CTL_BASEBAND)
+				val |= AR5K_AR2315_RESET_BB_WARM;
+		} else {
+			reg = (u32 *) AR5K_AR5312_RESET;
+			if (to_platform_device(ah->ah_sc->dev)->id == 0) {
+				if (mask & AR5K_RESET_CTL_MAC)
+					val |= AR5K_AR5312_RESET_WMAC0;
+				if (mask & AR5K_RESET_CTL_BASEBAND)
+					val |= AR5K_AR5312_RESET_BB0_COLD |
+					       AR5K_AR5312_RESET_BB0_WARM;
+			} else {
+				if (mask & AR5K_RESET_CTL_MAC)
+					val |= AR5K_AR5312_RESET_WMAC1;
+				if (mask & AR5K_RESET_CTL_BASEBAND)
+					val |= AR5K_AR5312_RESET_BB1_COLD |
+					       AR5K_AR5312_RESET_BB1_WARM;
+			}
+		}
 
-	/* Wait at least 128 PCI clocks */
-	udelay(15);
+		/* Put BB/MAC into reset */
+		regval = __raw_readl(reg);
+		__raw_writel(regval | val, reg);
+		regval = __raw_readl(reg);
+		udelay(100);
 
-	if (ah->ah_version == AR5K_AR5210) {
-		val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
-			| AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
-		mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
-			| AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+		/* Bring BB/MAC out of reset */
+		__raw_writel(regval & ~val, reg);
+		regval = __raw_readl(reg);
 	} else {
-		val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
-		mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
-	}
 
-	ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
+		ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
+
+		/* Wait at least 128 PCI clocks */
+		udelay(15);
+
+		if (ah->ah_version == AR5K_AR5210) {
+			val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+				| AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+			mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+				| AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+		} else {
+			val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+			mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+		}
+
+		ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL,
+				mask, val, false);
+	}
 
 	/*
 	 * Reset configuration register (for hw byte-swap). Note that this
@@ -334,6 +378,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
 	u32 bus_flags;
 	int ret;
 
+	if (ath5k_get_bus_type(ah) == ATH_AHB)
+		return 0;
+
 	/* Make sure device is awake */
 	ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
 	if (ret) {
@@ -390,22 +437,30 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 	mode = 0;
 	clock = 0;
 
-	/* Wakeup the device */
-	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;
+	if (ath5k_get_bus_type(ah) == ATH_AHB && !initial) {
+		/* Wakeup the device */
+		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: putting 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 && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+	if (ath5k_get_bus_type(ah) == ATH_AHB) {
+		/* Reset MAC on WiSoc devices */
+		bus_flags = (initial) ? AR5K_RESET_CTL_MAC : 0;
+	} else {
+		/* Note: putting 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 && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+	}
 
 	if (ah->ah_version == AR5K_AR5210) {
 		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -536,6 +591,9 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	u32 scal, spending, usec32;
 
+	if (ath5k_get_bus_type(ah) == ATH_AHB)
+		enable = false;
+
 	/* Only set 32KHz settings if we have an external
 	 * 32KHz crystal present */
 	if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
@@ -607,6 +665,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
 
 		if ((ah->ah_radio == AR5K_RF5112) ||
 		(ah->ah_radio == AR5K_RF5413) ||
+		(ah->ah_radio == AR5K_RF2316) ||
 		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
 			spending = 0x14;
 		else
@@ -614,7 +673,9 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
 		ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
 
 		if ((ah->ah_radio == AR5K_RF5112) ||
-		(ah->ah_radio == AR5K_RF5413))
+		(ah->ah_radio == AR5K_RF5413) ||
+		(ah->ah_radio == AR5K_RF2316) ||
+		(ah->ah_radio == AR5K_RF2317))
 			usec32 = 39;
 		else
 			usec32 = 31;
@@ -678,7 +739,8 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
 
 	/* Set fast ADC */
 	if ((ah->ah_radio == AR5K_RF5413) ||
-	(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+		(ah->ah_radio == AR5K_RF2317) ||
+		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
 		u32 fast_adc = true;
 
 		if (channel->center_freq == 2462 ||
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices.
  2010-11-26  9:57 ` [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices Wojciech Dubowik
@ 2010-11-27  0:29   ` Nick Kossifidis
  0 siblings, 0 replies; 3+ messages in thread
From: Nick Kossifidis @ 2010-11-27  0:29 UTC (permalink / raw)
  To: Wojciech Dubowik; +Cc: linville, linux-wireless, nbd, ath5k-devel

MjAxMC8xMS8yNiBXb2pjaWVjaCBEdWJvd2lrIDxkdWJvd29qQG5lcmF0ZWMuY29tPjoKPiBGcm9t
OiBGZWxpeCBGaWV0a2F1IDxuYmRAb3BlbndydC5vcmc+Cj4KPiBPbiBXaVNvYyB3ZSBjYW5ub3Qg
YWNjZXNzIG1hYyByZWdpc3RlciBiZWZvcmUgaXQgaXMgcmVzZXR0ZWQuCj4gSXQgd2lsbCBjcmFz
aCBoYXJkd2FyZSBvdGhlcndpc2UuCj4KPiBTaWduZWQtb2ZmLWJ5OiBGZWxpeCBGaWV0a2F1IDxu
YmRAb3BlbndydC5vcmc+Cj4gU2lnbmVkLW9mZi1ieTogV29qY2llY2ggRHVib3dpayA8V29qY2ll
Y2guRHVib3dpa0BuZXJhdGVjLmNvbT4KPiAtLS0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0
aC9hdGg1ay9iYXNlLmMgwqB8IMKgIMKgNyArKy0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0
aC9hdGg1ay9yZXNldC5jIHwgwqAxMTQgKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLQo+
IMKgMiBmaWxlcyBjaGFuZ2VkLCA5NCBpbnNlcnRpb25zKCspLCAyNyBkZWxldGlvbnMoLSkKPgo+
IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvYmFzZS5jIGIvZHJp
dmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2Jhc2UuYwo+IGluZGV4IDRkNWFjNzEuLjg3YTRi
YjYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2Jhc2UuYwo+
ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9iYXNlLmMKPiBAQCAtMjE2OSw3
ICsyMTY5LDggQEAgYXRoNWtfaW50cihpbnQgaXJxLCB2b2lkICpkZXZfaWQpCj4gwqAgwqAgwqAg
wqB1bnNpZ25lZCBpbnQgY291bnRlciA9IDEwMDA7Cj4KPiDCoCDCoCDCoCDCoGlmICh1bmxpa2Vs
eSh0ZXN0X2JpdChBVEhfU1RBVF9JTlZBTElELCBzYy0+c3RhdHVzKSB8fAo+IC0gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgIWF0aDVrX2h3X2lzX2ludHJfcGVu
ZGluZyhhaCkpKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKChhdGg1a19nZXRfYnVzX3R5cGUo
YWgpICE9IEFUSF9BSEIpICYmCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCAhYXRoNWtfaHdfaXNfaW50cl9wZW5kaW5nKGFoKSkpKQo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgcmV0dXJuIElSUV9OT05FOwo+Cj4gwqAgwqAgwqAgwqBkbyB7Cj4gQEAgLTIy
MzUsNiArMjIzNiwxMCBAQCBhdGg1a19pbnRyKGludCBpcnEsIHZvaWQgKmRldl9pZCkKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHRhc2tsZXRfc2NoZWR1
bGUoJnNjLT5yZl9raWxsLnRvZ2dsZXEpOwo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9Cj4g
Kwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGF0aDVrX2dldF9idXNfdHlwZShhaCkgPT0g
QVRIX0FIQikKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+ICsK
PiDCoCDCoCDCoCDCoH0gd2hpbGUgKGF0aDVrX2h3X2lzX2ludHJfcGVuZGluZyhhaCkgJiYgLS1j
b3VudGVyID4gMCk7Cj4KPiDCoCDCoCDCoCDCoGlmICh1bmxpa2VseSghY291bnRlcikpCj4gZGlm
ZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jIGIvZHJpdmVy
cy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3Jlc2V0LmMKPiBpbmRleCAxOThhMTQ2Li40ZjU0NjU1
IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jCj4g
KysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3Jlc2V0LmMKPiBAQCAtMjcsNiAr
MjcsNyBAQAo+Cj4gwqAjaW5jbHVkZSA8bGludXgvcGNpLmg+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIC8qIFRvIGRldGVybWluZSBpZiBhIGNhcmQgaXMgcGNpLWUgKi8KPiDCoCNpbmNsdWRlIDxs
aW51eC9sb2cyLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPiDCoCNp
bmNsdWRlICJhdGg1ay5oIgo+IMKgI2luY2x1ZGUgInJlZy5oIgo+IMKgI2luY2x1ZGUgImJhc2Uu
aCIKPiBAQCAtMTk4LDMxICsxOTksNzQgQEAgc3RhdGljIGlubGluZSB2b2lkIGF0aDVrX2h3X3dy
aXRlX3JhdGVfZHVyYXRpb24oc3RydWN0IGF0aDVrX2h3ICphaCwKPiDCoCovCj4gwqBzdGF0aWMg
aW50IGF0aDVrX2h3X25pY19yZXNldChzdHJ1Y3QgYXRoNWtfaHcgKmFoLCB1MzIgdmFsKQo+IMKg
ewo+IC0gwqAgwqAgwqAgaW50IHJldDsKPiArIMKgIMKgIMKgIGludCByZXQgPSAwOwo+IMKgIMKg
IMKgIMKgdTMyIG1hc2sgPSB2YWwgPyB2YWwgOiB+MFU7Cj4KPiDCoCDCoCDCoCDCoC8qIFJlYWQt
YW5kLWNsZWFyIFJYIERlc2NyaXB0b3IgUG9pbnRlciovCj4gLSDCoCDCoCDCoCBhdGg1a19od19y
ZWdfcmVhZChhaCwgQVI1S19SWERQKTsKPiArIMKgIMKgIMKgIGlmICghKG1hc2sgJiBBUjVLX1JF
U0VUX0NUTF9NQUMpKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYXRoNWtfaHdfcmVnX3JlYWQo
YWgsIEFSNUtfUlhEUCk7Cj4KPiDCoCDCoCDCoCDCoC8qCj4gwqAgwqAgwqAgwqAgKiBSZXNldCB0
aGUgZGV2aWNlIGFuZCB3YWl0IHVudGlsIHN1Y2Nlc3MKPiDCoCDCoCDCoCDCoCAqLwo+IC0gwqAg
wqAgwqAgYXRoNWtfaHdfcmVnX3dyaXRlKGFoLCB2YWwsIEFSNUtfUkVTRVRfQ1RMKTsKPiArIMKg
IMKgIMKgIGlmIChhdGg1a19nZXRfYnVzX3R5cGUoYWgpID09IEFUSF9BSEIpIHsKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHZvbGF0aWxlIHUzMiAqcmVnOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgdTMyIHJlZ3ZhbDsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCA9IDA7Cj4gKwo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgLyogYWgtPmFoX21hY19zcmV2IGlzIG5vdCBhdmFpbGFibGUg
YXQgdGhpcyBwb2ludCB5ZXQgKi8KPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChhaC0+YWhf
c2MtPmRldmlkID49IEFSNUtfU1JFVl9BUjIzMTVfUjYpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHJlZyA9ICh1MzIgKikgQVI1S19BUjIzMTVfUkVTRVQ7Cj4gKyDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAobWFzayAmIEFSNUtfUkVTRVRfQ1RMX01B
QykKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCB8
PSBBUjVLX0FSMjMxNV9SRVNFVF9XTUFDOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgaWYgKG1hc2sgJiBBUjVLX1JFU0VUX0NUTF9CQVNFQkFORCkKPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCB8PSBBUjVLX0FSMjMxNV9SRVNF
VF9CQl9XQVJNOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJlZyA9ICh1MzIgKikgQVI1S19BUjUzMTJfUkVTRVQ7
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAodG9fcGxhdGZvcm1fZGV2
aWNlKGFoLT5haF9zYy0+ZGV2KS0+aWQgPT0gMCkgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKG1hc2sgJiBBUjVLX1JFU0VUX0NUTF9NQUMpCj4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCB2YWwgfD0gQVI1S19BUjUzMTJfUkVTRVRfV01BQzA7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAobWFzayAmIEFSNUtfUkVTRVRfQ1RMX0JBU0VC
QU5EKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgdmFsIHw9IEFSNUtfQVI1MzEyX1JFU0VUX0JCMF9DT0xEIHwKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgQVI1S19BUjUzMTJfUkVTRVRfQkIwX1dBUk07Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCB9IGVsc2Ugewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgaWYgKG1hc2sgJiBBUjVLX1JFU0VUX0NUTF9NQUMpCj4gKyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB2YWwgfD0gQVI1
S19BUjUzMTJfUkVTRVRfV01BQzE7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBpZiAobWFzayAmIEFSNUtfUkVTRVRfQ1RMX0JBU0VCQU5EKQo+ICsgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdmFs
IHw9IEFSNUtfQVI1MzEyX1JFU0VUX0JCMV9DT0xEIHwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19BUjUz
MTJfUkVTRVRfQkIxX1dBUk07Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4KPiAtIMKgIMKgIMKgIC8qIFdhaXQgYXQgbGVh
c3QgMTI4IFBDSSBjbG9ja3MgKi8KPiAtIMKgIMKgIMKgIHVkZWxheSgxNSk7Cj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCAvKiBQdXQgQkIvTUFDIGludG8gcmVzZXQgKi8KPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHJlZ3ZhbCA9IF9fcmF3X3JlYWRsKHJlZyk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDC
oCDCoCBfX3Jhd193cml0ZWwocmVndmFsIHwgdmFsLCByZWcpOwo+ICsgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgcmVndmFsID0gX19yYXdfcmVhZGwocmVnKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IHVkZWxheSgxMDApOwo+Cj4gLSDCoCDCoCDCoCBpZiAoYWgtPmFoX3ZlcnNpb24gPT0gQVI1S19B
UjUyMTApIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCAmPSBBUjVLX1JFU0VUX0NUTF9Q
Q1UgfCBBUjVLX1JFU0VUX0NUTF9ETUEKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIHwgQVI1S19SRVNFVF9DVExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+IC0gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgbWFzayAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NU
TF9ETUEKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwgQVI1S19SRVNFVF9D
VExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLyog
QnJpbmcgQkIvTUFDIG91dCBvZiByZXNldCAqLwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgX19y
YXdfd3JpdGVsKHJlZ3ZhbCAmIH52YWwsIHJlZyk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy
ZWd2YWwgPSBfX3Jhd19yZWFkbChyZWcpOwo+IMKgIMKgIMKgIMKgfSBlbHNlIHsKPiAtIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHZhbCAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NU
TF9CQVNFQkFORDsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1hc2sgJj0gQVI1S19SRVNFVF9D
VExfUENVIHwgQVI1S19SRVNFVF9DVExfQkFTRUJBTkQ7Cj4gLSDCoCDCoCDCoCB9Cj4KPiAtIMKg
IMKgIMKgIHJldCA9IGF0aDVrX2h3X3JlZ2lzdGVyX3RpbWVvdXQoYWgsIEFSNUtfUkVTRVRfQ1RM
LCBtYXNrLCB2YWwsIGZhbHNlKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGF0aDVrX2h3X3Jl
Z193cml0ZShhaCwgdmFsLCBBUjVLX1JFU0VUX0NUTCk7Cj4gKwo+ICsgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgLyogV2FpdCBhdCBsZWFzdCAxMjggUENJIGNsb2NrcyAqLwo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgdWRlbGF5KDE1KTsKPiArCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAoYWgt
PmFoX3ZlcnNpb24gPT0gQVI1S19BUjUyMTApIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHZhbCAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NUTF9ETUEK
PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwgQVI1S19S
RVNFVF9DVExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgbWFzayAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NU
TF9ETUEKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHwg
QVI1S19SRVNFVF9DVExfTUFDIHwgQVI1S19SRVNFVF9DVExfUEhZOwo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZh
bCAmPSBBUjVLX1JFU0VUX0NUTF9QQ1UgfCBBUjVLX1JFU0VUX0NUTF9CQVNFQkFORDsKPiArIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1hc2sgJj0gQVI1S19SRVNFVF9DVExfUENV
IHwgQVI1S19SRVNFVF9DVExfQkFTRUJBTkQ7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4g
Kwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfcmVnaXN0ZXJfdGltZW91
dChhaCwgQVI1S19SRVNFVF9DVEwsCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBtYXNrLCB2YWwsIGZhbHNlKTsKPiArIMKgIMKgIMKgIH0KPgoKSSB0aGlu
ayBpdCB3b3VsZCBiZSBtdWNoIGNsZWFuZXIgaWYgd2UgaGFkIGEgZGlmZmVyZW50IGZ1bmN0aW9u
IHRvCmhhbmRsZSB3aXNvYyByZXNldCBpbnN0ZWFkCm9mIHB1dHRpbmcgYm90aCBvbiBuaWNfcmVz
ZXQuIEhvdyBhYm91dCBoYXZpbmcgYSBhdGg1a19od193aXNvY19yZXNldAphbmQgY2FsbCB0aGF0
IGluc3RlYWQgPwoKPiDCoCDCoCDCoCDCoC8qCj4gwqAgwqAgwqAgwqAgKiBSZXNldCBjb25maWd1
cmF0aW9uIHJlZ2lzdGVyIChmb3IgaHcgYnl0ZS1zd2FwKS4gTm90ZSB0aGF0IHRoaXMKPiBAQCAt
MzM0LDYgKzM3OCw5IEBAIGludCBhdGg1a19od19vbl9ob2xkKHN0cnVjdCBhdGg1a19odyAqYWgp
Cj4gwqAgwqAgwqAgwqB1MzIgYnVzX2ZsYWdzOwo+IMKgIMKgIMKgIMKgaW50IHJldDsKPgo+ICsg
wqAgwqAgwqAgaWYgKGF0aDVrX2dldF9idXNfdHlwZShhaCkgPT0gQVRIX0FIQikKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHJldHVybiAwOwo+ICsKPiDCoCDCoCDCoCDCoC8qIE1ha2Ugc3VyZSBk
ZXZpY2UgaXMgYXdha2UgKi8KPiDCoCDCoCDCoCDCoHJldCA9IGF0aDVrX2h3X3NldF9wb3dlcihh
aCwgQVI1S19QTV9BV0FLRSwgdHJ1ZSwgMCk7Cj4gwqAgwqAgwqAgwqBpZiAocmV0KSB7Cj4gQEAg
LTM5MCwyMiArNDM3LDMwIEBAIGludCBhdGg1a19od19uaWNfd2FrZXVwKHN0cnVjdCBhdGg1a19o
dyAqYWgsIGludCBmbGFncywgYm9vbCBpbml0aWFsKQo+IMKgIMKgIMKgIMKgbW9kZSA9IDA7Cj4g
wqAgwqAgwqAgwqBjbG9jayA9IDA7Cj4KPiAtIMKgIMKgIMKgIC8qIFdha2V1cCB0aGUgZGV2aWNl
ICovCj4gLSDCoCDCoCDCoCByZXQgPSBhdGg1a19od19zZXRfcG93ZXIoYWgsIEFSNUtfUE1fQVdB
S0UsIHRydWUsIDApOwo+IC0gwqAgwqAgwqAgaWYgKHJldCkgewo+IC0gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgQVRINUtfRVJSKGFoLT5haF9zYywgImZhaWxlZCB0byB3YWtldXAgdGhlIE1BQyBDaGlw
XG4iKTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiByZXQ7Cj4gKyDCoCDCoCDCoCBp
ZiAoYXRoNWtfZ2V0X2J1c190eXBlKGFoKSA9PSBBVEhfQUhCICYmICFpbml0aWFsKSB7Cj4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCAvKiBXYWtldXAgdGhlIGRldmljZSAqLwo+ICsgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgcmV0ID0gYXRoNWtfaHdfc2V0X3Bvd2VyKGFoLCBBUjVLX1BNX0FXQUtFLCB0
cnVlLCAwKTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChyZXQpIHsKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaC0+YWhfc2MsICJmYWlsZWQgdG8g
d2FrZXVwIHRoZSBNQUMgQ2hpcFxuIik7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCByZXR1cm4gcmV0Owo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfQo+IMKgIMKgIMKgIMKg
fQo+CgpZb3Ugb25seSBjYWxsIGF0aDVrX2h3X3NldF9wb3dlciBmb3IgQUhCIGRldmljZXMgdGhp
cyB3YXkgIQoKPiDCoCDCoCDCoCDCoC8qCj4gwqAgwqAgwqAgwqAgKiBQdXQgY2hpcHNldCBvbiB3
YXJtIHJlc2V0Li4uCj4gwqAgwqAgwqAgwqAgKgo+IC0gwqAgwqAgwqAgwqAqIE5vdGU6IHB1dHRp
bmcgUENJIGNvcmUgb24gd2FybSByZXNldCBvbiBQQ0ktRSBjYXJkcwo+IC0gwqAgwqAgwqAgwqAq
IHJlc3VsdHMgY2FyZCB0byBoYW5nIGFuZCBhbHdheXMgcmV0dXJuIDB4ZmZmZi4uLiBzbwo+IC0g
wqAgwqAgwqAgwqAqIHdlIGluZ29yZSB0aGF0IGZsYWcgZm9yIFBDSS1FIGNhcmRzLiBPbiBQQ0kg
Y2FyZHMKPiAtIMKgIMKgIMKgIMKgKiB0aGlzIGZsYWcgZ2V0cyBjbGVhcmVkIGFmdGVyIDY0IFBD
SSBjbG9ja3MuCj4gwqAgwqAgwqAgwqAgKi8KPiAtIMKgIMKgIMKgIGJ1c19mbGFncyA9IChwZGV2
ICYmIHBkZXYtPmlzX3BjaWUpID8gMCA6IEFSNUtfUkVTRVRfQ1RMX1BDSTsKPiArIMKgIMKgIMKg
IGlmIChhdGg1a19nZXRfYnVzX3R5cGUoYWgpID09IEFUSF9BSEIpIHsKPiArIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIC8qIFJlc2V0IE1BQyBvbiBXaVNvYyBkZXZpY2VzICovCj4gKyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCBidXNfZmxhZ3MgPSAoaW5pdGlhbCkgPyBBUjVLX1JFU0VUX0NUTF9NQUMgOiAw
Owo+ICsgwqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC8qIE5vdGU6
IHB1dHRpbmcgUENJIGNvcmUgb24gd2FybSByZXNldCBvbiBQQ0ktRSBjYXJkcwo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAqIHJlc3VsdHMgY2FyZCB0byBoYW5nIGFuZCBhbHdheXMgcmV0dXJu
IDB4ZmZmZi4uLiBzbwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqIHdlIGluZ29yZSB0aGF0
IGZsYWcgZm9yIFBDSS1FIGNhcmRzLiBPbiBQQ0kgY2FyZHMKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgKiB0aGlzIGZsYWcgZ2V0cyBjbGVhcmVkIGFmdGVyIDY0IFBDSSBjbG9ja3MuCj4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCovCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBidXNfZmxh
Z3MgPSAocGRldiAmJiBwZGV2LT5pc19wY2llKSA/IDAgOiBBUjVLX1JFU0VUX0NUTF9QQ0k7Cj4g
KyDCoCDCoCDCoCB9Cj4KClRoaXMgaXMgd3JvbmcuLi4KI2RlZmluZSBBUjVLX1JFU0VUX0NUTF9N
QUMgICAgICAweDAwMDAwMDA0ICAgICAgLyogTUFDIHJlc2V0CihQQ1UrQmFzZWJhbmQgPykgWzUy
MTBdICovCnRoaXMgYml0IHdhcyBvbmx5IGF2YWlsYWJsZSBvbiBlYXJsaWVyIGNoaXBzLiBUbyBy
ZXNldCBtYWMgb24gbGF0ZXIKY2hpcHMgKFdpU29DIHRvbykgeW91IG5lZWQgdG8gdXNlCkFSNUtf
UkVTRVRfQ1RMX1BDVSAgYW5kIHdlIGFscmVhZHkgZG8gdGhhdCBiZWxvdy4KClRoaXMgaXMgc29t
ZXRoaW5nIEkgaGF2ZSB0byBjbGVhbiB1cCBhY3R1YWxseSwgYml0IDAgaXMgcmVzZXQgbWFjCihi
b3RoIFBDVSArIERNQSkgYW5kIGJpdCAxIHJlc2V0cyBCYXNlYmFuZC4gTm90ZSB0aGVyZSBpcyBw
b29yCmRvY3VtZW50YXRpb24gb24gdGhhdCwgZG9jdW1lbnRhdGlvbiBvbiBBUjIzMTcgZWcuIHNh
eXMgbWFjIHJlc2V0IGZvcgpiaXQgMCBhbmQgIndhcm0gcmVzZXQgdG8gYmFzZWJhbmQgbG9naWMi
IGZvciBiaXQgMSAod2hpY2ggaXMgY29ycmVjdCkKYnV0IG9uIGRlc2NyaXB0aW9uIGZvciBiaXQg
MSBzYXlzICJQQ1UgYW5kIERNQSBidXQgbm90IGJhc2ViYW5kIgoodGhhdCdzIGFjdHVhbGx5IHRo
ZSBkZXNjcmlwdGlvbiBvZiBiaXQgMCkgYW5kIGFib3ZlIHNheXMgImluIG9yZGVyIHRvCnJlc2V0
IGJvdGggYmFzZWJhbmQgYW5kIG1hYyBhbmQgcGNpIHdyaXRlIDB4MTMiICgweDEwIGlzIHBjaSkg
dGhhdApkb2Vzbid0IG1ha2Ugc2Vuc2UgYmVjYXVzZSBhY2NvcmRpbmcgdG8gZGVzY3JpcHRpb25z
IG5vbmUgb2YgdGhlIDIKZmlyc3QgYml0cyByZXNldHMgYmFzZWJhbmQgOlAgSWYgeW91IGdvIG9u
IEFSNTIxMywgZG9jdW1lbnRhdGlvbiBpcwpjb3JyZWN0LCBpdCBzYXlzIHRoYXQgYml0IDAgaXMg
Zm9yIFBDVSBhbmQgRE1BIGFuZCBiaXQgMSBpcyBmb3IKYmFzZWJhbmQgYW5kIHRoYXQgYWxzbyB3
b3JrcyBvbiBhbGwgcG9zdC01MjExIGNoaXBzLiBUaGF0J3Mgd2h5IEkndmUKcHV0IHRoZSBjb21t
ZW50cyBvbiByZWcuaCwgYWxsIFs1MjEwXSBhcmUgb25seSBhdmFpbGFibGUgb24gQVI1MjEwLApv
bmx5IGJpdHMvcmVnaXN0ZXJzIG1hcmtlZCB3aXRoIFs1MjExK10gYXJlIGF2YWlsYWJsZSBvbiBs
YXRlciBtYWNzLgoKU28gd2hhdCB5b3UgYXJlIHJlYWxseSBkb2luZyBoZXJlIGlzIGFjdGl2YXRl
IGJpdCAzIHRoYXQgaXMgcmVzZXJ2ZWQKYWNjb3JkaW5nIHRvIGRvY3MgYW5kIHNob3VsZCBiZSB6
ZXJvZWQgISBXZSBhbHJlYWR5IGRvIHdoYXQncyBuZWVkZWQKdG8gcmVzZXQgYm90aCBtYWMgYW5k
IGJhc2ViYW5kIGxhdGVyLgoKdmFsICY9IEFSNUtfUkVTRVRfQ1RMX1BDVSB8IEFSNUtfUkVTRVRf
Q1RMX0JBU0VCQU5EOwoKTm90aWNlIHRoYXQgQVI1S19SRVNFVF9DVExfUENVIHwgQVI1S19SRVNF
VF9DVExfQkFTRUJBTkQgPSAweDEzIGFzCmRvY3VtZW50YXRpb24gc3VnZ2VzdHMuCgo+IMKgIMKg
IMKgIMKgaWYgKGFoLT5haF92ZXJzaW9uID09IEFSNUtfQVI1MjEwKSB7Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqByZXQgPSBhdGg1a19od19uaWNfcmVzZXQoYWgsIEFSNUtfUkVTRVRfQ1RMX1BD
VSB8Cj4gQEAgLTUzNiw2ICs1OTEsOSBAQCBzdGF0aWMgdm9pZCBhdGg1a19od19zZXRfc2xlZXBf
Y2xvY2soc3RydWN0IGF0aDVrX2h3ICphaCwgYm9vbCBlbmFibGUpCj4gwqAgwqAgwqAgwqBzdHJ1
Y3QgYXRoNWtfZWVwcm9tX2luZm8gKmVlID0gJmFoLT5haF9jYXBhYmlsaXRpZXMuY2FwX2VlcHJv
bTsKPiDCoCDCoCDCoCDCoHUzMiBzY2FsLCBzcGVuZGluZywgdXNlYzMyOwo+Cj4gKyDCoCDCoCDC
oCBpZiAoYXRoNWtfZ2V0X2J1c190eXBlKGFoKSA9PSBBVEhfQUhCKQo+ICsgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgZW5hYmxlID0gZmFsc2U7Cj4gKwo+IMKgIMKgIMKgIMKgLyogT25seSBzZXQgMzJL
SHogc2V0dGluZ3MgaWYgd2UgaGF2ZSBhbiBleHRlcm5hbAo+IMKgIMKgIMKgIMKgICogMzJLSHog
Y3J5c3RhbCBwcmVzZW50ICovCj4gwqAgwqAgwqAgwqBpZiAoKEFSNUtfRUVQUk9NX0hBUzMyS0ha
Q1JZU1RBTChlZS0+ZWVfbWlzYzEpIHx8Cj4gQEAgLTYwNyw2ICs2NjUsNyBAQCBzdGF0aWMgdm9p
ZCBhdGg1a19od19zZXRfc2xlZXBfY2xvY2soc3RydWN0IGF0aDVrX2h3ICphaCwgYm9vbCBlbmFi
bGUpCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICgoYWgtPmFoX3JhZGlvID09IEFSNUtf
UkY1MTEyKSB8fAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKGFoLT5haF9yYWRpbyA9PSBBUjVL
X1JGNTQxMykgfHwKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChhaC0+YWhfcmFkaW8gPT0gQVI1
S19SRjIzMTYpIHx8Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoYWgtPmFoX21hY192ZXJzaW9u
ID09IChBUjVLX1NSRVZfQVIyNDE3ID4+IDQpKSkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoHNwZW5kaW5nID0gMHgxNDsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVsc2UK
PiBAQCAtNjE0LDcgKzY3Myw5IEBAIHN0YXRpYyB2b2lkIGF0aDVrX2h3X3NldF9zbGVlcF9jbG9j
ayhzdHJ1Y3QgYXRoNWtfaHcgKmFoLCBib29sIGVuYWJsZSkKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoGF0aDVrX2h3X3JlZ193cml0ZShhaCwgc3BlbmRpbmcsIEFSNUtfUEhZX1NQRU5ESU5HKTsK
Pgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKChhaC0+YWhfcmFkaW8gPT0gQVI1S19SRjUx
MTIpIHx8Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoYWgtPmFoX3JhZGlvID09IEFSNUtfUkY1
NDEzKSkKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChhaC0+YWhfcmFkaW8gPT0gQVI1S19SRjU0
MTMpIHx8Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoYWgtPmFoX3JhZGlvID09IEFSNUtfUkYy
MzE2KSB8fAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGFoLT5haF9yYWRpbyA9PSBBUjVLX1JG
MjMxNykpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1c2VjMzIgPSAzOTsK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVsc2UKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoHVzZWMzMiA9IDMxOwo+IEBAIC02NzgsNyArNzM5LDggQEAgc3RhdGljIHZvaWQg
YXRoNWtfaHdfdHdlYWtfaW5pdHZhbF9zZXR0aW5ncyhzdHJ1Y3QgYXRoNWtfaHcgKmFoLAo+Cj4g
wqAgwqAgwqAgwqAvKiBTZXQgZmFzdCBBREMgKi8KPiDCoCDCoCDCoCDCoGlmICgoYWgtPmFoX3Jh
ZGlvID09IEFSNUtfUkY1NDEzKSB8fAo+IC0gwqAgwqAgwqAgKGFoLT5haF9tYWNfdmVyc2lvbiA9
PSAoQVI1S19TUkVWX0FSMjQxNyA+PiA0KSkpIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChh
aC0+YWhfcmFkaW8gPT0gQVI1S19SRjIzMTcpIHx8Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCAo
YWgtPmFoX21hY192ZXJzaW9uID09IChBUjVLX1NSRVZfQVIyNDE3ID4+IDQpKSkgewo+IMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgdTMyIGZhc3RfYWRjID0gdHJ1ZTsKPgo+IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgaWYgKGNoYW5uZWwtPmNlbnRlcl9mcmVxID09IDI0NjIgfHwKPiAtLQo+IDEuNy4x
Cj4KPiAtLQo+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1
bnN1YnNjcmliZSBsaW51eC13aXJlbGVzcyIgaW4KPiB0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8g
bWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZwo+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgwqBodHRw
Oi8vdmdlci5rZXJuZWwub3JnL21ham9yZG9tby1pbmZvLmh0bWwKPgoKCgotLSAKR1BHIElEOiAw
eEQyMURCMkRCCkFzIHlvdSByZWFkIHRoaXMgcG9zdCBnbG9iYWwgZW50cm9weSByaXNlcy4gSGF2
ZSBGdW4gOy0pCk5pY2sK

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices.
       [not found] <31403932.141291029281159.JavaMail.wlan@CHBU500181>
@ 2010-11-29 11:19 ` Wojciech Dubowik
  0 siblings, 0 replies; 3+ messages in thread
From: Wojciech Dubowik @ 2010-11-29 11:19 UTC (permalink / raw)
  To: Nick Kossifidis; +Cc: linux-wireless, nbd, ath5k-devel

> 2010/11/26 Wojciech Dubowik <dubowoj@neratec.com>:
> > From: Felix Fietkau <nbd@openwrt.org>
> >
> > On WiSoc we cannot access mac register before it is resetted.
> > It will crash hardware otherwise.
> >
> > Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> > Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
> > ---
> >  drivers/net/wireless/ath/ath5k/base.c  |    7 ++-
> >  drivers/net/wireless/ath/ath5k/reset.c |  114
> ++++++++++++++++++++++++-------
> >  2 files changed, 94 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/ath5k/base.c
> b/drivers/net/wireless/ath/ath5k/base.c
> > index 4d5ac71..87a4bb6 100644
> > --- a/drivers/net/wireless/ath/ath5k/base.c
> > +++ b/drivers/net/wireless/ath/ath5k/base.c
> > @@ -2169,7 +2169,8 @@ ath5k_intr(int irq, void *dev_id)
> >        unsigned int counter = 1000;
> >
> >        if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
> > -                               !ath5k_hw_is_intr_pending(ah)))
> > +               ((ath5k_get_bus_type(ah) != ATH_AHB) &&
> > +                               !ath5k_hw_is_intr_pending(ah))))
> >                return IRQ_NONE;
> >
> >        do {
> > @@ -2235,6 +2236,10 @@ ath5k_intr(int irq, void *dev_id)
> >                              
>  tasklet_schedule(&sc->rf_kill.toggleq);
> >
> >                }
> > +
> > +               if (ath5k_get_bus_type(ah) == ATH_AHB)
> > +                       break;
> > +
> >        } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
> >
> >        if (unlikely(!counter))
> > diff --git a/drivers/net/wireless/ath/ath5k/reset.c
> b/drivers/net/wireless/ath/ath5k/reset.c
> > index 198a146..4f54655 100644
> > --- a/drivers/net/wireless/ath/ath5k/reset.c
> > +++ b/drivers/net/wireless/ath/ath5k/reset.c
> > @@ -27,6 +27,7 @@
> >
> >  #include <linux/pci.h>                 /* To determine if a card is
> pci-e */
> >  #include <linux/log2.h>
> > +#include <linux/platform_device.h>
> >  #include "ath5k.h"
> >  #include "reg.h"
> >  #include "base.h"
> > @@ -198,31 +199,74 @@ static inline void
> ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
> >  */
> >  static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
> >  {
> > -       int ret;
> > +       int ret = 0;
> >        u32 mask = val ? val : ~0U;
> >
> >        /* Read-and-clear RX Descriptor Pointer*/
> > -       ath5k_hw_reg_read(ah, AR5K_RXDP);
> > +       if (!(mask & AR5K_RESET_CTL_MAC))
> > +               ath5k_hw_reg_read(ah, AR5K_RXDP);
> >
> >        /*
> >         * Reset the device and wait until success
> >         */
> > -       ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
> > +       if (ath5k_get_bus_type(ah) == ATH_AHB) {
> > +               volatile u32 *reg;
> > +               u32 regval;
> > +               val = 0;
> > +
> > +               /* ah->ah_mac_srev is not available at this point
> yet */
> > +               if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
> > +                       reg = (u32 *) AR5K_AR2315_RESET;
> > +                       if (mask & AR5K_RESET_CTL_MAC)
> > +                               val |= AR5K_AR2315_RESET_WMAC;
> > +                       if (mask & AR5K_RESET_CTL_BASEBAND)
> > +                               val |= AR5K_AR2315_RESET_BB_WARM;
> > +               } else {
> > +                       reg = (u32 *) AR5K_AR5312_RESET;
> > +                       if (to_platform_device(ah->ah_sc->dev)->id
> == 0) {
> > +                               if (mask & AR5K_RESET_CTL_MAC)
> > +                                       val |=
> AR5K_AR5312_RESET_WMAC0;
> > +                               if (mask & AR5K_RESET_CTL_BASEBAND)
> > +                                       val |=
> AR5K_AR5312_RESET_BB0_COLD |
> > +                                            
>  AR5K_AR5312_RESET_BB0_WARM;
> > +                       } else {
> > +                               if (mask & AR5K_RESET_CTL_MAC)
> > +                                       val |=
> AR5K_AR5312_RESET_WMAC1;
> > +                               if (mask & AR5K_RESET_CTL_BASEBAND)
> > +                                       val |=
> AR5K_AR5312_RESET_BB1_COLD |
> > +                                            
>  AR5K_AR5312_RESET_BB1_WARM;
> > +                       }
> > +               }
> >
> > -       /* Wait at least 128 PCI clocks */
> > -       udelay(15);
> > +               /* Put BB/MAC into reset */
> > +               regval = __raw_readl(reg);
> > +               __raw_writel(regval | val, reg);
> > +               regval = __raw_readl(reg);
> > +               udelay(100);
> >
> > -       if (ah->ah_version == AR5K_AR5210) {
> > -               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
> > -                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
> > -               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
> > -                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
> > +               /* Bring BB/MAC out of reset */
> > +               __raw_writel(regval & ~val, reg);
> > +               regval = __raw_readl(reg);
> >        } else {
> > -               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
> > -               mask &= AR5K_RESET_CTL_PCU |
> AR5K_RESET_CTL_BASEBAND;
> > -       }
> >
> > -       ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask,
> val, false);
> > +               ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
> > +
> > +               /* Wait at least 128 PCI clocks */
> > +               udelay(15);
> > +
> > +               if (ah->ah_version == AR5K_AR5210) {
> > +                       val &= AR5K_RESET_CTL_PCU |
> AR5K_RESET_CTL_DMA
> > +                               | AR5K_RESET_CTL_MAC |
> AR5K_RESET_CTL_PHY;
> > +                       mask &= AR5K_RESET_CTL_PCU |
> AR5K_RESET_CTL_DMA
> > +                               | AR5K_RESET_CTL_MAC |
> AR5K_RESET_CTL_PHY;
> > +               } else {
> > +                       val &= AR5K_RESET_CTL_PCU |
> AR5K_RESET_CTL_BASEBAND;
> > +                       mask &= AR5K_RESET_CTL_PCU |
> AR5K_RESET_CTL_BASEBAND;
> > +               }
> > +
> > +               ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL,
> > +                               mask, val, false);
> > +       }
> >
> 
> I think it would be much cleaner if we had a different function to
> handle wisoc reset instead
> of putting both on nic_reset. How about having a ath5k_hw_wisoc_reset
> and call that instead ?

I will rework the reset functions and come up with the proposal. The only
problem is that I don't have AR2316 or AR2317 to test all the possible
paths. I have only AR5312/AR2313 and a bunch of miniPCI cards.

I will look whether I can find a cheap one for testing.

Wojtek

> 
> >        /*
> >         * Reset configuration register (for hw byte-swap). Note that
> this
> > @@ -334,6 +378,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
> >        u32 bus_flags;
> >        int ret;
> >
> > +       if (ath5k_get_bus_type(ah) == ATH_AHB)
> > +               return 0;
> > +
> >        /* Make sure device is awake */
> >        ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
> >        if (ret) {
> > @@ -390,22 +437,30 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah,
> int flags, bool initial)
> >        mode = 0;
> >        clock = 0;
> >
> > -       /* Wakeup the device */
> > -       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;
> > +       if (ath5k_get_bus_type(ah) == ATH_AHB && !initial) {
> > +               /* Wakeup the device */
> > +               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;
> > +               }
> >        }
> >
> 
> You only call ath5k_hw_set_power for AHB devices this way !
> 
> >        /*
> >         * Put chipset on warm reset...
> >         *
> > -        * Note: putting 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 && pdev->is_pcie) ? 0 :
> AR5K_RESET_CTL_PCI;
> > +       if (ath5k_get_bus_type(ah) == ATH_AHB) {
> > +               /* Reset MAC on WiSoc devices */
> > +               bus_flags = (initial) ? AR5K_RESET_CTL_MAC : 0;
> > +       } else {
> > +               /* Note: putting 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 && pdev->is_pcie) ? 0 :
> AR5K_RESET_CTL_PCI;
> > +       }
> >
> 
> This is wrong...
> #define AR5K_RESET_CTL_MAC      0x00000004      /* MAC reset
> (PCU+Baseband ?) [5210] */
> this bit was only available on earlier chips. To reset mac on later
> chips (WiSoC too) you need to use
> AR5K_RESET_CTL_PCU  and we already do that below.
> 
> This is something I have to clean up actually, bit 0 is reset mac
> (both PCU + DMA) and bit 1 resets Baseband. Note there is poor
> documentation on that, documentation on AR2317 eg. says mac reset for
> bit 0 and "warm reset to baseband logic" for bit 1 (which is correct)
> but on description for bit 1 says "PCU and DMA but not baseband"
> (that's actually the description of bit 0) and above says "in order to
> reset both baseband and mac and pci write 0x13" (0x10 is pci) that
> doesn't make sense because according to descriptions none of the 2
> first bits resets baseband :P If you go on AR5213, documentation is
> correct, it says that bit 0 is for PCU and DMA and bit 1 is for
> baseband and that also works on all post-5211 chips. That's why I've
> put the comments on reg.h, all [5210] are only available on AR5210,
> only bits/registers marked with [5211+] are available on later macs.
> 
> So what you are really doing here is activate bit 3 that is reserved
> according to docs and should be zeroed ! We already do what's needed
> to reset both mac and baseband later.
> 
> val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
> 
> Notice that AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND = 0x13 as
> documentation suggests.
> 

Need to study documentation for this part. Till now it was more of the
trial and error.

Wojtek

> >        if (ah->ah_version == AR5K_AR5210) {
> >                ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
> > @@ -536,6 +591,9 @@ static void ath5k_hw_set_sleep_clock(struct
> ath5k_hw *ah, bool enable)
> >        struct ath5k_eeprom_info *ee =
> &ah->ah_capabilities.cap_eeprom;
> >        u32 scal, spending, usec32;
> >
> > +       if (ath5k_get_bus_type(ah) == ATH_AHB)
> > +               enable = false;
> > +
> >        /* Only set 32KHz settings if we have an external
> >         * 32KHz crystal present */
> >        if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
> > @@ -607,6 +665,7 @@ static void ath5k_hw_set_sleep_clock(struct
> ath5k_hw *ah, bool enable)
> >
> >                if ((ah->ah_radio == AR5K_RF5112) ||
> >                (ah->ah_radio == AR5K_RF5413) ||
> > +               (ah->ah_radio == AR5K_RF2316) ||
> >                (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
> >                        spending = 0x14;
> >                else
> > @@ -614,7 +673,9 @@ static void ath5k_hw_set_sleep_clock(struct
> ath5k_hw *ah, bool enable)
> >                ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
> >
> >                if ((ah->ah_radio == AR5K_RF5112) ||
> > -               (ah->ah_radio == AR5K_RF5413))
> > +               (ah->ah_radio == AR5K_RF5413) ||
> > +               (ah->ah_radio == AR5K_RF2316) ||
> > +               (ah->ah_radio == AR5K_RF2317))
> >                        usec32 = 39;
> >                else
> >                        usec32 = 31;
> > @@ -678,7 +739,8 @@ static void
> ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
> >
> >        /* Set fast ADC */
> >        if ((ah->ah_radio == AR5K_RF5413) ||
> > -       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
> > +               (ah->ah_radio == AR5K_RF2317) ||
> > +               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
> >                u32 fast_adc = true;
> >
> >                if (channel->center_freq == 2462 ||
> > --
> > 1.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> linux-wireless" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 
> 
> 
> --
> GPG ID: 0xD21DB2DB
> As you read this post global entropy rises. Have Fun ;-)
> Nick

-- 
Wojciech Dubowik
Senior Software Engineer
Neratec Solutions AG
Rosswiesstr. 29, CH-8608 Bubikon, Switzerland
Tel: +41 55 253 2096 (office)
Fax: +41 55 253 2070
wojciech.dubowik@neratec.com
http://www.neratec.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-11-29 11:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <28511431.361290765324515.JavaMail.wlan@CHBU500181>
2010-11-26  9:57 ` [PATCH v6 9/9] ath5k: Fix reset and interrupts for AHB type of devices Wojciech Dubowik
2010-11-27  0:29   ` Nick Kossifidis
     [not found] <31403932.141291029281159.JavaMail.wlan@CHBU500181>
2010-11-29 11:19 ` Wojciech Dubowik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.