From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E225C43467 for ; Thu, 8 Oct 2020 11:33:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B30992145D for ; Thu, 8 Oct 2020 11:33:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="ElOtw1BR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729851AbgJHLdd (ORCPT ); Thu, 8 Oct 2020 07:33:33 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:33957 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725900AbgJHLdb (ORCPT ); Thu, 8 Oct 2020 07:33:31 -0400 X-UUID: 959b5ef85c274479bbbbd0f86559a60f-20201008 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=UisLcbrPlbx7LpeQVyT9OpVv91AaDRogMFoMs4nSJE8=; b=ElOtw1BRZMQ17mh9/sF7aKwIhul1YX+Ay6K87wj+q9N8CSeJZSqdsv5wEJXCq6b29vaIdf3kAgM+0q0ysEsnrzAeMXD3od1DZx7/14c85+68VXHsPDF9uUD7I8bZAKnOttQtku10hFQeR7GHZaW75bd30GNwI0SIIGhOG4ZHE2M=; X-UUID: 959b5ef85c274479bbbbd0f86559a60f-20201008 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 350107183; Thu, 08 Oct 2020 19:33:16 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 8 Oct 2020 19:33:13 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 8 Oct 2020 19:33:14 +0800 From: Shayne Chen To: Felix Fietkau CC: linux-wireless , Lorenzo Bianconi , Ryder Lee , Evelyn Tsai , linux-mediatek , Shayne Chen Subject: [PATCH 07/10] mt76: mt7915: implement testmode tx support Date: Thu, 8 Oct 2020 19:29:01 +0800 Message-ID: <20201008112904.10620-7-shayne.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20201008112904.10620-1-shayne.chen@mediatek.com> References: <20201008112904.10620-1-shayne.chen@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-SNTS-SMTP: F86A9544CE129FA3C8FF62FCBD9768F316A3B92F4206C69458FC30572727BC6C2000:8 X-MTK: N Content-Transfer-Encoding: base64 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org U3VwcG9ydCB0ZXN0bW9kZSB0eCBmb3IgTVQ3OTE1QSwgaW5jbHVkaW5nIHR4IHN0cmVhbXMgYW5k IEhFIHJhdGUNCnNldHRpbmdzLg0KDQpTaWduZWQtb2ZmLWJ5OiBTaGF5bmUgQ2hlbiA8c2hheW5l LmNoZW5AbWVkaWF0ZWsuY29tPg0KUmV2aWV3ZWQtYnk6IFJ5ZGVyIExlZSA8cnlkZXIubGVlQG1l ZGlhdGVrLmNvbT4NCi0tLQ0KIC4uLi93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9NYWtl ZmlsZSAgICB8ICAgMiArDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9p bml0LmMgIHwgICA0ICsNCiAuLi4vbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21h Yy5jICAgfCAxMjcgKysrKysrKysrKysrDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2 L210NzkxNS9tYWluLmMgIHwgIDQwICsrKy0NCiAuLi4vbmV0L3dpcmVsZXNzL21lZGlhdGVrL210 NzYvbXQ3OTE1L21jdS5jICAgfCAgMzEgKysrDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9t dDc2L210NzkxNS9tY3UuaCAgIHwgICA1ICsNCiAuLi4vd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9t dDc5MTUvbXQ3OTE1LmggICAgfCAgMTQgKysNCiAuLi4vbmV0L3dpcmVsZXNzL21lZGlhdGVrL210 NzYvbXQ3OTE1L3JlZ3MuaCAgfCAgMzEgKysrDQogLi4uL3dpcmVsZXNzL21lZGlhdGVrL210NzYv bXQ3OTE1L3Rlc3Rtb2RlLmMgIHwgMTgwICsrKysrKysrKysrKysrKysrKw0KIC4uLi93aXJlbGVz cy9tZWRpYXRlay9tdDc2L210NzkxNS90ZXN0bW9kZS5oICB8ICAzNCArKysrDQogMTAgZmlsZXMg Y2hhbmdlZCwgNDYyIGluc2VydGlvbnMoKyksIDYgZGVsZXRpb25zKC0pDQogY3JlYXRlIG1vZGUg MTAwNjQ0IGRyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L3Rlc3Rtb2Rl LmMNCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3 Ni9tdDc5MTUvdGVzdG1vZGUuaA0KDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2lyZWxlc3Mv bWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvTWFrZWZpbGUgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRp YXRlay9tdDc2L210NzkxNS9NYWtlZmlsZQ0KaW5kZXggNTdmZTcyNi4uY2MyMDU0ZCAxMDA2NDQN Ci0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L01ha2VmaWxl DQorKysgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9NYWtlZmls ZQ0KQEAgLTQsMyArNCw1IEBAIG9iai0kKENPTkZJR19NVDc5MTVFKSArPSBtdDc5MTVlLm8NCiAN CiBtdDc5MTVlLXkgOj0gcGNpLm8gaW5pdC5vIGRtYS5vIGVlcHJvbS5vIG1haW4ubyBtY3UubyBt YWMubyBcDQogCSAgICAgZGVidWdmcy5vDQorDQorbXQ3OTE1ZS0kKENPTkZJR19OTDgwMjExX1RF U1RNT0RFKSArPSB0ZXN0bW9kZS5vDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2lyZWxlc3Mv bWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvaW5pdC5jIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0 ZWsvbXQ3Ni9tdDc5MTUvaW5pdC5jDQppbmRleCBlZTY5ZmU0Li4zOTBiMzI4IDEwMDY0NA0KLS0t IGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvaW5pdC5jDQorKysg Yi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9pbml0LmMNCkBAIC02 OTUsNiArNjk1LDEwIEBAIGludCBtdDc5MTVfcmVnaXN0ZXJfZGV2aWNlKHN0cnVjdCBtdDc5MTVf ZGV2ICpkZXYpDQogCW10NzkxNV9jYXBfZGJkY19kaXNhYmxlKGRldik7DQogCWRldi0+cGh5LmRm c19zdGF0ZSA9IC0xOw0KIA0KKyNpZmRlZiBDT05GSUdfTkw4MDIxMV9URVNUTU9ERQ0KKwlkZXYt Pm10NzYudGVzdF9vcHMgPSAmbXQ3OTE1X3Rlc3Rtb2RlX29wczsNCisjZW5kaWYNCisNCiAJcmV0 ID0gbXQ3Nl9yZWdpc3Rlcl9kZXZpY2UoJmRldi0+bXQ3NiwgdHJ1ZSwgbXQ3OTE1X3JhdGVzLA0K IAkJCQkgICBBUlJBWV9TSVpFKG10NzkxNV9yYXRlcykpOw0KIAlpZiAocmV0KQ0KZGlmZiAtLWdp dCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21hYy5jIGIvZHJp dmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWFjLmMNCmluZGV4IGE3MTE4 ZGYuLmUwM2UxMmYgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9t dDc2L210NzkxNS9tYWMuYw0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3 Ni9tdDc5MTUvbWFjLmMNCkBAIC01NjIsNiArNTYyLDExOCBAQCBpbnQgbXQ3OTE1X21hY19maWxs X3J4KHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHN0cnVjdCBza19idWZmICpza2IpDQogCXJldHVy biAwOw0KIH0NCiANCitzdGF0aWMgdTE2DQorbXQ3OTE1X21hY190eF9yYXRlX3ZhbChzdHJ1Y3Qg bXQ3Nl9waHkgKm1waHksIHU4IG1vZGUsIHU4IHJhdGVfaWR4LA0KKwkJICAgICAgIHU4IG5zcywg dTggc3RiYywgdTggKmJ3KQ0KK3sNCisJdTE2IHJhdGV2YWw7DQorDQorCXN3aXRjaCAobXBoeS0+ Y2hhbmRlZi53aWR0aCkgew0KKwljYXNlIE5MODAyMTFfQ0hBTl9XSURUSF80MDoNCisJCSpidyA9 IDE7DQorCQlicmVhazsNCisJY2FzZSBOTDgwMjExX0NIQU5fV0lEVEhfODA6DQorCQkqYncgPSAy Ow0KKwkJYnJlYWs7DQorCWNhc2UgTkw4MDIxMV9DSEFOX1dJRFRIXzgwUDgwOg0KKwljYXNlIE5M ODAyMTFfQ0hBTl9XSURUSF8xNjA6DQorCQkqYncgPSAzOw0KKwkJYnJlYWs7DQorCWRlZmF1bHQ6 DQorCQkqYncgPSAwOw0KKwkJYnJlYWs7DQorCX0NCisNCisJaWYgKG1vZGUgPT0gTVRfUEhZX1RZ UEVfSFQgfHwgbW9kZSA9PSBNVF9QSFlfVFlQRV9IVF9HRikNCisJCW5zcyA9IDEgKyAocmF0ZV9p ZHggPj4gMyk7DQorDQorCXJhdGV2YWwgPSBGSUVMRF9QUkVQKE1UX1RYX1JBVEVfSURYLCByYXRl X2lkeCkgfA0KKwkJICBGSUVMRF9QUkVQKE1UX1RYX1JBVEVfTU9ERSwgbW9kZSkgfA0KKwkJICBG SUVMRF9QUkVQKE1UX1RYX1JBVEVfTlNTLCBuc3MgLSAxKTsNCisNCisJaWYgKHN0YmMgJiYgbnNz ID09IDEpIHsNCisJCW5zcysrOw0KKwkJcmF0ZXZhbCB8PSBNVF9UWF9SQVRFX1NUQkM7DQorCX0N CisNCisJcmV0dXJuIHJhdGV2YWw7DQorfQ0KKw0KK3N0YXRpYyB2b2lkDQorbXQ3OTE1X21hY193 cml0ZV90eHdpX3RtKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHN0cnVjdCBtdDc2X3BoeSAqbXBo eSwNCisJCQkgX19sZTMyICp0eHdpLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQ0KK3sNCisjaWZkZWYg Q09ORklHX05MODAyMTFfVEVTVE1PREUNCisJc3RydWN0IG10NzZfdGVzdG1vZGVfZGF0YSAqdGQg PSAmZGV2LT5tdDc2LnRlc3Q7DQorCXU4IGJ3LCBtb2RlOw0KKwl1MTYgcmF0ZXZhbDsNCisJdTMy IHZhbDsNCisNCisJaWYgKHNrYiAhPSBkZXYtPm10NzYudGVzdC50eF9za2IpDQorCQlyZXR1cm47 DQorDQorCXN3aXRjaCAodGQtPnR4X3JhdGVfbW9kZSkgew0KKwljYXNlIE1UNzZfVE1fVFhfTU9E RV9DQ0s6DQorCQltb2RlID0gTVRfUEhZX1RZUEVfQ0NLOw0KKwkJYnJlYWs7DQorCWNhc2UgTVQ3 Nl9UTV9UWF9NT0RFX0hUOg0KKwkJbW9kZSA9IE1UX1BIWV9UWVBFX0hUOw0KKwkJYnJlYWs7DQor CWNhc2UgTVQ3Nl9UTV9UWF9NT0RFX1ZIVDoNCisJCW1vZGUgPSBNVF9QSFlfVFlQRV9WSFQ7DQor CQlicmVhazsNCisJY2FzZSBNVDc2X1RNX1RYX01PREVfSEVfU1U6DQorCQltb2RlID0gTVRfUEhZ X1RZUEVfSEVfU1U7DQorCQlicmVhazsNCisJY2FzZSBNVDc2X1RNX1RYX01PREVfSEVfRVhUX1NV Og0KKwkJbW9kZSA9IE1UX1BIWV9UWVBFX0hFX0VYVF9TVTsNCisJCWJyZWFrOw0KKwljYXNlIE1U NzZfVE1fVFhfTU9ERV9IRV9UQjoNCisJCW1vZGUgPSBNVF9QSFlfVFlQRV9IRV9UQjsNCisJCWJy ZWFrOw0KKwljYXNlIE1UNzZfVE1fVFhfTU9ERV9IRV9NVToNCisJCW1vZGUgPSBNVF9QSFlfVFlQ RV9IRV9NVTsNCisJCWJyZWFrOw0KKwljYXNlIE1UNzZfVE1fVFhfTU9ERV9PRkRNOg0KKwlkZWZh dWx0Og0KKwkJbW9kZSA9IE1UX1BIWV9UWVBFX09GRE07DQorCQlicmVhazsNCisJfQ0KKw0KKwly YXRldmFsID0gbXQ3OTE1X21hY190eF9yYXRlX3ZhbChtcGh5LCBtb2RlLCB0ZC0+dHhfcmF0ZV9p ZHgsDQorCQkJCQkgdGQtPnR4X3JhdGVfbnNzLCB0ZC0+dHhfcmF0ZV9zdGJjLCAmYncpOw0KKw0K Kwl0eHdpWzJdIHw9IGNwdV90b19sZTMyKE1UX1RYRDJfRklYX1JBVEUpOw0KKwlpZiAodGQtPnR4 X3JhdGVfbW9kZSA8IE1UNzZfVE1fVFhfTU9ERV9IVCkNCisJCXR4d2lbM10gfD0gY3B1X3RvX2xl MzIoTVRfVFhEM19CQV9ESVNBQkxFKTsNCisNCisJdmFsID0gTVRfVFhENl9GSVhFRF9CVyB8DQor CSAgICAgIEZJRUxEX1BSRVAoTVRfVFhENl9CVywgYncpIHwNCisJICAgICAgRklFTERfUFJFUChN VF9UWEQ2X1RYX1JBVEUsIHJhdGV2YWwpIHwNCisJICAgICAgRklFTERfUFJFUChNVF9UWEQ2X1NH SSwgdGQtPnR4X3JhdGVfc2dpKTsNCisNCisJLyogZm9yIEhFX1NVL0hFX0VYVF9TVSBQUERVDQor CSAqIC0gMXgsIDJ4LCA0eCBMVEYgKyAwLjh1cyBHSQ0KKwkgKiAtIDJ4IExURiArIDEuNnVzIEdJ LCA0eCBMVEYgKyAzLjJ1cyBHSQ0KKwkgKiBmb3IgSEVfTVUgUFBEVQ0KKwkgKiAtIDJ4LCA0eCBM VEYgKyAwLjh1cyBHSQ0KKwkgKiAtIDJ4IExURiArIDEuNnVzIEdJLCA0eCBMVEYgKyAzLjJ1cyBH SQ0KKwkgKiBmb3IgSEVfVEIgUFBEVQ0KKwkgKiAtIDF4LCAyeCBMVEYgKyAxLjZ1cyBHSQ0KKwkg KiAtIDR4IExURiArIDMuMnVzIEdJDQorCSAqLw0KKwlpZiAobW9kZSA+PSBNVF9QSFlfVFlQRV9I RV9TVSkNCisJCXZhbCB8PSBGSUVMRF9QUkVQKE1UX1RYRDZfSEVMVEYsIHRkLT50eF9sdGYpOw0K Kw0KKwlpZiAodGQtPnR4X3JhdGVfbGRwYykNCisJCXZhbCB8PSBNVF9UWEQ2X0xEUEM7DQorDQor CXR4d2lbNl0gfD0gY3B1X3RvX2xlMzIodmFsKTsNCisJdHh3aVs3XSB8PSBjcHVfdG9fbGUzMihG SUVMRF9QUkVQKE1UX1RYRDdfU1BFX0lEWCwNCisJCQkJCSAgZGV2LT50ZXN0LnNwZV9pZHgpKTsN CisjZW5kaWYNCit9DQorDQogc3RhdGljIHZvaWQNCiBtdDc5MTVfbWFjX3dyaXRlX3R4d2lfODAy MyhzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2LCBfX2xlMzIgKnR4d2ksDQogCQkJICAgc3RydWN0IHNr X2J1ZmYgKnNrYiwgc3RydWN0IG10NzZfd2NpZCAqd2NpZCkNCkBAIC03NjEsNiArODczLDkgQEAg dm9pZCBtdDc5MTVfbWFjX3dyaXRlX3R4d2koc3RydWN0IG10NzkxNV9kZXYgKmRldiwgX19sZTMy ICp0eHdpLA0KIAkJdHh3aVs2XSB8PSBjcHVfdG9fbGUzMih2YWwpOw0KIAkJdHh3aVszXSB8PSBj cHVfdG9fbGUzMihNVF9UWEQzX0JBX0RJU0FCTEUpOw0KIAl9DQorDQorCWlmIChtdDc2X3Rlc3Rt b2RlX2VuYWJsZWQoJmRldi0+bXQ3NikpDQorCQltdDc5MTVfbWFjX3dyaXRlX3R4d2lfdG0oZGV2 LCBtcGh5LCB0eHdpLCBza2IpOw0KIH0NCiANCiBpbnQgbXQ3OTE1X3R4X3ByZXBhcmVfc2tiKHN0 cnVjdCBtdDc2X2RldiAqbWRldiwgdm9pZCAqdHh3aV9wdHIsDQpAQCAtODgxLDYgKzk5NiwxOCBA QCBtdDc5MTVfdHhfY29tcGxldGVfc3RhdHVzKHN0cnVjdCBtdDc2X2RldiAqbWRldiwgc3RydWN0 IHNrX2J1ZmYgKnNrYiwNCiANCiAJaHcgPSBtdDc2X3R4X3N0YXR1c19nZXRfaHcobWRldiwgc2ti KTsNCiANCisjaWZkZWYgQ09ORklHX05MODAyMTFfVEVTVE1PREUNCisJaWYgKHNrYiA9PSBtZGV2 LT50ZXN0LnR4X3NrYikgew0KKwkJc3RydWN0IG10NzkxNV9waHkgKnBoeSA9IG10NzkxNV9od19w aHkoaHcpOw0KKwkJc3RydWN0IGllZWU4MDIxMV92aWYgKnZpZiA9IHBoeS0+bW9uaXRvcl92aWY7 DQorCQlzdHJ1Y3QgbXQ3OTE1X3ZpZiAqbXZpZiA9IChzdHJ1Y3QgbXQ3OTE1X3ZpZiAqKXZpZi0+ ZHJ2X3ByaXY7DQorDQorCQltdDc2X3R4X2NvbXBsZXRlX3NrYihtZGV2LCBtdmlmLT5zdGEud2Np ZC5pZHgsIHNrYik7DQorDQorCQlyZXR1cm47DQorCX0NCisjZW5kaWYNCisNCiAJaWYgKGluZm8t PmZsYWdzICYgSUVFRTgwMjExX1RYX0NUTF9BTVBEVSkNCiAJCWluZm8tPmZsYWdzIHw9IElFRUU4 MDIxMV9UWF9TVEFUX0FNUERVOw0KIA0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNz L21lZGlhdGVrL210NzYvbXQ3OTE1L21haW4uYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlh dGVrL210NzYvbXQ3OTE1L21haW4uYw0KaW5kZXggMTI2MmZiMy4uOWViZTVhZiAxMDA2NDQNCi0t LSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21haW4uYw0KKysr IGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWFpbi5jDQpAQCAt NDQsMTMgKzQ0LDE0IEBAIHN0YXRpYyBpbnQgbXQ3OTE1X3N0YXJ0KHN0cnVjdCBpZWVlODAyMTFf aHcgKmh3KQ0KIAkJbXQ3OTE1X21hY19lbmFibGVfbmYoZGV2LCAxKTsNCiAJfQ0KIA0KLQltdDc5 MTVfbWN1X3NldF9za3VfZW4ocGh5LCB0cnVlKTsNCisJbXQ3OTE1X21jdV9zZXRfc2t1X2VuKHBo eSwgIW10NzZfdGVzdG1vZGVfZW5hYmxlZCgmZGV2LT5tdDc2KSk7DQogCW10NzkxNV9tY3Vfc2V0 X2NoYW5faW5mbyhwaHksIE1DVV9FWFRfQ01EX1NFVF9SWF9QQVRIKTsNCiANCiAJc2V0X2JpdChN VDc2X1NUQVRFX1JVTk5JTkcsICZwaHktPm10NzYtPnN0YXRlKTsNCiANCi0JaWVlZTgwMjExX3F1 ZXVlX2RlbGF5ZWRfd29yayhodywgJnBoeS0+bWFjX3dvcmssDQotCQkJCSAgICAgTVQ3OTE1X1dB VENIRE9HX1RJTUUpOw0KKwlpZiAoIW10NzZfdGVzdG1vZGVfZW5hYmxlZCgmZGV2LT5tdDc2KSkN CisJCWllZWU4MDIxMV9xdWV1ZV9kZWxheWVkX3dvcmsoaHcsICZwaHktPm1hY193b3JrLA0KKwkJ CQkJICAgICBNVDc5MTVfV0FUQ0hET0dfVElNRSk7DQogDQogCWlmICghcnVubmluZykNCiAJCW10 NzkxNV9tYWNfcmVzZXRfY291bnRlcnMocGh5KTsNCkBAIC02OSw2ICs3MCw4IEBAIHN0YXRpYyB2 b2lkIG10NzkxNV9zdG9wKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3KQ0KIA0KIAltdXRleF9sb2Nr KCZkZXYtPm10NzYubXV0ZXgpOw0KIA0KKwltdDc2X3Rlc3Rtb2RlX3Jlc2V0KCZkZXYtPm10NzYs IHRydWUpOw0KKw0KIAljbGVhcl9iaXQoTVQ3Nl9TVEFURV9SVU5OSU5HLCAmcGh5LT5tdDc2LT5z dGF0ZSk7DQogDQogCWlmIChwaHkgIT0gJmRldi0+cGh5KSB7DQpAQCAtMTUwLDYgKzE1MywxMiBA QCBzdGF0aWMgaW50IG10NzkxNV9hZGRfaW50ZXJmYWNlKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3 LA0KIA0KIAltdXRleF9sb2NrKCZkZXYtPm10NzYubXV0ZXgpOw0KIA0KKwltdDc2X3Rlc3Rtb2Rl X3Jlc2V0KCZkZXYtPm10NzYsIHRydWUpOw0KKw0KKwlpZiAodmlmLT50eXBlID09IE5MODAyMTFf SUZUWVBFX01PTklUT1IgJiYNCisJICAgIGlzX3plcm9fZXRoZXJfYWRkcih2aWYtPmFkZHIpKQ0K KwkJcGh5LT5tb25pdG9yX3ZpZiA9IHZpZjsNCisNCiAJbXZpZi0+aWR4ID0gZmZzKH5waHktPm10 NzYtPnZpZl9tYXNrKSAtIDE7DQogCWlmIChtdmlmLT5pZHggPj0gTVQ3OTE1X01BWF9JTlRFUkZB Q0VTKSB7DQogCQlyZXQgPSAtRU5PU1BDOw0KQEAgLTIxOCw2ICsyMjcsMTMgQEAgc3RhdGljIHZv aWQgbXQ3OTE1X3JlbW92ZV9pbnRlcmZhY2Uoc3RydWN0IGllZWU4MDIxMV9odyAqaHcsDQogDQog CS8qIFRPRE86IGRpc2FibGUgYmVhY29uIGZvciB0aGUgYnNzICovDQogDQorCW11dGV4X2xvY2so JmRldi0+bXQ3Ni5tdXRleCk7DQorCW10NzZfdGVzdG1vZGVfcmVzZXQoJmRldi0+bXQ3NiwgdHJ1 ZSk7DQorCW11dGV4X3VubG9jaygmZGV2LT5tdDc2Lm11dGV4KTsNCisNCisJaWYgKHZpZiA9PSBw aHktPm1vbml0b3JfdmlmKQ0KKwkJcGh5LT5tb25pdG9yX3ZpZiA9IE5VTEw7DQorDQogCW10Nzkx NV9tY3VfYWRkX2Rldl9pbmZvKHBoeSwgdmlmLCBmYWxzZSk7DQogDQogCXJjdV9hc3NpZ25fcG9p bnRlcihkZXYtPm10NzYud2NpZFtpZHhdLCBOVUxMKTsNCkBAIC0yNTIsNyArMjY4LDcgQEAgc3Rh dGljIHZvaWQgbXQ3OTE1X2luaXRfZGZzX3N0YXRlKHN0cnVjdCBtdDc5MTVfcGh5ICpwaHkpDQog CXBoeS0+ZGZzX3N0YXRlID0gLTE7DQogfQ0KIA0KLXN0YXRpYyBpbnQgbXQ3OTE1X3NldF9jaGFu bmVsKHN0cnVjdCBtdDc5MTVfcGh5ICpwaHkpDQoraW50IG10NzkxNV9zZXRfY2hhbm5lbChzdHJ1 Y3QgbXQ3OTE1X3BoeSAqcGh5KQ0KIHsNCiAJc3RydWN0IG10NzkxNV9kZXYgKmRldiA9IHBoeS0+ ZGV2Ow0KIAlpbnQgcmV0Ow0KQEAgLTI4MSw4ICsyOTcsMTAgQEAgb3V0Og0KIAltdXRleF91bmxv Y2soJmRldi0+bXQ3Ni5tdXRleCk7DQogDQogCW10NzZfdHhxX3NjaGVkdWxlX2FsbChwaHktPm10 NzYpOw0KLQlpZWVlODAyMTFfcXVldWVfZGVsYXllZF93b3JrKHBoeS0+bXQ3Ni0+aHcsICZwaHkt Pm1hY193b3JrLA0KLQkJCQkgICAgIE1UNzkxNV9XQVRDSERPR19USU1FKTsNCisNCisJaWYgKCFt dDc2X3Rlc3Rtb2RlX2VuYWJsZWQoJmRldi0+bXQ3NikpDQorCQlpZWVlODAyMTFfcXVldWVfZGVs YXllZF93b3JrKHBoeS0+bXQ3Ni0+aHcsICZwaHktPm1hY193b3JrLA0KKwkJCQkJICAgICBNVDc5 MTVfV0FUQ0hET0dfVElNRSk7DQogDQogCXJldHVybiByZXQ7DQogfQ0KQEAgLTM0Niw2ICszNjQs MTMgQEAgc3RhdGljIGludCBtdDc5MTVfY29uZmlnKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LCB1 MzIgY2hhbmdlZCkNCiAJaW50IHJldDsNCiANCiAJaWYgKGNoYW5nZWQgJiBJRUVFODAyMTFfQ09O Rl9DSEFOR0VfQ0hBTk5FTCkgew0KKyNpZmRlZiBDT05GSUdfTkw4MDIxMV9URVNUTU9ERQ0KKwkJ aWYgKGRldi0+bXQ3Ni50ZXN0LnN0YXRlICE9IE1UNzZfVE1fU1RBVEVfT0ZGKSB7DQorCQkJbXV0 ZXhfbG9jaygmZGV2LT5tdDc2Lm11dGV4KTsNCisJCQltdDc2X3Rlc3Rtb2RlX3Jlc2V0KCZkZXYt Pm10NzYsIGZhbHNlKTsNCisJCQltdXRleF91bmxvY2soJmRldi0+bXQ3Ni5tdXRleCk7DQorCQl9 DQorI2VuZGlmDQogCQlpZWVlODAyMTFfc3RvcF9xdWV1ZXMoaHcpOw0KIAkJcmV0ID0gbXQ3OTE1 X3NldF9jaGFubmVsKHBoeSk7DQogCQlpZiAocmV0KQ0KQEAgLTM3MCw2ICszOTUsNyBAQCBzdGF0 aWMgaW50IG10NzkxNV9jb25maWcoc3RydWN0IGllZWU4MDIxMV9odyAqaHcsIHUzMiBjaGFuZ2Vk KQ0KIAkJCXBoeS0+cnhmaWx0ZXIgJj0gfk1UX1dGX1JGQ1JfRFJPUF9PVEhFUl9VQzsNCiANCiAJ CW10NzZfcm13X2ZpZWxkKGRldiwgTVRfRE1BX0RDUjAsIE1UX0RNQV9EQ1IwX1JYRF9HNV9FTiwg ZW5hYmxlZCk7DQorCQltdDc2X3Rlc3Rtb2RlX3Jlc2V0KCZkZXYtPm10NzYsIHRydWUpOw0KIAkJ bXQ3Nl93cihkZXYsIE1UX1dGX1JGQ1IoYmFuZCksIHBoeS0+cnhmaWx0ZXIpOw0KIAl9DQogDQpA QCAtODg3LDYgKzkxMyw4IEBAIGNvbnN0IHN0cnVjdCBpZWVlODAyMTFfb3BzIG10NzkxNV9vcHMg PSB7DQogCS5zZXRfY292ZXJhZ2VfY2xhc3MgPSBtdDc5MTVfc2V0X2NvdmVyYWdlX2NsYXNzLA0K IAkuc3RhX3N0YXRpc3RpY3MgPSBtdDc5MTVfc3RhX3N0YXRpc3RpY3MsDQogCS5zdGFfc2V0XzRh ZGRyID0gbXQ3OTE1X3N0YV9zZXRfNGFkZHIsDQorCUNGRzgwMjExX1RFU1RNT0RFX0NNRChtdDc2 X3Rlc3Rtb2RlX2NtZCkNCisJQ0ZHODAyMTFfVEVTVE1PREVfRFVNUChtdDc2X3Rlc3Rtb2RlX2R1 bXApDQogI2lmZGVmIENPTkZJR19NQUM4MDIxMV9ERUJVR0ZTDQogCS5zdGFfYWRkX2RlYnVnZnMg PSBtdDc5MTVfc3RhX2FkZF9kZWJ1Z2ZzLA0KICNlbmRpZg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMv bmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21jdS5jIGIvZHJpdmVycy9uZXQvd2ly ZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWN1LmMNCmluZGV4IDVjY2RlNTQuLjM3MmY0NWIg MTAwNjQ0DQotLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9t Y3UuYw0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWN1 LmMNCkBAIC0zMTg2LDYgKzMxODYsMTUgQEAgaW50IG10NzkxNV9tY3Vfc2V0X2NoYW5faW5mbyhz dHJ1Y3QgbXQ3OTE1X3BoeSAqcGh5LCBpbnQgY21kKQ0KIAkJLmNoYW5uZWxfYmFuZCA9IGNoYW5k ZWYtPmNoYW4tPmJhbmQsDQogCX07DQogDQorI2lmZGVmIENPTkZJR19OTDgwMjExX1RFU1RNT0RF DQorCWlmIChkZXYtPm10NzYudGVzdC50eF9hbnRlbm5hX21hc2sgJiYNCisJICAgIChkZXYtPm10 NzYudGVzdC5zdGF0ZSA9PSBNVDc2X1RNX1NUQVRFX1RYX0ZSQU1FUyB8fA0KKwkgICAgIGRldi0+ bXQ3Ni50ZXN0LnN0YXRlID09IE1UNzZfVE1fU1RBVEVfUlhfRlJBTUVTKSkgew0KKwkJcmVxLnR4 X3N0cmVhbXNfbnVtID0gZmxzKGRldi0+bXQ3Ni50ZXN0LnR4X2FudGVubmFfbWFzayk7DQorCQly ZXEucnhfc3RyZWFtcyA9IGRldi0+bXQ3Ni50ZXN0LnR4X2FudGVubmFfbWFzazsNCisJfQ0KKyNl bmRpZg0KKw0KIAlpZiAoZGV2LT5tdDc2Lmh3LT5jb25mLmZsYWdzICYgSUVFRTgwMjExX0NPTkZf T0ZGQ0hBTk5FTCkNCiAJCXJlcS5zd2l0Y2hfcmVhc29uID0gQ0hfU1dJVENIX1NDQU5fQllQQVNT X0RQRDsNCiAJZWxzZSBpZiAoKGNoYW5kZWYtPmNoYW4tPmZsYWdzICYgSUVFRTgwMjExX0NIQU5f UkFEQVIpICYmDQpAQCAtMzMzMCw2ICszMzM5LDI4IEBAIGludCBtdDc5MTVfbWN1X3NldF90eHBv d2VyX3NrdShzdHJ1Y3QgbXQ3OTE1X3BoeSAqcGh5KQ0KIAkJCQkgc2l6ZW9mKHJlcSksIHRydWUp Ow0KIH0NCiANCitpbnQgbXQ3OTE1X21jdV9zZXRfdGVzdF9wYXJhbShzdHJ1Y3QgbXQ3OTE1X2Rl diAqZGV2LCB1OCBwYXJhbSwgYm9vbCB0ZXN0X21vZGUsDQorCQkJICAgICAgdTggZW4pDQorew0K KwlzdHJ1Y3Qgew0KKwkJdTggdGVzdF9tb2RlX2VuOw0KKwkJdTggcGFyYW1faWR4Ow0KKwkJdTgg X3JzdlsyXTsNCisNCisJCXU4IGVuYWJsZTsNCisJCXU4IF9yc3YyWzNdOw0KKw0KKwkJdTggcGFk WzhdOw0KKwl9IF9fcGFja2VkIHJlcSA9IHsNCisJCS50ZXN0X21vZGVfZW4gPSB0ZXN0X21vZGUs DQorCQkucGFyYW1faWR4ID0gcGFyYW0sDQorCQkuZW5hYmxlID0gZW4sDQorCX07DQorDQorCXJl dHVybiBtdDc2X21jdV9zZW5kX21zZygmZGV2LT5tdDc2LCBNQ1VfRVhUX0NNRF9BVEVfQ1RSTCwg JnJlcSwNCisJCQkJIHNpemVvZihyZXEpLCBmYWxzZSk7DQorfQ0KKw0KIGludCBtdDc5MTVfbWN1 X3NldF9za3VfZW4oc3RydWN0IG10NzkxNV9waHkgKnBoeSwgYm9vbCBlbmFibGUpDQogew0KIAlz dHJ1Y3QgbXQ3OTE1X2RldiAqZGV2ID0gcGh5LT5kZXY7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9u ZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWN1LmggYi9kcml2ZXJzL25ldC93aXJl bGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9tY3UuaA0KaW5kZXggNWYyM2YyNy4uMGE3ZTlkMiAx MDA2NDQNCi0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21j dS5oDQorKysgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9tY3Uu aA0KQEAgLTQ2LDYgKzQ2LDEwIEBAIGVudW0gew0KIAlNQ1VfRVhUX0VWRU5UX1JBVEVfUkVQT1JU ID0gMHg4NywNCiB9Ow0KIA0KK2VudW0gew0KKwlNQ1VfQVRFX1NFVF9UUlggPSAweDEsDQorfTsN CisNCiBzdHJ1Y3QgbXQ3OTE1X21jdV9yeGQgew0KIAlfX2xlMzIgcnhkWzZdOw0KIA0KQEAgLTIx Niw2ICsyMjAsNyBAQCBlbnVtIHsNCiAJTUNVX0VYVF9DTURfV1RCTF9VUERBVEUgPSAweDMyLA0K IAlNQ1VfRVhUX0NNRF9TRVRfRFJSX0NUUkwgPSAweDM2LA0KIAlNQ1VfRVhUX0NNRF9TRVRfUkRE X0NUUkwgPSAweDNhLA0KKwlNQ1VfRVhUX0NNRF9BVEVfQ1RSTCA9IDB4M2QsDQogCU1DVV9FWFRf Q01EX1BST1RFQ1RfQ1RSTCA9IDB4M2UsDQogCU1DVV9FWFRfQ01EX01BQ19JTklUX0NUUkwgPSAw eDQ2LA0KIAlNQ1VfRVhUX0NNRF9SWF9IRFJfVFJBTlMgPSAweDQ3LA0KZGlmZiAtLWdpdCBhL2Ry aXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L210NzkxNS5oIGIvZHJpdmVy cy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbXQ3OTE1LmgNCmluZGV4IDQyOTIx NTMuLjY3MzU5MTUgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9t dDc2L210NzkxNS9tdDc5MTUuaA0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsv bXQ3Ni9tdDc5MTUvbXQ3OTE1LmgNCkBAIC0xMDgsNiArMTA4LDggQEAgc3RydWN0IG10NzkxNV9w aHkgew0KIA0KIAlzdHJ1Y3QgaWVlZTgwMjExX3NiYW5kX2lmdHlwZV9kYXRhIGlmdHlwZVsyXVtO VU1fTkw4MDIxMV9JRlRZUEVTXTsNCiANCisJc3RydWN0IGllZWU4MDIxMV92aWYgKm1vbml0b3Jf dmlmOw0KKw0KIAl1MzIgcnhmaWx0ZXI7DQogCXU2NCBvbWFjX21hc2s7DQogDQpAQCAtMTU4LDYg KzE2MCwxNCBAQCBzdHJ1Y3QgbXQ3OTE1X2RldiB7DQogCXN0cnVjdCBpZHIgdG9rZW47DQogDQog CWJvb2wgZndfZGVidWc7DQorDQorI2lmZGVmIENPTkZJR19OTDgwMjExX1RFU1RNT0RFDQorCXN0 cnVjdCB7DQorCQl1MzIgKnJlZ19iYWNrdXA7DQorDQorCQl1OCBzcGVfaWR4Ow0KKwl9IHRlc3Q7 DQorI2VuZGlmDQogfTsNCiANCiBlbnVtIHsNCkBAIC0yNDcsNiArMjU3LDcgQEAgc3RhdGljIGlu bGluZSB1OCBtdDc5MTVfbG1hY19tYXBwaW5nKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHU4IGFj KQ0KIA0KIGV4dGVybiBjb25zdCBzdHJ1Y3QgaWVlZTgwMjExX29wcyBtdDc5MTVfb3BzOw0KIGV4 dGVybiBzdHJ1Y3QgcGNpX2RyaXZlciBtdDc5MTVfcGNpX2RyaXZlcjsNCitleHRlcm4gY29uc3Qg c3RydWN0IG10NzZfdGVzdG1vZGVfb3BzIG10NzkxNV90ZXN0bW9kZV9vcHM7DQogDQogdTMyIG10 NzkxNV9yZWdfbWFwKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHUzMiBhZGRyKTsNCiANCkBAIC0y OTIsNiArMzAzLDcgQEAgaW50IG10NzkxNV9tY3VfYWRkX3JhdGVfY3RybChzdHJ1Y3QgbXQ3OTE1 X2RldiAqZGV2LCBzdHJ1Y3QgaWVlZTgwMjExX3ZpZiAqdmlmLA0KIAkJCSAgICAgc3RydWN0IGll ZWU4MDIxMV9zdGEgKnN0YSk7DQogaW50IG10NzkxNV9tY3VfYWRkX3NtcHMoc3RydWN0IG10Nzkx NV9kZXYgKmRldiwgc3RydWN0IGllZWU4MDIxMV92aWYgKnZpZiwNCiAJCQlzdHJ1Y3QgaWVlZTgw MjExX3N0YSAqc3RhKTsNCitpbnQgbXQ3OTE1X3NldF9jaGFubmVsKHN0cnVjdCBtdDc5MTVfcGh5 ICpwaHkpOw0KIGludCBtdDc5MTVfbWN1X3NldF9jaGFuX2luZm8oc3RydWN0IG10NzkxNV9waHkg KnBoeSwgaW50IGNtZCk7DQogaW50IG10NzkxNV9tY3Vfc2V0X3R4KHN0cnVjdCBtdDc5MTVfZGV2 ICpkZXYsIHN0cnVjdCBpZWVlODAyMTFfdmlmICp2aWYpOw0KIGludCBtdDc5MTVfbWN1X3NldF9m aXhlZF9yYXRlKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsDQpAQCAtMzAwLDYgKzMxMiw4IEBAIGlu dCBtdDc5MTVfbWN1X3NldF9lZXByb20oc3RydWN0IG10NzkxNV9kZXYgKmRldik7DQogaW50IG10 NzkxNV9tY3VfZ2V0X2VlcHJvbShzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2LCB1MzIgb2Zmc2V0KTsN CiBpbnQgbXQ3OTE1X21jdV9zZXRfbWFjKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIGludCBiYW5k LCBib29sIGVuYWJsZSwNCiAJCSAgICAgICBib29sIGhkcl90cmFucyk7DQoraW50IG10NzkxNV9t Y3Vfc2V0X3Rlc3RfcGFyYW0oc3RydWN0IG10NzkxNV9kZXYgKmRldiwgdTggcGFyYW0sIGJvb2wg dGVzdF9tb2RlLA0KKwkJCSAgICAgIHU4IGVuKTsNCiBpbnQgbXQ3OTE1X21jdV9zZXRfc2NzKHN0 cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHU4IGJhbmQsIGJvb2wgZW5hYmxlKTsNCiBpbnQgbXQ3OTE1 X21jdV9zZXRfc2VyKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHU4IGFjdGlvbiwgdTggc2V0LCB1 OCBiYW5kKTsNCiBpbnQgbXQ3OTE1X21jdV9zZXRfcnRzX3RocmVzaChzdHJ1Y3QgbXQ3OTE1X3Bo eSAqcGh5LCB1MzIgdmFsKTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRp YXRlay9tdDc2L210NzkxNS9yZWdzLmggYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9t dDc2L210NzkxNS9yZWdzLmgNCmluZGV4IGU0MjUyYzguLjkxYjYzNTYgMTAwNjQ0DQotLS0gYS9k cml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9yZWdzLmgNCisrKyBiL2Ry aXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L3JlZ3MuaA0KQEAgLTUxLDYg KzUxLDkgQEANCiAjZGVmaW5lIE1UX1dGX1RNQUNfQkFTRShfYmFuZCkJCSgoX2JhbmQpID8gMHhh MTAwMCA6IDB4MjEwMDApDQogI2RlZmluZSBNVF9XRl9UTUFDKF9iYW5kLCBvZnMpCQkoTVRfV0Zf VE1BQ19CQVNFKF9iYW5kKSArIChvZnMpKQ0KIA0KKyNkZWZpbmUgTVRfVE1BQ19UQ1IwKF9iYW5k KQkJTVRfV0ZfVE1BQyhfYmFuZCwgMCkNCisjZGVmaW5lIE1UX1RNQUNfVENSMF9UQlRUX1NUT1Bf Q1RSTAlCSVQoMjUpDQorDQogI2RlZmluZSBNVF9UTUFDX0NEVFIoX2JhbmQpCQlNVF9XRl9UTUFD KF9iYW5kLCAweDA5MCkNCiAjZGVmaW5lIE1UX1RNQUNfT0RUUihfYmFuZCkJCU1UX1dGX1RNQUMo X2JhbmQsIDB4MDk0KQ0KICNkZWZpbmUgTVRfVElNRU9VVF9WQUxfUExDUAkJR0VOTUFTSygxNSwg MCkNCkBAIC03Miw2ICs3NSw5IEBADQogI2RlZmluZSBNVF9UTUFDX0ZQMFIxOChfYmFuZCkJCU1U X1dGX1RNQUMoX2JhbmQsIDB4MjcwKQ0KICNkZWZpbmUgTVRfVE1BQ19GUF9NQVNLCQkJR0VOTUFT Syg3LCAwKQ0KIA0KKyNkZWZpbmUgTVRfVE1BQ19UUkNSMChfYmFuZCkJCU1UX1dGX1RNQUMoX2Jh bmQsIDB4MDljKQ0KKyNkZWZpbmUgTVRfVE1BQ19URkNSMChfYmFuZCkJCU1UX1dGX1RNQUMoX2Jh bmQsIDB4MWUwKQ0KKw0KIC8qIERNQSBCYW5kIDAgKi8NCiAjZGVmaW5lIE1UX1dGX0RNQV9CQVNF CQkJMHgyMWUwMA0KICNkZWZpbmUgTVRfV0ZfRE1BKG9mcykJCQkoTVRfV0ZfRE1BX0JBU0UgKyAo b2ZzKSkNCkBAIC0xNzEsMTAgKzE3NywzMyBAQA0KICNkZWZpbmUgTVRfV0ZfQUdHX0JBU0UoX2Jh bmQpCQkoKF9iYW5kKSA/IDB4YTA4MDAgOiAweDIwODAwKQ0KICNkZWZpbmUgTVRfV0ZfQUdHKF9i YW5kLCBvZnMpCQkoTVRfV0ZfQUdHX0JBU0UoX2JhbmQpICsgKG9mcykpDQogDQorI2RlZmluZSBN VF9BR0dfQVdTQ1IwKF9iYW5kLCBfbikJCU1UX1dGX0FHRyhfYmFuZCwgMHgwNWMgKyAoX24pICog NCkNCisjZGVmaW5lIE1UX0FHR19QQ1IwKF9iYW5kLCBfbikJCU1UX1dGX0FHRyhfYmFuZCwgMHgw NmMgKyAoX24pICogNCkNCisjZGVmaW5lIE1UX0FHR19QQ1IwX01NX1BST1QJCUJJVCgwKQ0KKyNk ZWZpbmUgTVRfQUdHX1BDUjBfR0ZfUFJPVAkJQklUKDEpDQorI2RlZmluZSBNVF9BR0dfUENSMF9C VzIwX1BST1QJCUJJVCgyKQ0KKyNkZWZpbmUgTVRfQUdHX1BDUjBfQlc0MF9QUk9UCQlCSVQoNCkN CisjZGVmaW5lIE1UX0FHR19QQ1IwX0JXODBfUFJPVAkJQklUKDYpDQorI2RlZmluZSBNVF9BR0df UENSMF9FUlBfUFJPVAkJR0VOTUFTSygxMiwgOCkNCisjZGVmaW5lIE1UX0FHR19QQ1IwX1ZIVF9Q Uk9UCQlCSVQoMTMpDQorI2RlZmluZSBNVF9BR0dfUENSMF9QVEFfV0lOX0RJUwkJQklUKDE1KQ0K Kw0KKyNkZWZpbmUgTVRfQUdHX1BDUjFfUlRTMF9OVU1fVEhSRVMJR0VOTUFTSygzMSwgMjMpDQor I2RlZmluZSBNVF9BR0dfUENSMV9SVFMwX0xFTl9USFJFUwlHRU5NQVNLKDE5LCAwKQ0KKw0KICNk ZWZpbmUgTVRfQUdHX0FDUjAoX2JhbmQpCQlNVF9XRl9BR0coX2JhbmQsIDB4MDg0KQ0KICNkZWZp bmUgTVRfQUdHX0FDUl9DRkVORF9SQVRFCQlHRU5NQVNLKDEzLCAwKQ0KICNkZWZpbmUgTVRfQUdH X0FDUl9CQVJfUkFURQkJR0VOTUFTSygyOSwgMTYpDQogDQorI2RlZmluZSBNVF9BR0dfTVJDUihf YmFuZCkJCU1UX1dGX0FHRyhfYmFuZCwgMHgwOTgpDQorI2RlZmluZSBNVF9BR0dfTVJDUl9CQVJf Q05UX0xJTUlUCUdFTk1BU0soMTUsIDEyKQ0KKyNkZWZpbmUgTVRfQUdHX01SQ1JfTEFTVF9SVFNf Q1RTX1JOCUJJVCg2KQ0KKyNkZWZpbmUgTVRfQUdHX01SQ1JfUlRTX0ZBSUxfTElNSVQJR0VOTUFT SygxMSwgNykNCisjZGVmaW5lIE1UX0FHR19NUkNSX1RYQ01EX1JUU19GQUlMX0xJTUlUCUdFTk1B U0soMjgsIDI0KQ0KKw0KKyNkZWZpbmUgTVRfQUdHX0FUQ1IxKF9iYW5kKQkJTVRfV0ZfQUdHKF9i YW5kLCAweDBmMCkNCisjZGVmaW5lIE1UX0FHR19BVENSMyhfYmFuZCkJCU1UX1dGX0FHRyhfYmFu ZCwgMHgwZjQpDQorDQogLyogQVJCOiBiYW5kIDAoMHgyMGMwMCksIGJhbmQgMSgweGEwYzAwKSAq Lw0KICNkZWZpbmUgTVRfV0ZfQVJCX0JBU0UoX2JhbmQpCQkoKF9iYW5kKSA/IDB4YTBjMDAgOiAw eDIwYzAwKQ0KICNkZWZpbmUgTVRfV0ZfQVJCKF9iYW5kLCBvZnMpCQkoTVRfV0ZfQVJCX0JBU0Uo X2JhbmQpICsgKG9mcykpDQpAQCAtMTgzLDYgKzIxMiw4IEBADQogI2RlZmluZSBNVF9BUkJfU0NS X1RYX0RJU0FCTEUJCUJJVCg4KQ0KICNkZWZpbmUgTVRfQVJCX1NDUl9SWF9ESVNBQkxFCQlCSVQo OSkNCiANCisjZGVmaW5lIE1UX0FSQl9EUk5HUjAoX2JhbmQsIF9uKQlNVF9XRl9BUkIoX2JhbmQs IDB4MTk0ICsgKF9uKSAqIDQpDQorDQogLyogUk1BQzogYmFuZCAwKDB4MjE0MDApLCBiYW5kIDEo MHhhMTQwMCkgKi8NCiAjZGVmaW5lIE1UX1dGX1JNQUNfQkFTRShfYmFuZCkJCSgoX2JhbmQpID8g MHhhMTQwMCA6IDB4MjE0MDApDQogI2RlZmluZSBNVF9XRl9STUFDKF9iYW5kLCBvZnMpCQkoTVRf V0ZfUk1BQ19CQVNFKF9iYW5kKSArIChvZnMpKQ0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dp cmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L3Rlc3Rtb2RlLmMgYi9kcml2ZXJzL25ldC93aXJl bGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS90ZXN0bW9kZS5jDQpuZXcgZmlsZSBtb2RlIDEwMDY0 NA0KaW5kZXggMDAwMDAwMC4uNTNmYzk3Nw0KLS0tIC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9u ZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvdGVzdG1vZGUuYw0KQEAgLTAsMCArMSwx ODAgQEANCisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogSVNDDQorLyogQ29weXJpZ2h0IChD KSAyMDIwIE1lZGlhVGVrIEluYy4gKi8NCisNCisjaW5jbHVkZSAibXQ3OTE1LmgiDQorI2luY2x1 ZGUgIm1hYy5oIg0KKyNpbmNsdWRlICJtY3UuaCINCisjaW5jbHVkZSAidGVzdG1vZGUuaCINCisN CitzdHJ1Y3QgcmVnX2JhbmQgew0KKwl1MzIgYmFuZFsyXTsNCit9Ow0KKw0KKyNkZWZpbmUgUkVH X0JBTkQoX3JlZykgXA0KKwl7IC5iYW5kWzBdID0gTVRfIyNfcmVnKDApLCAuYmFuZFsxXSA9IE1U XyMjX3JlZygxKSB9DQorI2RlZmluZSBSRUdfQkFORF9JRFgoX3JlZywgX2lkeCkgXA0KKwl7IC5i YW5kWzBdID0gTVRfIyNfcmVnKDAsIF9pZHgpLCAuYmFuZFsxXSA9IE1UXyMjX3JlZygxLCBfaWR4 KSB9DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCByZWdfYmFuZCByZWdfYmFja3VwX2xpc3RbXSA9 IHsNCisJUkVHX0JBTkRfSURYKEFHR19QQ1IwLCAwKSwNCisJUkVHX0JBTkRfSURYKEFHR19QQ1Iw LCAxKSwNCisJUkVHX0JBTkRfSURYKEFHR19BV1NDUjAsIDApLA0KKwlSRUdfQkFORF9JRFgoQUdH X0FXU0NSMCwgMSksDQorCVJFR19CQU5EX0lEWChBR0dfQVdTQ1IwLCAyKSwNCisJUkVHX0JBTkRf SURYKEFHR19BV1NDUjAsIDMpLA0KKwlSRUdfQkFORChBR0dfTVJDUiksDQorCVJFR19CQU5EKFRN QUNfVEZDUjApLA0KKwlSRUdfQkFORChUTUFDX1RDUjApLA0KKwlSRUdfQkFORChBR0dfQVRDUjEp LA0KKwlSRUdfQkFORChBR0dfQVRDUjMpLA0KKwlSRUdfQkFORChUTUFDX1RSQ1IwKSwNCisJUkVH X0JBTkQoVE1BQ19JQ1IwKSwNCisJUkVHX0JBTkRfSURYKEFSQl9EUk5HUjAsIDApLA0KKwlSRUdf QkFORF9JRFgoQVJCX0RSTkdSMCwgMSksDQorfTsNCisNCitzdGF0aWMgaW50DQorbXQ3OTE1X3Rt X21vZGVfY3RybChzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2LCBib29sIGVuYWJsZSkNCit7DQorCXN0 cnVjdCB7DQorCQl1OCBmb3JtYXRfaWQ7DQorCQlib29sIGVuYWJsZTsNCisJCXU4IHJzdlsyXTsN CisJfSByZXEgPSB7DQorCQkuZm9ybWF0X2lkID0gMHg2LA0KKwkJLmVuYWJsZSA9IGVuYWJsZSwN CisJfTsNCisNCisJcmV0dXJuIG10NzZfbWN1X3NlbmRfbXNnKCZkZXYtPm10NzYsDQorCQkJCSBN Q1VfRVhUX0NNRF9UWF9QT1dFUl9GRUFUVVJFX0NUUkwsDQorCQkJCSAmcmVxLCBzaXplb2YocmVx KSwgZmFsc2UpOw0KK30NCisNCitzdGF0aWMgaW50DQorbXQ3OTE1X3RtX3NldF90cngoc3RydWN0 IG10NzkxNV9kZXYgKmRldiwgc3RydWN0IG10NzkxNV9waHkgKnBoeSwNCisJCSAgaW50IHR5cGUs IGJvb2wgZW4pDQorew0KKwlzdHJ1Y3QgbXQ3OTE1X3RtX2NtZCByZXEgPSB7DQorCQkudGVzdG1v ZGVfZW4gPSAxLA0KKwkJLnBhcmFtX2lkeCA9IE1DVV9BVEVfU0VUX1RSWCwNCisJCS5wYXJhbS50 cngudHlwZSA9IHR5cGUsDQorCQkucGFyYW0udHJ4LmVuYWJsZSA9IGVuLA0KKwkJLnBhcmFtLnRy eC5iYW5kID0gcGh5ICE9ICZkZXYtPnBoeSwNCisJfTsNCisNCisJcmV0dXJuIG10NzZfbWN1X3Nl bmRfbXNnKCZkZXYtPm10NzYsIE1DVV9FWFRfQ01EX0FURV9DVFJMLCAmcmVxLA0KKwkJCQkgc2l6 ZW9mKHJlcSksIGZhbHNlKTsNCit9DQorDQorc3RhdGljIHZvaWQNCittdDc5MTVfdG1fcmVnX2Jh Y2t1cF9yZXN0b3JlKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHN0cnVjdCBtdDc5MTVfcGh5ICpw aHkpDQorew0KKwlpbnQgbl9yZWdzID0gQVJSQVlfU0laRShyZWdfYmFja3VwX2xpc3QpOw0KKwli b29sIGV4dF9waHkgPSBwaHkgIT0gJmRldi0+cGh5Ow0KKwl1MzIgKmIgPSBkZXYtPnRlc3QucmVn X2JhY2t1cDsNCisJaW50IGk7DQorDQorCWlmIChkZXYtPm10NzYudGVzdC5zdGF0ZSA9PSBNVDc2 X1RNX1NUQVRFX09GRikgew0KKwkJZm9yIChpID0gMDsgaSA8IG5fcmVnczsgaSsrKQ0KKwkJCW10 NzZfd3IoZGV2LCByZWdfYmFja3VwX2xpc3RbaV0uYmFuZFtleHRfcGh5XSwgYltpXSk7DQorCQly ZXR1cm47DQorCX0NCisNCisJaWYgKGIpDQorCQlyZXR1cm47DQorDQorCWIgPSBkZXZtX2t6YWxs b2MoZGV2LT5tdDc2LmRldiwgNCAqIG5fcmVncywgR0ZQX0tFUk5FTCk7DQorCWlmICghYikNCisJ CXJldHVybjsNCisNCisJZGV2LT50ZXN0LnJlZ19iYWNrdXAgPSBiOw0KKwlmb3IgKGkgPSAwOyBp IDwgbl9yZWdzOyBpKyspDQorCQliW2ldID0gbXQ3Nl9ycihkZXYsIHJlZ19iYWNrdXBfbGlzdFtp XS5iYW5kW2V4dF9waHldKTsNCisNCisJbXQ3Nl9jbGVhcihkZXYsIE1UX0FHR19QQ1IwKGV4dF9w aHksIDApLCBNVF9BR0dfUENSMF9NTV9QUk9UIHwNCisJCSAgIE1UX0FHR19QQ1IwX0dGX1BST1Qg fCBNVF9BR0dfUENSMF9FUlBfUFJPVCB8DQorCQkgICBNVF9BR0dfUENSMF9WSFRfUFJPVCB8IE1U X0FHR19QQ1IwX0JXMjBfUFJPVCB8DQorCQkgICBNVF9BR0dfUENSMF9CVzQwX1BST1QgfCBNVF9B R0dfUENSMF9CVzgwX1BST1QpOw0KKwltdDc2X3NldChkZXYsIE1UX0FHR19QQ1IwKGV4dF9waHks IDApLCBNVF9BR0dfUENSMF9QVEFfV0lOX0RJUyk7DQorDQorCW10NzZfd3IoZGV2LCBNVF9BR0df UENSMChleHRfcGh5LCAxKSwgTVRfQUdHX1BDUjFfUlRTMF9OVU1fVEhSRVMgfA0KKwkJTVRfQUdH X1BDUjFfUlRTMF9MRU5fVEhSRVMpOw0KKw0KKwltdDc2X2NsZWFyKGRldiwgTVRfQUdHX01SQ1Io MCksIE1UX0FHR19NUkNSX0JBUl9DTlRfTElNSVQgfA0KKwkJICAgTVRfQUdHX01SQ1JfTEFTVF9S VFNfQ1RTX1JOIHwgTVRfQUdHX01SQ1JfUlRTX0ZBSUxfTElNSVQgfA0KKwkJICAgTVRfQUdHX01S Q1JfVFhDTURfUlRTX0ZBSUxfTElNSVQpOw0KKw0KKwltdDc2X3JtdyhkZXYsIE1UX0FHR19NUkNS KDApLCBNVF9BR0dfTVJDUl9SVFNfRkFJTF9MSU1JVCB8DQorCQkgTVRfQUdHX01SQ1JfVFhDTURf UlRTX0ZBSUxfTElNSVQsDQorCQkgRklFTERfUFJFUChNVF9BR0dfTVJDUl9SVFNfRkFJTF9MSU1J VCwgMSkgfA0KKwkJIEZJRUxEX1BSRVAoTVRfQUdHX01SQ1JfVFhDTURfUlRTX0ZBSUxfTElNSVQs IDEpKTsNCisNCisJbXQ3Nl93cihkZXYsIE1UX1RNQUNfVEZDUjAoMCksIDApOw0KKwltdDc2X2Ns ZWFyKGRldiwgTVRfVE1BQ19UQ1IwKDApLCBNVF9UTUFDX1RDUjBfVEJUVF9TVE9QX0NUUkwpOw0K K30NCisNCitzdGF0aWMgdm9pZA0KK210NzkxNV90bV9pbml0KHN0cnVjdCBtdDc5MTVfZGV2ICpk ZXYpDQorew0KKwlib29sIGVuID0gIShkZXYtPm10NzYudGVzdC5zdGF0ZSA9PSBNVDc2X1RNX1NU QVRFX09GRik7DQorDQorCWlmICghdGVzdF9iaXQoTVQ3Nl9TVEFURV9SVU5OSU5HLCAmZGV2LT5w aHkubXQ3Ni0+c3RhdGUpKQ0KKwkJcmV0dXJuOw0KKw0KKwltdDc5MTVfdG1fbW9kZV9jdHJsKGRl diwgZW4pOw0KKwltdDc5MTVfdG1fcmVnX2JhY2t1cF9yZXN0b3JlKGRldiwgJmRldi0+cGh5KTsN CisJbXQ3OTE1X3RtX3NldF90cngoZGV2LCAmZGV2LT5waHksIFRNX01BQ19UWFJYLCAhZW4pOw0K K30NCisNCitzdGF0aWMgdm9pZA0KK210NzkxNV90bV9zZXRfdHhfZnJhbWVzKHN0cnVjdCBtdDc5 MTVfZGV2ICpkZXYsIGJvb2wgZW4pDQorew0KKwlzdGF0aWMgY29uc3QgdTggc3BlX2lkeF9tYXBb XSA9IHswLCAwLCAxLCAwLCAzLCAyLCA0LCAwLA0KKwkJCQkJIDksIDgsIDYsIDEwLCAxNiwgMTIs IDE4LCAwfTsNCisJc3RydWN0IHNrX2J1ZmYgKnNrYiA9IGRldi0+bXQ3Ni50ZXN0LnR4X3NrYjsN CisJc3RydWN0IGllZWU4MDIxMV90eF9pbmZvICppbmZvOw0KKw0KKwltdDc5MTVfdG1fc2V0X3Ry eChkZXYsICZkZXYtPnBoeSwgVE1fTUFDX1JYX1JYViwgZmFsc2UpOw0KKw0KKwlpZiAoZW4pIHsN CisJCXU4IHR4X2FudCA9IGRldi0+bXQ3Ni50ZXN0LnR4X2FudGVubmFfbWFzazsNCisNCisJCW11 dGV4X3VubG9jaygmZGV2LT5tdDc2Lm11dGV4KTsNCisJCW10NzkxNV9zZXRfY2hhbm5lbCgmZGV2 LT5waHkpOw0KKwkJbXV0ZXhfbG9jaygmZGV2LT5tdDc2Lm11dGV4KTsNCisNCisJCW10NzkxNV9t Y3Vfc2V0X2NoYW5faW5mbygmZGV2LT5waHksIE1DVV9FWFRfQ01EX1NFVF9SWF9QQVRIKTsNCisJ CWRldi0+dGVzdC5zcGVfaWR4ID0gc3BlX2lkeF9tYXBbdHhfYW50XTsNCisJfQ0KKw0KKwltdDc5 MTVfdG1fc2V0X3RyeChkZXYsICZkZXYtPnBoeSwgVE1fTUFDX1RYLCBlbik7DQorDQorCWlmICgh ZW4gfHwgIXNrYikNCisJCXJldHVybjsNCisNCisJaW5mbyA9IElFRUU4MDIxMV9TS0JfQ0Ioc2ti KTsNCisJaW5mby0+Y29udHJvbC52aWYgPSBkZXYtPnBoeS5tb25pdG9yX3ZpZjsNCit9DQorDQor c3RhdGljIGludA0KK210NzkxNV90bV9zZXRfc3RhdGUoc3RydWN0IG10NzZfZGV2ICptZGV2LCBl bnVtIG10NzZfdGVzdG1vZGVfc3RhdGUgc3RhdGUpDQorew0KKwlzdHJ1Y3QgbXQ3OTE1X2RldiAq ZGV2ID0gY29udGFpbmVyX29mKG1kZXYsIHN0cnVjdCBtdDc5MTVfZGV2LCBtdDc2KTsNCisJc3Ry dWN0IG10NzZfdGVzdG1vZGVfZGF0YSAqdGQgPSAmbWRldi0+dGVzdDsNCisJZW51bSBtdDc2X3Rl c3Rtb2RlX3N0YXRlIHByZXZfc3RhdGUgPSB0ZC0+c3RhdGU7DQorDQorCW1kZXYtPnRlc3Quc3Rh dGUgPSBzdGF0ZTsNCisNCisJaWYgKHByZXZfc3RhdGUgPT0gTVQ3Nl9UTV9TVEFURV9UWF9GUkFN RVMpDQorCQltdDc5MTVfdG1fc2V0X3R4X2ZyYW1lcyhkZXYsIGZhbHNlKTsNCisJZWxzZSBpZiAo c3RhdGUgPT0gTVQ3Nl9UTV9TVEFURV9UWF9GUkFNRVMpDQorCQltdDc5MTVfdG1fc2V0X3R4X2Zy YW1lcyhkZXYsIHRydWUpOw0KKwllbHNlIGlmIChwcmV2X3N0YXRlID09IE1UNzZfVE1fU1RBVEVf T0ZGIHx8IHN0YXRlID09IE1UNzZfVE1fU1RBVEVfT0ZGKQ0KKwkJbXQ3OTE1X3RtX2luaXQoZGV2 KTsNCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK2NvbnN0IHN0cnVjdCBtdDc2X3Rlc3Rtb2RlX29w cyBtdDc5MTVfdGVzdG1vZGVfb3BzID0gew0KKwkuc2V0X3N0YXRlID0gbXQ3OTE1X3RtX3NldF9z dGF0ZSwNCit9Ow0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210 NzYvbXQ3OTE1L3Rlc3Rtb2RlLmggYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2 L210NzkxNS90ZXN0bW9kZS5oDQpuZXcgZmlsZSBtb2RlIDEwMDY0NA0KaW5kZXggMDAwMDAwMC4u MDRmNGEyYw0KLS0tIC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0 ZWsvbXQ3Ni9tdDc5MTUvdGVzdG1vZGUuaA0KQEAgLTAsMCArMSwzNCBAQA0KKy8vIFNQRFgtTGlj ZW5zZS1JZGVudGlmaWVyOiBJU0MNCisvKiBDb3B5cmlnaHQgKEMpIDIwMjAgTWVkaWFUZWsgSW5j LiAqLw0KKw0KKyNpZm5kZWYgX19NVDc5MTVfVEVTVE1PREVfSA0KKyNkZWZpbmUgX19NVDc5MTVf VEVTVE1PREVfSA0KKw0KK3N0cnVjdCBtdDc5MTVfdG1fdHJ4IHsNCisJdTggdHlwZTsNCisJdTgg ZW5hYmxlOw0KKwl1OCBiYW5kOw0KKwl1OCByc3Y7DQorfTsNCisNCitzdHJ1Y3QgbXQ3OTE1X3Rt X2NtZCB7DQorCXU4IHRlc3Rtb2RlX2VuOw0KKwl1OCBwYXJhbV9pZHg7DQorCXU4IF9yc3ZbMl07 DQorCXVuaW9uIHsNCisJCV9fbGUzMiBkYXRhOw0KKwkJc3RydWN0IG10NzkxNV90bV90cnggdHJ4 Ow0KKwkJdTggdGVzdFs3Ml07DQorCX0gcGFyYW07DQorfSBfX3BhY2tlZDsNCisNCitlbnVtIHsN CisJVE1fTUFDX1RYID0gMSwNCisJVE1fTUFDX1JYLA0KKwlUTV9NQUNfVFhSWCwNCisJVE1fTUFD X1RYUlhfUlhWLA0KKwlUTV9NQUNfUlhWLA0KKwlUTV9NQUNfUlhfUlhWLA0KK307DQorDQorI2Vu ZGlmDQotLSANCjIuMTcuMQ0K From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CEBEC43467 for ; Thu, 8 Oct 2020 11:33:55 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A7F9D2145D for ; Thu, 8 Oct 2020 11:33:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="tdzDqbDV"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Z8wyqZQK" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A7F9D2145D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qGTa0mv5nibVF+FeKS1ljZ8T5/XvWAQEHZM+HVzjP8s=; b=tdzDqbDV9R2Xi6IQfZ6Psj/Kt d3Ez5h1TEUKTxcQQK03d2yjLfzrUgigs0j8B/wtOZnwH5lgoFxhIdo3lAKcdSkegvv1haAvlmlaHc aLSAolVo/TN5fjAl+7Rqgh3/AcMdTkO/qYd5p5RRj0+pEtCYXGiTRkhLnqlXmce/qy9kH/AQ62WW9 nV9pDvV1oWl4FY9AMKD+f8QX/6NoTOV9zta6Dqd75cFKSPn6psiDhhd8sEcnxg+MLA078yTes4CCv 7LlXxdWFU1F8UMWx6DXkBPDGm3dqdZi8Y2jKWNUF49YHSKQkW4ZgdCKWPUFkdqw+hthgGhYZlBCGK mJFCua/jQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kQUB6-0003Zj-QM; Thu, 08 Oct 2020 11:33:44 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kQUAx-0003SJ-2u for linux-mediatek@lists.infradead.org; Thu, 08 Oct 2020 11:33:39 +0000 X-UUID: 66c300d6b18340d4a327ad628331cbb3-20201008 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=UisLcbrPlbx7LpeQVyT9OpVv91AaDRogMFoMs4nSJE8=; b=Z8wyqZQKE01XtQnsUbtXc7DnuglyUS94Rm82fYW6G5uTKGEdmQhhXBtGCfutIEfuoVvfFqcgAv0lpUEy7cCJjF8e7qDPCpR1ymTR9/q5z+hXM0AZemhFJIExRcZO7cFIxN259fXWq9e+DGuVLDuFUv2tDNM49G89+ThRUXWgLOw=; X-UUID: 66c300d6b18340d4a327ad628331cbb3-20201008 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 2000530498; Thu, 08 Oct 2020 03:33:30 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 8 Oct 2020 04:33:28 -0700 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 8 Oct 2020 19:33:13 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 8 Oct 2020 19:33:14 +0800 From: Shayne Chen To: Felix Fietkau Subject: [PATCH 07/10] mt76: mt7915: implement testmode tx support Date: Thu, 8 Oct 2020 19:29:01 +0800 Message-ID: <20201008112904.10620-7-shayne.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20201008112904.10620-1-shayne.chen@mediatek.com> References: <20201008112904.10620-1-shayne.chen@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: F86A9544CE129FA3C8FF62FCBD9768F316A3B92F4206C69458FC30572727BC6C2000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201008_073335_355769_E27B94D9 X-CRM114-Status: GOOD ( 18.89 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ryder Lee , Evelyn Tsai , linux-wireless , linux-mediatek , Lorenzo Bianconi , Shayne Chen Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Support testmode tx for MT7915A, including tx streams and HE rate settings. Signed-off-by: Shayne Chen Reviewed-by: Ryder Lee --- .../wireless/mediatek/mt76/mt7915/Makefile | 2 + .../net/wireless/mediatek/mt76/mt7915/init.c | 4 + .../net/wireless/mediatek/mt76/mt7915/mac.c | 127 ++++++++++++ .../net/wireless/mediatek/mt76/mt7915/main.c | 40 +++- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 31 +++ .../net/wireless/mediatek/mt76/mt7915/mcu.h | 5 + .../wireless/mediatek/mt76/mt7915/mt7915.h | 14 ++ .../net/wireless/mediatek/mt76/mt7915/regs.h | 31 +++ .../wireless/mediatek/mt76/mt7915/testmode.c | 180 ++++++++++++++++++ .../wireless/mediatek/mt76/mt7915/testmode.h | 34 ++++ 10 files changed, 462 insertions(+), 6 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt7915/testmode.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7915/testmode.h diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/Makefile b/drivers/net/wireless/mediatek/mt76/mt7915/Makefile index 57fe726..cc2054d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt7915/Makefile @@ -4,3 +4,5 @@ obj-$(CONFIG_MT7915E) += mt7915e.o mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \ debugfs.o + +mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index ee69fe4..390b328 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -695,6 +695,10 @@ int mt7915_register_device(struct mt7915_dev *dev) mt7915_cap_dbdc_disable(dev); dev->phy.dfs_state = -1; +#ifdef CONFIG_NL80211_TESTMODE + dev->mt76.test_ops = &mt7915_testmode_ops; +#endif + ret = mt76_register_device(&dev->mt76, true, mt7915_rates, ARRAY_SIZE(mt7915_rates)); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index a7118df..e03e12f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -562,6 +562,118 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) return 0; } +static u16 +mt7915_mac_tx_rate_val(struct mt76_phy *mphy, u8 mode, u8 rate_idx, + u8 nss, u8 stbc, u8 *bw) +{ + u16 rateval; + + switch (mphy->chandef.width) { + case NL80211_CHAN_WIDTH_40: + *bw = 1; + break; + case NL80211_CHAN_WIDTH_80: + *bw = 2; + break; + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + *bw = 3; + break; + default: + *bw = 0; + break; + } + + if (mode == MT_PHY_TYPE_HT || mode == MT_PHY_TYPE_HT_GF) + nss = 1 + (rate_idx >> 3); + + rateval = FIELD_PREP(MT_TX_RATE_IDX, rate_idx) | + FIELD_PREP(MT_TX_RATE_MODE, mode) | + FIELD_PREP(MT_TX_RATE_NSS, nss - 1); + + if (stbc && nss == 1) { + nss++; + rateval |= MT_TX_RATE_STBC; + } + + return rateval; +} + +static void +mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy, + __le32 *txwi, struct sk_buff *skb) +{ +#ifdef CONFIG_NL80211_TESTMODE + struct mt76_testmode_data *td = &dev->mt76.test; + u8 bw, mode; + u16 rateval; + u32 val; + + if (skb != dev->mt76.test.tx_skb) + return; + + switch (td->tx_rate_mode) { + case MT76_TM_TX_MODE_CCK: + mode = MT_PHY_TYPE_CCK; + break; + case MT76_TM_TX_MODE_HT: + mode = MT_PHY_TYPE_HT; + break; + case MT76_TM_TX_MODE_VHT: + mode = MT_PHY_TYPE_VHT; + break; + case MT76_TM_TX_MODE_HE_SU: + mode = MT_PHY_TYPE_HE_SU; + break; + case MT76_TM_TX_MODE_HE_EXT_SU: + mode = MT_PHY_TYPE_HE_EXT_SU; + break; + case MT76_TM_TX_MODE_HE_TB: + mode = MT_PHY_TYPE_HE_TB; + break; + case MT76_TM_TX_MODE_HE_MU: + mode = MT_PHY_TYPE_HE_MU; + break; + case MT76_TM_TX_MODE_OFDM: + default: + mode = MT_PHY_TYPE_OFDM; + break; + } + + rateval = mt7915_mac_tx_rate_val(mphy, mode, td->tx_rate_idx, + td->tx_rate_nss, td->tx_rate_stbc, &bw); + + txwi[2] |= cpu_to_le32(MT_TXD2_FIX_RATE); + if (td->tx_rate_mode < MT76_TM_TX_MODE_HT) + txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); + + val = MT_TXD6_FIXED_BW | + FIELD_PREP(MT_TXD6_BW, bw) | + FIELD_PREP(MT_TXD6_TX_RATE, rateval) | + FIELD_PREP(MT_TXD6_SGI, td->tx_rate_sgi); + + /* for HE_SU/HE_EXT_SU PPDU + * - 1x, 2x, 4x LTF + 0.8us GI + * - 2x LTF + 1.6us GI, 4x LTF + 3.2us GI + * for HE_MU PPDU + * - 2x, 4x LTF + 0.8us GI + * - 2x LTF + 1.6us GI, 4x LTF + 3.2us GI + * for HE_TB PPDU + * - 1x, 2x LTF + 1.6us GI + * - 4x LTF + 3.2us GI + */ + if (mode >= MT_PHY_TYPE_HE_SU) + val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf); + + if (td->tx_rate_ldpc) + val |= MT_TXD6_LDPC; + + txwi[6] |= cpu_to_le32(val); + txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, + dev->test.spe_idx)); +#endif +} + static void mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid) @@ -761,6 +873,9 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, txwi[6] |= cpu_to_le32(val); txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); } + + if (mt76_testmode_enabled(&dev->mt76)) + mt7915_mac_write_txwi_tm(dev, mphy, txwi, skb); } int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, @@ -881,6 +996,18 @@ mt7915_tx_complete_status(struct mt76_dev *mdev, struct sk_buff *skb, hw = mt76_tx_status_get_hw(mdev, skb); +#ifdef CONFIG_NL80211_TESTMODE + if (skb == mdev->test.tx_skb) { + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct ieee80211_vif *vif = phy->monitor_vif; + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + + mt76_tx_complete_skb(mdev, mvif->sta.wcid.idx, skb); + + return; + } +#endif + if (info->flags & IEEE80211_TX_CTL_AMPDU) info->flags |= IEEE80211_TX_STAT_AMPDU; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 1262fb3..9ebe5af 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -44,13 +44,14 @@ static int mt7915_start(struct ieee80211_hw *hw) mt7915_mac_enable_nf(dev, 1); } - mt7915_mcu_set_sku_en(phy, true); + mt7915_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76)); mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH); set_bit(MT76_STATE_RUNNING, &phy->mt76->state); - ieee80211_queue_delayed_work(hw, &phy->mac_work, - MT7915_WATCHDOG_TIME); + if (!mt76_testmode_enabled(&dev->mt76)) + ieee80211_queue_delayed_work(hw, &phy->mac_work, + MT7915_WATCHDOG_TIME); if (!running) mt7915_mac_reset_counters(phy); @@ -69,6 +70,8 @@ static void mt7915_stop(struct ieee80211_hw *hw) mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, true); + clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); if (phy != &dev->phy) { @@ -150,6 +153,12 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, true); + + if (vif->type == NL80211_IFTYPE_MONITOR && + is_zero_ether_addr(vif->addr)) + phy->monitor_vif = vif; + mvif->idx = ffs(~phy->mt76->vif_mask) - 1; if (mvif->idx >= MT7915_MAX_INTERFACES) { ret = -ENOSPC; @@ -218,6 +227,13 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw, /* TODO: disable beacon for the bss */ + mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, true); + mutex_unlock(&dev->mt76.mutex); + + if (vif == phy->monitor_vif) + phy->monitor_vif = NULL; + mt7915_mcu_add_dev_info(phy, vif, false); rcu_assign_pointer(dev->mt76.wcid[idx], NULL); @@ -252,7 +268,7 @@ static void mt7915_init_dfs_state(struct mt7915_phy *phy) phy->dfs_state = -1; } -static int mt7915_set_channel(struct mt7915_phy *phy) +int mt7915_set_channel(struct mt7915_phy *phy) { struct mt7915_dev *dev = phy->dev; int ret; @@ -281,8 +297,10 @@ out: mutex_unlock(&dev->mt76.mutex); mt76_txq_schedule_all(phy->mt76); - ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work, - MT7915_WATCHDOG_TIME); + + if (!mt76_testmode_enabled(&dev->mt76)) + ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work, + MT7915_WATCHDOG_TIME); return ret; } @@ -346,6 +364,13 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) int ret; if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { +#ifdef CONFIG_NL80211_TESTMODE + if (dev->mt76.test.state != MT76_TM_STATE_OFF) { + mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, false); + mutex_unlock(&dev->mt76.mutex); + } +#endif ieee80211_stop_queues(hw); ret = mt7915_set_channel(phy); if (ret) @@ -370,6 +395,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC; mt76_rmw_field(dev, MT_DMA_DCR0, MT_DMA_DCR0_RXD_G5_EN, enabled); + mt76_testmode_reset(&dev->mt76, true); mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter); } @@ -887,6 +913,8 @@ const struct ieee80211_ops mt7915_ops = { .set_coverage_class = mt7915_set_coverage_class, .sta_statistics = mt7915_sta_statistics, .sta_set_4addr = mt7915_sta_set_4addr, + CFG80211_TESTMODE_CMD(mt76_testmode_cmd) + CFG80211_TESTMODE_DUMP(mt76_testmode_dump) #ifdef CONFIG_MAC80211_DEBUGFS .sta_add_debugfs = mt7915_sta_add_debugfs, #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 5ccde54..372f45b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -3186,6 +3186,15 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) .channel_band = chandef->chan->band, }; +#ifdef CONFIG_NL80211_TESTMODE + if (dev->mt76.test.tx_antenna_mask && + (dev->mt76.test.state == MT76_TM_STATE_TX_FRAMES || + dev->mt76.test.state == MT76_TM_STATE_RX_FRAMES)) { + req.tx_streams_num = fls(dev->mt76.test.tx_antenna_mask); + req.rx_streams = dev->mt76.test.tx_antenna_mask; + } +#endif + if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; else if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) && @@ -3330,6 +3339,28 @@ int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy) sizeof(req), true); } +int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, + u8 en) +{ + struct { + u8 test_mode_en; + u8 param_idx; + u8 _rsv[2]; + + u8 enable; + u8 _rsv2[3]; + + u8 pad[8]; + } __packed req = { + .test_mode_en = test_mode, + .param_idx = param, + .enable = en, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req, + sizeof(req), false); +} + int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable) { struct mt7915_dev *dev = phy->dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 5f23f27..0a7e9d2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -46,6 +46,10 @@ enum { MCU_EXT_EVENT_RATE_REPORT = 0x87, }; +enum { + MCU_ATE_SET_TRX = 0x1, +}; + struct mt7915_mcu_rxd { __le32 rxd[6]; @@ -216,6 +220,7 @@ enum { MCU_EXT_CMD_WTBL_UPDATE = 0x32, MCU_EXT_CMD_SET_DRR_CTRL = 0x36, MCU_EXT_CMD_SET_RDD_CTRL = 0x3a, + MCU_EXT_CMD_ATE_CTRL = 0x3d, MCU_EXT_CMD_PROTECT_CTRL = 0x3e, MCU_EXT_CMD_MAC_INIT_CTRL = 0x46, MCU_EXT_CMD_RX_HDR_TRANS = 0x47, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 4292153..6735915 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -108,6 +108,8 @@ struct mt7915_phy { struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES]; + struct ieee80211_vif *monitor_vif; + u32 rxfilter; u64 omac_mask; @@ -158,6 +160,14 @@ struct mt7915_dev { struct idr token; bool fw_debug; + +#ifdef CONFIG_NL80211_TESTMODE + struct { + u32 *reg_backup; + + u8 spe_idx; + } test; +#endif }; enum { @@ -247,6 +257,7 @@ static inline u8 mt7915_lmac_mapping(struct mt7915_dev *dev, u8 ac) extern const struct ieee80211_ops mt7915_ops; extern struct pci_driver mt7915_pci_driver; +extern const struct mt76_testmode_ops mt7915_testmode_ops; u32 mt7915_reg_map(struct mt7915_dev *dev, u32 addr); @@ -292,6 +303,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +int mt7915_set_channel(struct mt7915_phy *phy); int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd); int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif); int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev, @@ -300,6 +312,8 @@ int mt7915_mcu_set_eeprom(struct mt7915_dev *dev); int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset); int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, bool hdr_trans); +int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, + u8 en); int mt7915_mcu_set_scs(struct mt7915_dev *dev, u8 band, bool enable); int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band); int mt7915_mcu_set_rts_thresh(struct mt7915_phy *phy, u32 val); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index e4252c8..91b6356 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -51,6 +51,9 @@ #define MT_WF_TMAC_BASE(_band) ((_band) ? 0xa1000 : 0x21000) #define MT_WF_TMAC(_band, ofs) (MT_WF_TMAC_BASE(_band) + (ofs)) +#define MT_TMAC_TCR0(_band) MT_WF_TMAC(_band, 0) +#define MT_TMAC_TCR0_TBTT_STOP_CTRL BIT(25) + #define MT_TMAC_CDTR(_band) MT_WF_TMAC(_band, 0x090) #define MT_TMAC_ODTR(_band) MT_WF_TMAC(_band, 0x094) #define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0) @@ -72,6 +75,9 @@ #define MT_TMAC_FP0R18(_band) MT_WF_TMAC(_band, 0x270) #define MT_TMAC_FP_MASK GENMASK(7, 0) +#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c) +#define MT_TMAC_TFCR0(_band) MT_WF_TMAC(_band, 0x1e0) + /* DMA Band 0 */ #define MT_WF_DMA_BASE 0x21e00 #define MT_WF_DMA(ofs) (MT_WF_DMA_BASE + (ofs)) @@ -171,10 +177,33 @@ #define MT_WF_AGG_BASE(_band) ((_band) ? 0xa0800 : 0x20800) #define MT_WF_AGG(_band, ofs) (MT_WF_AGG_BASE(_band) + (ofs)) +#define MT_AGG_AWSCR0(_band, _n) MT_WF_AGG(_band, 0x05c + (_n) * 4) +#define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, 0x06c + (_n) * 4) +#define MT_AGG_PCR0_MM_PROT BIT(0) +#define MT_AGG_PCR0_GF_PROT BIT(1) +#define MT_AGG_PCR0_BW20_PROT BIT(2) +#define MT_AGG_PCR0_BW40_PROT BIT(4) +#define MT_AGG_PCR0_BW80_PROT BIT(6) +#define MT_AGG_PCR0_ERP_PROT GENMASK(12, 8) +#define MT_AGG_PCR0_VHT_PROT BIT(13) +#define MT_AGG_PCR0_PTA_WIN_DIS BIT(15) + +#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23) +#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0) + #define MT_AGG_ACR0(_band) MT_WF_AGG(_band, 0x084) #define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0) #define MT_AGG_ACR_BAR_RATE GENMASK(29, 16) +#define MT_AGG_MRCR(_band) MT_WF_AGG(_band, 0x098) +#define MT_AGG_MRCR_BAR_CNT_LIMIT GENMASK(15, 12) +#define MT_AGG_MRCR_LAST_RTS_CTS_RN BIT(6) +#define MT_AGG_MRCR_RTS_FAIL_LIMIT GENMASK(11, 7) +#define MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT GENMASK(28, 24) + +#define MT_AGG_ATCR1(_band) MT_WF_AGG(_band, 0x0f0) +#define MT_AGG_ATCR3(_band) MT_WF_AGG(_band, 0x0f4) + /* ARB: band 0(0x20c00), band 1(0xa0c00) */ #define MT_WF_ARB_BASE(_band) ((_band) ? 0xa0c00 : 0x20c00) #define MT_WF_ARB(_band, ofs) (MT_WF_ARB_BASE(_band) + (ofs)) @@ -183,6 +212,8 @@ #define MT_ARB_SCR_TX_DISABLE BIT(8) #define MT_ARB_SCR_RX_DISABLE BIT(9) +#define MT_ARB_DRNGR0(_band, _n) MT_WF_ARB(_band, 0x194 + (_n) * 4) + /* RMAC: band 0(0x21400), band 1(0xa1400) */ #define MT_WF_RMAC_BASE(_band) ((_band) ? 0xa1400 : 0x21400) #define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c new file mode 100644 index 0000000..53fc977 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2020 MediaTek Inc. */ + +#include "mt7915.h" +#include "mac.h" +#include "mcu.h" +#include "testmode.h" + +struct reg_band { + u32 band[2]; +}; + +#define REG_BAND(_reg) \ + { .band[0] = MT_##_reg(0), .band[1] = MT_##_reg(1) } +#define REG_BAND_IDX(_reg, _idx) \ + { .band[0] = MT_##_reg(0, _idx), .band[1] = MT_##_reg(1, _idx) } + +static const struct reg_band reg_backup_list[] = { + REG_BAND_IDX(AGG_PCR0, 0), + REG_BAND_IDX(AGG_PCR0, 1), + REG_BAND_IDX(AGG_AWSCR0, 0), + REG_BAND_IDX(AGG_AWSCR0, 1), + REG_BAND_IDX(AGG_AWSCR0, 2), + REG_BAND_IDX(AGG_AWSCR0, 3), + REG_BAND(AGG_MRCR), + REG_BAND(TMAC_TFCR0), + REG_BAND(TMAC_TCR0), + REG_BAND(AGG_ATCR1), + REG_BAND(AGG_ATCR3), + REG_BAND(TMAC_TRCR0), + REG_BAND(TMAC_ICR0), + REG_BAND_IDX(ARB_DRNGR0, 0), + REG_BAND_IDX(ARB_DRNGR0, 1), +}; + +static int +mt7915_tm_mode_ctrl(struct mt7915_dev *dev, bool enable) +{ + struct { + u8 format_id; + bool enable; + u8 rsv[2]; + } req = { + .format_id = 0x6, + .enable = enable, + }; + + return mt76_mcu_send_msg(&dev->mt76, + MCU_EXT_CMD_TX_POWER_FEATURE_CTRL, + &req, sizeof(req), false); +} + +static int +mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy, + int type, bool en) +{ + struct mt7915_tm_cmd req = { + .testmode_en = 1, + .param_idx = MCU_ATE_SET_TRX, + .param.trx.type = type, + .param.trx.enable = en, + .param.trx.band = phy != &dev->phy, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req, + sizeof(req), false); +} + +static void +mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy) +{ + int n_regs = ARRAY_SIZE(reg_backup_list); + bool ext_phy = phy != &dev->phy; + u32 *b = dev->test.reg_backup; + int i; + + if (dev->mt76.test.state == MT76_TM_STATE_OFF) { + for (i = 0; i < n_regs; i++) + mt76_wr(dev, reg_backup_list[i].band[ext_phy], b[i]); + return; + } + + if (b) + return; + + b = devm_kzalloc(dev->mt76.dev, 4 * n_regs, GFP_KERNEL); + if (!b) + return; + + dev->test.reg_backup = b; + for (i = 0; i < n_regs; i++) + b[i] = mt76_rr(dev, reg_backup_list[i].band[ext_phy]); + + mt76_clear(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_MM_PROT | + MT_AGG_PCR0_GF_PROT | MT_AGG_PCR0_ERP_PROT | + MT_AGG_PCR0_VHT_PROT | MT_AGG_PCR0_BW20_PROT | + MT_AGG_PCR0_BW40_PROT | MT_AGG_PCR0_BW80_PROT); + mt76_set(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_PTA_WIN_DIS); + + mt76_wr(dev, MT_AGG_PCR0(ext_phy, 1), MT_AGG_PCR1_RTS0_NUM_THRES | + MT_AGG_PCR1_RTS0_LEN_THRES); + + mt76_clear(dev, MT_AGG_MRCR(0), MT_AGG_MRCR_BAR_CNT_LIMIT | + MT_AGG_MRCR_LAST_RTS_CTS_RN | MT_AGG_MRCR_RTS_FAIL_LIMIT | + MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT); + + mt76_rmw(dev, MT_AGG_MRCR(0), MT_AGG_MRCR_RTS_FAIL_LIMIT | + MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, + FIELD_PREP(MT_AGG_MRCR_RTS_FAIL_LIMIT, 1) | + FIELD_PREP(MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, 1)); + + mt76_wr(dev, MT_TMAC_TFCR0(0), 0); + mt76_clear(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TBTT_STOP_CTRL); +} + +static void +mt7915_tm_init(struct mt7915_dev *dev) +{ + bool en = !(dev->mt76.test.state == MT76_TM_STATE_OFF); + + if (!test_bit(MT76_STATE_RUNNING, &dev->phy.mt76->state)) + return; + + mt7915_tm_mode_ctrl(dev, en); + mt7915_tm_reg_backup_restore(dev, &dev->phy); + mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TXRX, !en); +} + +static void +mt7915_tm_set_tx_frames(struct mt7915_dev *dev, bool en) +{ + static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0, + 9, 8, 6, 10, 16, 12, 18, 0}; + struct sk_buff *skb = dev->mt76.test.tx_skb; + struct ieee80211_tx_info *info; + + mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, false); + + if (en) { + u8 tx_ant = dev->mt76.test.tx_antenna_mask; + + mutex_unlock(&dev->mt76.mutex); + mt7915_set_channel(&dev->phy); + mutex_lock(&dev->mt76.mutex); + + mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH); + dev->test.spe_idx = spe_idx_map[tx_ant]; + } + + mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TX, en); + + if (!en || !skb) + return; + + info = IEEE80211_SKB_CB(skb); + info->control.vif = dev->phy.monitor_vif; +} + +static int +mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state) +{ + struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); + struct mt76_testmode_data *td = &mdev->test; + enum mt76_testmode_state prev_state = td->state; + + mdev->test.state = state; + + if (prev_state == MT76_TM_STATE_TX_FRAMES) + mt7915_tm_set_tx_frames(dev, false); + else if (state == MT76_TM_STATE_TX_FRAMES) + mt7915_tm_set_tx_frames(dev, true); + else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF) + mt7915_tm_init(dev); + + return 0; +} + +const struct mt76_testmode_ops mt7915_testmode_ops = { + .set_state = mt7915_tm_set_state, +}; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h new file mode 100644 index 0000000..04f4a2c --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2020 MediaTek Inc. */ + +#ifndef __MT7915_TESTMODE_H +#define __MT7915_TESTMODE_H + +struct mt7915_tm_trx { + u8 type; + u8 enable; + u8 band; + u8 rsv; +}; + +struct mt7915_tm_cmd { + u8 testmode_en; + u8 param_idx; + u8 _rsv[2]; + union { + __le32 data; + struct mt7915_tm_trx trx; + u8 test[72]; + } param; +} __packed; + +enum { + TM_MAC_TX = 1, + TM_MAC_RX, + TM_MAC_TXRX, + TM_MAC_TXRX_RXV, + TM_MAC_RXV, + TM_MAC_RX_RXV, +}; + +#endif -- 2.17.1 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek