From patchwork Sun Aug 21 14:49:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 9292195 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 257B1600CB for ; Sun, 21 Aug 2016 14:49:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 169B5281D2 for ; Sun, 21 Aug 2016 14:49:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0AED928657; Sun, 21 Aug 2016 14:49:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A920281D2 for ; Sun, 21 Aug 2016 14:49:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753309AbcHUOtg (ORCPT ); Sun, 21 Aug 2016 10:49:36 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:35689 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753148AbcHUOtb (ORCPT ); Sun, 21 Aug 2016 10:49:31 -0400 Received: by mail-wm0-f66.google.com with SMTP id i5so9888019wmg.2; Sun, 21 Aug 2016 07:49:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=m0aa29GexoeKnl/PNczQaXzWuskRS1eqjfgirNiFwvg=; b=dp7K1zrRlnOC5VRzG287dsTFEEVNawS8niVDBqn/KoQIF+9e9OVCKEGU6mlWjgl5qr b4uTOTzVflqp1hwLKv9pcbhorbng5oUXzgwFW/lSGmQT9AY4EHjFhmLTuizgZZ8sXvvU VeJEDwFYd4dT36nEP3tDFoztdQORBpsakAnd5IOBcTbJmqR/uX7rMNJnubNvUdlY+v3G FiWueKqsfuuaSk54+SPWn7VQGg2s2uGkbPI4D3ylANenYZOOejCf6rvR85sPGZmBXBhv knEIk1gnaIFMhlpiXIjhDteDxxAucFDPMiyhXvlNYY5o54Be+bPEZHjSaiOT1cODr5Ls l0dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=m0aa29GexoeKnl/PNczQaXzWuskRS1eqjfgirNiFwvg=; b=dXWdJ2XQaeJslFUfX5kZbJyQ5oc7OuRAWhQhzXt7bwOlXroCkqgPccs+8ckSAF1d8Z pDzKmjJOIhNu78nVw2I+qJa0Ynzb5nv8N6V3SVAhv97vQtTy/XZVjn5/AixcgAz4FToR fKJPVyMkBiZkRcvHVIykn2hyxKkpbcnP6RaO/XJbuFK91RvkfjkzhPxijwtm6G7n8aJ5 owUw6fRRyiHT/nkpXas8KYZl3qwK/x196Xq9wW33dFqUNFu6HCtRCWIybyxdOvPWWfjz S288aMFCHPQzRvyvRlX8z9wZoUHDACpHhjDMZfXvtPyf1E1O3kaUb0dE4ewk2P97AuNI QaDQ== X-Gm-Message-State: AEkoout5Chfv8oOePfI5v6g6y/CpNiH0jnUpoQ4i2lecWJ9L7XTtdgQoiBoOkO/SC2I+2A== X-Received: by 10.28.174.11 with SMTP id x11mr12218241wme.41.1471790969403; Sun, 21 Aug 2016 07:49:29 -0700 (PDT) Received: from blackbox.darklights.net (p5DE388BA.dip0.t-ipconnect.de. [93.227.136.186]) by smtp.googlemail.com with ESMTPSA id c16sm15581351wme.4.2016.08.21.07.49.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 21 Aug 2016 07:49:28 -0700 (PDT) From: Martin Blumenstingl To: kvalo@codeaurora.org, ath9k-devel@qca.qualcomm.com, linux-wireless@vger.kernel.org, ath9k-devel@lists.ath9k.org, devicetree@vger.kernel.org Cc: robh+dt@kernel.org, mark.rutland@arm.com, arnd@arndb.de, chunkeey@googlemail.com, nbd@nbd.name, Martin Blumenstingl Subject: [PATCH 4/5] ath9k: Make the EEPROM swapping check use the eepmisc register Date: Sun, 21 Aug 2016 16:49:05 +0200 Message-Id: <20160821144906.30984-5-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160821144906.30984-1-martin.blumenstingl@googlemail.com> References: <20160821144906.30984-1-martin.blumenstingl@googlemail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There are two ways of swapping the EEPROM data in the ath9k driver: 1) swab16 based on the first two EEPROM "magic" bytes (same for all EEPROM formats) 2) field and EEPROM format specific swab16/swab32 (different for eeprom_def, eeprom_4k and eeprom_9287) The result of the first check was used to also enable the second swap. This behavior seems incorrect, since the data may only be byte-swapped (afterwards the data could be in the correct endianness). Thus we introduce a separate check based on the "eepmisc" register (which is part of the EEPROM data). When bit 0 is set, then the EEPROM format specific values are in "big endian". This is also done by the FreeBSD kernel, see [0] for example. This allows us to parse EEPROMs with the "correct" magic bytes but swapped EEPROM format specific values. These EEPROMs (mostly found in lantiq and broadcom based big endian MIPS based devices) only worked due to platform specific "hacks" which swapped the EEPROM so the magic was inverted, which also enabled the format specific swapping. With this patch the old behavior is still supported, but neither recommended nor needed anymore. [0] https://github.com/freebsd/freebsd/blob/50719b56d9ce8d7d4beb53b16e9edb2e9a4a7a18/sys/dev/ath/ath_hal/ah_eeprom_9287.c#L351 --- drivers/net/wireless/ath/ath9k/eeprom.c | 57 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index a449588..8138a1d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -155,11 +155,19 @@ bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) return ret; } +#ifdef __BIG_ENDIAN +#define EXPECTED_EEPMISC_VAL AR5416_EEPMISC_BIG_ENDIAN +#else +#define EXPECTED_EEPMISC_VAL 0 +#endif + int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) { u16 magic; u16 *eepdata; + u8 eepmisc; int i; + bool needs_byteswap = false; struct ath_common *common = ath9k_hw_common(ah); if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { @@ -167,36 +175,53 @@ int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) return -EIO; } - *swap_needed = false; if (swab16(magic) == AR5416_EEPROM_MAGIC) { + needs_byteswap = true; + ath_dbg(common, EEPROM, + "EEPROM needs byte-swapping to correct endianness.\n"); + } else if (magic != AR5416_EEPROM_MAGIC) { + if (ath9k_hw_use_flash(ah)) { + ath_dbg(common, EEPROM, + "Ignoring invalid EEPROM magic (0x%04x).\n", + magic); + } else { + ath_err(common, + "Invalid EEPROM magic (0x%04x).\n", magic); + return -EINVAL; + } + } + + if (needs_byteswap) { if (ah->ah_flags & AH_NO_EEP_SWAP) { ath_info(common, "Ignoring endianness difference in EEPROM magic bytes.\n"); } else { - *swap_needed = true; - } - } else if (magic != AR5416_EEPROM_MAGIC) { - if (ath9k_hw_use_flash(ah)) - return 0; + eepdata = (u16 *)(&ah->eeprom); - ath_err(common, - "Invalid EEPROM Magic (0x%04x).\n", magic); - return -EINVAL; + for (i = 0; i < size; i++) + eepdata[i] = swab16(eepdata[i]); + } } - eepdata = (u16 *)(&ah->eeprom); - - if (*swap_needed) { - ath_dbg(common, EEPROM, - "EEPROM Endianness is not native.. Changing.\n"); + *swap_needed = false; - for (i = 0; i < size; i++) - eepdata[i] = swab16(eepdata[i]); + eepmisc = ah->eep_ops->get_eepmisc(ah); + if ((eepmisc & AR5416_EEPMISC_BIG_ENDIAN) != EXPECTED_EEPMISC_VAL) { + if (ah->ah_flags & AH_NO_EEP_SWAP) { + ath_info(common, + "Ignoring endianness difference in eepmisc register.\n"); + } else { + *swap_needed = true; + ath_dbg(common, EEPROM, + "EEPROM needs swapping according to the eepmisc register.\n"); + } } return 0; } +#undef EXPECTED_EEPMISC_VAL + bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size) { u32 i, sum = 0;