-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AR9380 mini pcie card - unable to read eeprom (32 bit PowerPC - bigendian) #4
Comments
Hello Tim, thank you for reporting this issue and sorry for delayed answer. Looking at the provided logs, I am tending to assume that this is some weird register byteswapping on PowerPC arch. Especially this looks suspicious:
Probably debugfs register access suffer from the same issue. Need to reproduce the issue, but at the moment I have no setup with big-endian CPU and a wireless interface with a real EEPROM chip. If you need to quickly check the EEPROM contents and the EEPROM is not corrupted, then the easiest way to do this is dump the EEPROM via the ath9k debugfs interface, and then parse it with atheepmgr:
|
I you need the full utility functionality, then we need to figure out what happened with the EEPROM contents during the loading stage. Please, apply the attached patch. It introduce a new command that saves the EEPROM contents without any checks. And do the raw data fetching:
|
Thanks for the patch. I carried out a few experiments. Firstly I used the following:
This produced similar errors like:
However copying the file off to my x86_64 laptop would dump the file contents as expected... The following patch seems to let the PCI 'save' command also produce a file which can be parsed by the laptop (only tested with read, and only compile-tested on Linux): --- /home/tim/prog/atheepmgr/con_pci.c 2022-07-04 12:38:06.758600176 +0100
+++ con_pci.c 2022-07-11 15:26:26.443861455 +0100
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <pciaccess.h>
+#include <endian.h>
#include "atheepmgr.h"
@@ -124,14 +125,14 @@
{
struct pci_priv *ppd = aem->con_priv;
- return *((volatile uint32_t *)(ppd->io_map + reg));
+ return le32toh(*((volatile uint32_t *)(ppd->io_map + reg)));
}
static void pci_reg_write(struct atheepmgr *aem, uint32_t reg, uint32_t val)
{
struct pci_priv *ppd = aem->con_priv;
- *((volatile uint32_t *)(ppd->io_map + reg)) = val;
+ *((volatile uint32_t *)(ppd->io_map + reg)) = htobe32(val);
}
static void pci_reg_rmw(struct atheepmgr *aem, uint32_t reg, uint32_t set,
@@ -140,10 +141,10 @@
struct pci_priv *ppd = aem->con_priv;
uint32_t tmp;
- tmp = *((volatile uint32_t *)(ppd->io_map + reg));
+ tmp = le32toh(*((volatile uint32_t *)(ppd->io_map + reg)));
tmp &= ~clr;
tmp |= set;
- *((volatile uint32_t *)(ppd->io_map + reg)) = tmp;
+ *((volatile uint32_t *)(ppd->io_map + reg)) = htobe32(tmp);
}
static int pci_parse_devarg(const char *str, struct pci_slot_match *slot) I didn't have a clear idea where the code was working with CPU-endian data, and where it was working with device-endian data, but since both ppc32 and x86_64 were saying "Use byteswapped EEPROM I/O", and that seemed weird, I speculatively tried applying the following hack-patch, and that seemed fix parsing (but I've no idea whether or not it's bogus and will cause problems elsewhere): diff --git a/eep_common.h b/eep_common.h
index dffd8c2..cd58fc8 100644
--- a/eep_common.h
+++ b/eep_common.h
@@ -34,11 +34,11 @@
#define LE32CONST(__val) ((uint32_t)(__val))
#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
+/* #if __BYTE_ORDER == __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5
-#else
+#else */
#define AR5416_EEPROM_MAGIC 0xa55a
-#endif
+/* #endif */
#define AR5416_EEPROM_MAGIC_OFFSET 0x0
#define AR5416_EEP_NO_BACK_VER 0x1 With both patches applied, on the ppc32 all of these seem to do the right thing:
The same files can also be parsed on the x86_64 laptop. Happy to carry out further tests... Tim. |
Looks like this would make things work on BSD, but I don't have a BSD system here that I can test on
|
Hello Tim, thank you for this research! It is now clear that atheepmgr has a number of endians handling issues. At the moment I do not have access to any BE platform with an AR93xx card. I will leave this issue open until I have a chance to run tests on a real hardware and finally fix it. |
No problem, thanks for following up. The device I'm testing on is a Netgear WNDAP660, which has two identical 3x3 ath9k mini-pcie cards inside. A while ago a lot of these were being decommissioned by corporate users, and so they were quite cheap on the second hand market, but there seem to be less now, and the prices are a bit higher. Looking eBay, there are some on sale near to me for £25 (around €30 or $30) at the moment. I'm currently using two of them in my house, but I could free one up, and arrange remote ssh access to it (running a fresh install of OpenWRT 22.03) at some point if that would help you out? |
Tim, thank you for your assistance. I just need, besides the board, to find some spare time to carefully study the possible endianness cases to properly fix the issue. This summer is kind of crazy, but I hope it ends someday :) |
Sometime the utility unable to check EEPROM/OTP contents. In particular, this could be caused, for example, by a conntents corruption or a missed template in the decompression algorithm. The utility declined any handling of data if they looked inconsistent. The readed data saving will be rejected as well in case of a failed check. But sometimes it is desireable to do just our best and at least save the extracted data as it is. E.g. for a partial audit, data consistency recovery, or simply for further utility development in a relaxed and more comfortable environment. So add a capability to save the read RAW data as-is. Without any checks and even without I/O byteswapping. This change introduces only the RAW data saving framework: new commands, new code execution paths that bypass checks, and a set of flags indicating whether a particular format handler is capable to fetch data without any preprocessing. Per-format support for the RAW data loading will be introduces by the following changes. Refs: gh-4, gh-6
Add support for RAW EEPROM and OTP contents loading if it is requested by the caller. It assumes complete contents ignoring, including I/O byteswapping check bypassing and decompression avoidance. A WNIC can contain two data sources: EEPROM and OTP, with EEPROM being tried first in the common case. So the EEPROM RAW reading code has been augmented with empty/missed EEPROM checks to skip the EEPROM and automatically continue with OTP memory as the data souce. The user can still explicitly specify which memory should be read using the appropriate utiltiy command: saveraweep or saverawotp. The change was runtime tested with QCA9565 based card. The card contains data only in the OTP memory, but the EEPROM reading should be reliable as well. Refs: gh-4
Hello Tim, I had a chance to test the utility with a BE CPU. I have used R11e-5HnD (AR9582 based) and R11e-5HacT (QCA9880 based) wireless cards with MikroTik RB912 board, which is equipped with AR9342 MIPS SoC (see full logs below). I found that the utility works as expected with the MIPS BE CPU via each interface: PCI, memory, driver. It correctly detects the card chip, performs the required unpacking, and properly detects the CPU-Data byte order difference. So we can narrow down the issue scope down to the PowerPC byte order mess, as you already pointed out in the updated issue title. I have checked the Linux I/O memory accessor implementations for the PPC arch. Looks like on a such platform the utility should manually byteswap the register value if it is obtained directly from the hardware (e.g. using PCI or IOMEM connectors). We need this to turn the PCI bus little-endian byteorder to the big-endian CPU byteorder. Fetching data via the driver interface works fine, as the kernel performs all the required byteswaps. But it is still unclear to me why the utility fail to process the extracted data. Now the issue is break down into two:
I will check the libc headers, which are related to endians handling to see how to solve the first issue. But the second issue requires more input. BTW, I just merged raw data saving support to the tree. Troubleshooting should be a bit easier now. RB912 + R11e-5HnD (AR9582 based, eep9300 format), PCI connector
RB912 + R11e-5HnD (AR9582 based, eep9300 format), IOMEM connector
RB912 + R11e-5HnD (AR9582 based, eep9300 format), driver debugfs connector
RB912 + R11e-5HacT (QCA9880 based, eep9880 format), PCI connector
RB912 + R11e-5HacT (QCA9880 based, eep9880 format), IOMEM connector
|
Thanks for looking at this - if it would be helpful to arrange secure remote access for you to a 32 bit BE OpenWRT PowerPC access point with an ath9k, please let me know. Similarly if I can help with any debug. |
Hi,
Thanks for writing this tool!
I have an AR9380 mini pcie card on a PowerPC 32bit system (openwrt - netgear wndap660).
I've tried to use the tool both directly via PCI (with the ath9k kernel modules unloaded):
... and also through the wireless device - both without luck:
... am I doing something wrong? I can try and remove the card and access it through an x86_64 PC if that would be worth trying?
The text was updated successfully, but these errors were encountered: