How to repair an Atheros 92xx based WiFi card, flashed with wrong IDs
Things you'll need:
- USB Flash drive 4 GB or more.
- Ubuntu 14.04 desktop x86 or x86_64 ISO (downloaded from the official page).
-
Universal USB Installer (a Windows-based tool).
- Internet connection for the Ubuntu Live session.
1. Preparing the USB drive.
It's pretty simple to create an USB install thumb drive with UUI. Just start the program, select the distribution, then the ISO and then the flash drive location. It is highly recommended to be use the persistent space option, so the changes that you've made to the Live session to be saved. For 4 GB flash drive set the persistent space to around 2 GB. Once the creation process has been completed, you can remove the flash drive.
2. Booting into the Ubuntu Live session and setting up some stuff.
Boot into the Ubuntu Live session (doesn't matter the legacy or the UEFI way). Once you have reached the desktop, it's time to setup some tools that you'll need for the recovery process.
a) Ensure that you have enabled the
universe and
mulitverse repositories (System Settings / Software and Updates / page 1)
b) Install the needed tools through Terminal:
Code:
sudo apt-get update
sudo apt-get install build-essential libncurses5-dev subversion ghex
The last one (gHex) is optional, you may use whatever hex editor you want.
3. Downloading some source code.
You'll need the source code of the ath9k driver and the iwleeprom tool.
Code:
cd ~/Downloads
svn checkout [URL]http://iwleeprom.googlecode.com/svn/branches/atheros[/URL] ./iwleeprom
You can find the latest ath9k source code at the
Backports page. Take the latest version and download the tarball to ~/Downloads.
4. Making the card operational.
In order for the iwleeprom tool to work, the card should be fully operational, even if the IDs are wrong. For that purpose, the ath9k driver should be tweaked and recompiled.
a) Extracting the tarball.
Code:
cd ~/Downloads
tar xvf ./backports-x.xx-xxx-x.tar.xz
cd backports-x.xx-xxx-x
b) Configuring the source code.
Execute the folloing command:
A ncurses-based command line interface will appear. For our purpose, we need to compile only the ath9k driver.
- Use the Up/Down arrows to go to the second line, named cfg80211 – wireless configuration API and press M to select it. Other options will appear, leave them as they are.
- Use the arrows to go to the line, named Generic IEEE 802.11 Networking stack (mac80211) and press M to select it. Another set of additional options will appear, leave them as they are.
- Use the Up/Down arrows to go to the options group, named Wireless LAN and press Enter. You'll see the list of the available wifi drivers. Go to the line, named Atheros Wireless Cards and press M to select it. Now press Enter.
- On the next screen go to the line, named Atheros 802.11n wireless cards support and press M to select it. Other options will bi marked as well, don't touch them. Use the Left/Right arrows to select the Exit command below and press Enter to return to the previous screen.
- Once there, go down to the line, named Realtek rtlwifi family of devices and press space to deselect it (we don't need it). When you're ready, select the Exit command below and press Enter to return to the previous screen.
- The line after the current one should be named Ethernet driver support. Select it and press space to deselect it (we don't need it as well).
- All things are set, now use the Left/Right arrow to go to the Save command and follow the instructions to save the current configuration as .config.
- When the configuration is saved, select the Exit command to return to the command prompt.
c) Tweaking the code.
You should change the code in order to make the ath9k module recognize the card, even with the wrong IDs. The following example is for Atheros 9285 based card. Go to the ath9k folder (
cd ./drivers/net/wireless/ath/ath9k) and make the following changes:
-
hw.h: look for a line
Code:
#define AR9285_DEVID_PCIE 0x002b
and change it to:
Code:
#define AR9285_DEVID_PCIE 0xXXXX
where XXXX is the current Product ID of the card (the wrong one). Save the file.
Change this line, if your card is AR9285 based, for other model, find the corresponding line (AR92XX_DEVID_PCIE)!!!
-
pci.c: Add the current IDs to that file, using the lines with PCI_VDEVICE for example . For this guide I've used the AR9285 section:
Code:
...
{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
...
and added the card with the wrong IDs like this:
Code:
...
{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
[B]{ PCI_VDEVICE(XXXX, 0xYYYY) },[/B]
…
where YYYY is the card's current Product ID and XXXX is the current Vendor ID.
Note the keywords that are used instead of the real Vendor IDs, you should use them at that place (ATHEROS,INTEL,BROADCOM, RALINK etc.). Don't forget the comma or you'll receive a compiler error. Once you have finished, save the file.
d) Compiling the code.
The code is set, now return to the main folder and issue the following commands:
You'll get a warnings about the wrong signatures on the second one, just ignore them.
e) Testing the card.
Now it's time to test the card. In Terminal, issue the following commands
Code:
sudo modprobe -r ath9k
sudo modprobe ath9k
Now open the network applet and if everything's ok, you should see the wireless networks around you in a few seconds.
5. Tweaking and compiling the iwleeprom tool.
Now, when the card is fully operational, it's time to restore it original IDs, but first we need to change the iwleeprom code in order to recognize the card with the current IDs. Go to the iwleeprom folder (
cd ~/Downloads/iwleeprom), open ath9kio.c and make the following changes:
a) Find the Atheros 92xx ID section:
Code:
...
/* Atheros 9k devices */
const struct pci_id ath9k_ids[] = {
{ ATHEROS_PCI_VID, 0x0023, "AR5416 (AR5008 family) Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x0024, "AR5416 (AR5008 family) Wireless Adapter (PCI-E)" },
{ ATHEROS_PCI_VID, 0x0027, "AR9160 802.11abgn Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x0029, "AR922X Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x002A, "AR928X Wireless Adapter (PCI-E)" },
{ ATHEROS_PCI_VID, 0x002B, "AR9285 Wireless Adapter (PCI-E)" },
{ ATHEROS_PCI_VID, 0x002C, "AR2427 Wireless Adapter (PCI-E)" }, /* PCI-E 802.11n bonded out */
{ ATHEROS_PCI_VID, 0x002D, "AR9287 Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x002E, "AR9287 Wireless Adapter (PCI-E)" },
{ 0, 0, "" }
};
…
and add your device in it:
Code:
/* Atheros 9k devices */
const struct pci_id ath9k_ids[] = {
{ ATHEROS_PCI_VID, 0x0023, "AR5416 (AR5008 family) Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x0024, "AR5416 (AR5008 family) Wireless Adapter (PCI-E)" },
{ ATHEROS_PCI_VID, 0x0027, "AR9160 802.11abgn Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x0029, "AR922X Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x002A, "AR928X Wireless Adapter (PCI-E)" },
{ ATHEROS_PCI_VID, 0x002B, "AR9285 Wireless Adapter (PCI-E)" },
{ ATHEROS_PCI_VID, 0x002C, "AR2427 Wireless Adapter (PCI-E)" }, /* PCI-E 802.11n bonded out */
{ ATHEROS_PCI_VID, 0x002D, "AR9287 Wireless Adapter (PCI)" },
{ ATHEROS_PCI_VID, 0x002E, "AR9287 Wireless Adapter (PCI-E)" },
[B]{ 0xXXXX, 0xYYYY, "My Hacked Wireless adaptor" },[/B]
{ 0, 0, "" }
};
where XXXX and YYYY are your current Vendor and Product IDs.
Note that you can store the Vendor ID just like the Product ID.
b) Find the following part:
Code:
...
// reading EEPROM size and setting it's base address
// thanks to Inv from forum.ixbt.com
if (dev->ops->eeprom_read16(dev, 128, &data) && (376 == data)) {
short_eeprom_base = 128;
short_eeprom_size = 376;
goto ssize_ok;
}
if (dev->ops->eeprom_read16(dev, 512, &data) && (3256 == data)) {
short_eeprom_base = 512;
short_eeprom_size = 3256;
goto ssize_ok;
}
if (dev->ops->eeprom_read16(dev, 256, &data) && (727 == data)) {
short_eeprom_base = 256;
short_eeprom_size = 727;
goto ssize_ok;
}
...
For the AR92xx cards you need to change only the first if statement to:
Code:
if (dev->ops->eeprom_read16(dev, 128, &data) && (376 == data)) {
[B]short_eeprom_base = 0;[/B]
[B] short_eeprom_size = 512;[/B]
goto ssize_ok;
}
For other card you may need to change the others as well.
Now save the file and compile the code by issuing make. The iwleeprom binary will appear in the current folder.
6. Extracting the current EEPROM.
Execute in the current folder the following command:
Code:
sudo iwleeprom -o ./eeprom1
You'll see the list of the recognized WiFi card(s) that you have installed on you PC, select it by pressing the corresponding number (1,2,3 etc) and the eeprom will be dumped as ./eeprom1
7. Editing the EERPOM.
Open ./eeprom1 in gHex (or any other hex editor), find your current (wrong) IDs and change them back to the original ones. Note that the IDs in this dump are byte-flipped, so you should look for 8c16 instead of 168c (Atheros) and 2b00 instead of 002b. I think you've got the point. If you have changed the SubVendor/SubProduct ID's, now it's time to change them back as well. Once you have finished with the edits, save the file.
8. Flashing the EEPROM.
Execute the following command:
Code:
sudo iwleeprom -i ./eeprom1
This command will flash the modified EEPROM on your wireless card. Select the card by its number and the confirm the flash process with capital Y. When it's done, reboot the computer and you should be able to use your card again.
Credits:
Alexander "ittrium" Kalinichenko (alexander_at_kalinichenko.org) - the original author of the iwleeprom tool.
Gennady "ShultZ" Kozlov (qpxtool_at_mail.ru) - the author of the Atheros branch.
raw99 - for his source code edits.