└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Wireless card rebranding 2 | The idea here is to use a Atheros AR9285 wireless card, and make it look like a Intel Centrino Advanced-N 6205 Wireless card. 3 | We do this by modifying the EEPROM card. We copy the vendor/device/subsystem IDs of the Intel card into the EEPROM Atheros card. 4 | 5 | However, there is an Atheros Card which is whitelisted by Lenovo `168C:002B:17AA:30A1` so its IDs can be use to flash the EEPROM card. But in this tutorial, I will use the Intel IDs. 6 | 7 | My setup: 8 | - Lenovo Thinkpad X230 with BIOS whitelist (v2.67), and MacOS Sierra and its original Centrino Advanced-N 6205 wireless card. 9 | - Spared Laptop with no restriction, and Ubuntu 16.04.3, and Atheros AR9285 wireless card. 10 | 11 | From now on, we'll use the spared laptop. 12 | First we need to identify both wireless cards. We start with the Centrino Advanced-N 6205 by putting it inside the spared laptop. 13 | Then, in terminal: 14 | `lspci` 15 | This will give us the pci slot used by the cards, for me: 03:00.0 16 | Then we take a look at: 17 | `ls /sys/bus/pci/devices/` 18 | And we look for the same pci slot, for me: 03:00.0 19 | And then we use: 20 | `udevadm info /sys/bus/pci/devices/0000:03:00.0` 21 | Result: 22 | ``` 23 | P: /devices/pci0000:00/0000:00:1c.1/0000:03:00.0 24 | E: DEVPATH=/devices/pci0000:00/0000:00:1c.1/0000:03:00.0 25 | E: DRIVER=iwlwifi 26 | E: ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN) 27 | E: ID_PCI_CLASS_FROM_DATABASE=Network controller 28 | E: ID_PCI_SUBCLASS_FROM_DATABASE=Network controller 29 | E: ID_VENDOR_FROM_DATABASE=Intel Corporation 30 | E: MODALIAS=pci:v00008086d00000085sv00008086sd00001311bc02sc80i00 31 | E: PCI_CLASS=28000 32 | E: PCI_ID=8086:0085 33 | E: PCI_SLOT_NAME=0000:03:00.0 34 | E: PCI_SUBSYS_ID=8086:1311 35 | E: SUBSYSTEM=pci 36 | E: USEC_INITIALIZED=6291525 37 | ``` 38 | This command give us enough informations about the card. We are interested in the PCI_ID and PCI_SUBSYS_ID. We'll modify both of them. 39 | We save those informations somewhere, remove the N6205 card, and put back the AR9285 inside the spared laptop, and we repeat the process: 40 | Result: 41 | ``` 42 | P: /devices/pci0000:00/0000:00:1c.1/0000:03:00.0 43 | E: DEVPATH=/devices/pci0000:00/0000:00:1c.1/0000:03:00.0 44 | E: DRIVER=ath9k 45 | E: ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (AW-NE785 / AW-NE785H 802.11bgn Wireless Full or Half-size Mini PCIe Card) 46 | E: ID_PCI_CLASS_FROM_DATABASE=Network controller 47 | E: ID_PCI_SUBCLASS_FROM_DATABASE=Network controller 48 | E: ID_VENDOR_FROM_DATABASE=Qualcomm Atheros 49 | E: MODALIAS=pci:v0000168Cd0000002Bsv00001A3Bsd00001089bc02sc80i00 50 | E: PCI_CLASS=28000 51 | E: PCI_ID=168C:002B 52 | E: PCI_SLOT_NAME=0000:03:00.0 53 | E: PCI_SUBSYS_ID=1A3B:1089 54 | E: SUBSYSTEM=pci 55 | E: USEC_INITIALIZED=6046558 56 | ``` 57 | We save those informations somewhere. 58 | So finally we have: 59 | - PCI_ID 168C:002B will become 8086:0085 60 | - PCI_SUBSYS_ID 1A3B:1089 will become 8086:1311 61 | 62 | Now we will dump the AR9285 EEPROM into a file, modify that file(to make it look like the N6205), and copy it back to the wireless card. 63 | We need a few tools. 64 | `sudo apt-get install build-essential ghex` 65 | ghex is a hexadecimal editor. 66 | Then, we download the tool source code that allows us to read and write EEPROMs, iwleeprom: 67 | ``` 68 | wget https://storage.googleapis.com/google-code-archive-source/v2/code.google.com/iwleeprom/source-archive.zip 69 | unzip source-archive.zip 70 | cd iwleeprom/branches/atheros 71 | ``` 72 | Then we need to modify a bit of code inside ath9kio.c, around line 795: 73 | ``` 74 | if (dev->ops->eeprom_read16(dev, 128, &data) && (376 == data)) { 75 | short_eeprom_base = 128; 76 | short_eeprom_size = 376; 77 | goto ssize_ok; 78 | } 79 | ``` 80 | change: 81 | ``` 82 | short_eeprom_base = 128; 83 | short_eeprom_size = 376; 84 | ``` 85 | into: 86 | ``` 87 | short_eeprom_base = 0; 88 | short_eeprom_size = 512; 89 | ``` 90 | save, and compile: 91 | `make` 92 | 93 | Now make sure this is the AR9285 card that we are actually using. 94 | We'll dump the AR9285 EEPROM into a file: 95 | `sudo ./iwleeprom -o ./AR9285-original.eeprom` 96 | Result: 97 | ``` 98 | Supported devices detected: 99 | [1] 0000:03:00.0 [RW] AR9285 Wireless Adapter (PCI-E) (168c:002b, 1a3b:1089) 100 | Select device [1-1] (or 0 to quit): 1 101 | Using device 0000:03:00.0 [RW] AR9285 Wireless Adapter (PCI-E) 102 | IO driver: ath9k 103 | HW: AR9285 (PCI-E) rev 0002 104 | RF: integrated 105 | Checking NVM size... 106 | ath9k short eeprom base: 0 size: 512 107 | Saving dump with byte order: LITTLE ENDIAN 108 | 0000 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] 109 | 0f80 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] 110 | 111 | EEPROM has been dumped to './AR9285-original.eeprom' 112 | ``` 113 | 114 | The file is owned by the root user, but you can change it back to a normal user owner `(chown)...` 115 | 116 | We keep the original intact, and we'll work on a copy: 117 | `cp AR9285-original.eeprom AR9285-patched.eeprom` 118 | 119 | Now it's time to open the eeprom dump file with ghex, find and replace vendor/device/subsystem IDs: 120 | `ghex AR9285-patched.eeprom` 121 | In the menu `"View" --> "Group Data As" --> "Words"`, it's just a preference. 122 | 123 | Now something IMPORTANT, the eeprom dump file is byte-flipped, which means, if we want to look for "168C", we will look for "8C16". 124 | So from: 125 | - PCI_ID 168C:002B will become 8086:0085 126 | - PCI_SUBSYS_ID 1A3B:1089 will become 8086:1311 127 | 128 | We obtain: 129 | - PCI_ID 8C16:2B00 will become 8680:8500 130 | - PCI_SUBSYS_ID 3B1A:8910 will become 8680:1113 131 | 132 | And a bit more clearly: 133 | - find 8C162B00 replace by 86808500 134 | - find 3B1A8910 replace by 86801113 135 | 136 | Don't forget, there are 2 OCCURENCES of each to find and replace by. 137 | Then save file. 138 | 139 | And now we write back the modified eeprom dump file into the wireless card, using iwleeprom tool: 140 | `sudo ./iwleeprom -i AR9285-patched.eeprom` 141 | 142 | Now our AR9285 card is patched and ready. We put it back in the Thinkpad X230, and boot it. You should not see any warning from the BIOS. 143 | 144 | However, the process is not finished. We've bypass the X230 BIOS. But now the AR9285 card is seen as an Intel N6205 card by Mac OS. 145 | So there is the process of put the right IDs back, by using [FakePCIID kexts from Rehabman](https://github.com/RehabMan/OS-X-Fake-PCI-ID). 146 | 147 | If you have multi OSs boot, your rebranded wireless card won't work on any of those other OSs without any equivalent solution like FakePCIID. 148 | 149 | If for some reasons, we want to change the IDs again, or we want to simply restore the original EEPROM, we cannot just write it back with iwleeprom. Because the card is recognized neither by the system nor by iwleeprom (it's identified as Intel but it's not). So we'll need to: 150 | - unload the intel module, which is trying to work with the fake intel card, 151 | - download the linux kernel, 152 | - modify the atheros module source code by puting the intel IDs, 153 | - build, and launch the modify kernel module, 154 | - modify iwleeprom source code by puting the intel IDs, 155 | - build, and now use iwleeprom to write back the original EEPROM. 156 | 157 | So here the process: 158 | First we need to unload Intel module, which is loaded because of our fake Intel ID inside our Atheros card: 159 | 160 | `sudo modprobe -r iwldvm` 161 | 162 | Next we download the Ubuntu Linux kernel source code: 163 | 164 | `apt source linux-image-$(uname -r)` 165 | 166 | It'll give us a source code folder, so get into it: 167 | 168 | `cd linux-xxx` 169 | 170 | Then we copy our actual config: 171 | 172 | `cp /boot/config-$(uname -r) .config` 173 | 174 | Then we prepare some kernel files: 175 | ``` 176 | make prepare 177 | make scripts 178 | ``` 179 | Then we go into the atheros module folder: 180 | 181 | `cd drivers/net/wireless/ath/ath9k/` 182 | 183 | And into that folder, there will be 2 source files to modify: 184 | - hw.h 185 | - and pci.c 186 | 187 | Let's start with hw.h, and look for: 188 | 189 | `#define AR9285_DEVID_PCIE 0x002b` 190 | 191 | and we replace it with the fake intel ID we're actually using, with is 85: 192 | 193 | `#define AR9285_DEVID_PCIE 0x0085` 194 | 195 | Next we go for pci.c, and look for: 196 | ``` 197 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ 198 | { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 199 | { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 200 | { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 201 | ``` 202 | And we add a new line with our fake Intel IDs too: 203 | 204 | `{ PCI_VDEVICE(INTEL, 0x0085) },` 205 | 206 | Don't forget the change `ATHEROS` into `INTEL`. 207 | 208 | Now we're ready to compile to modified atheros module, with: 209 | 210 | `make -C /lib/modules/$(uname -r)/build M=$(pwd) modules` 211 | 212 | And then, we're ready to install the modified atheros module: 213 | 214 | `sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install` 215 | 216 | There might be some sign errors but that should not be a problem. 217 | 218 | This will install the modified module into an extra folder: `/lib/modules/(your kernel version)/extra`, this way, it won't overwrite any original atheros module. 219 | 220 | However, we'll need to temporary disable the original atheros so they won't launch. 221 | So we go inside the original atheros module folder, and we rename them: 222 | 223 | `cd /lib/modules/$(uname -r)/kernel/drivers/net/wireless/ath/ath9k/` 224 | 225 | There will be 4 module files: 226 | ``` 227 | ath9k_common.ko 228 | ath9k_htc.ko 229 | ath9k_hw.ko 230 | ath9k.ko 231 | ``` 232 | We rename them into (by using `sudo mv ...`): 233 | ``` 234 | ath9k_common.ko.backup 235 | ath9k_htc.ko.backup 236 | ath9k_hw.ko.backup 237 | ath9k.ko.backup 238 | ``` 239 | 240 | Now it's time to launch the modified atheros module: 241 | ``` 242 | sudo depmod 243 | sudo modprobe -v ath9k 244 | ``` 245 | The atheros card should be up. 246 | 247 | Now it's time to modify iwleeprom source code. The idea is pretty much the same: we put the wrong IDs in the source code, so that iwleeprom will recognize the card. 248 | But first we need to modify `iwlio.c`. Because right now the card is seen as a real Intel card, so we look for: 249 | ``` 250 | /* Intel 6x00/6x50 devices */ 251 | const struct pci_id iwl6k_ids[] = { 252 | { INTEL_PCI_VID, 0x0082, "6000 Series Gen2 (6x05)"}, 253 | { INTEL_PCI_VID, 0x0083, "Centrino Wireless-N 1000"}, 254 | { INTEL_PCI_VID, 0x0084, "Centrino Wireless-N 1000"}, 255 | { INTEL_PCI_VID, 0x0085, "6000 Series Gen2 (6x05)"}, 256 | { INTEL_PCI_VID, 0x0087, "Centrino Advanced-N + WiMAX 6250"}, 257 | ``` 258 | And we comment the line with the ID 85 (which is our wrong ID): 259 | 260 | `/*{ INTEL_PCI_VID, 0x0085, "6000 Series Gen2 (6x05)"},*/` 261 | 262 | That way, iwleeprom won't see it as a real Intel card. 263 | 264 | Then we modify ath9kio.c, by looking for atheros IDs: 265 | ``` 266 | /* Atheros 9k devices */ 267 | const struct pci_id ath9k_ids[] = { 268 | { ATHEROS_PCI_VID, 0x0023, "AR5416 (AR5008 family) Wireless Adapter (PCI)" }, 269 | { ATHEROS_PCI_VID, 0x0024, "AR5416 (AR5008 family) Wireless Adapter (PCI-E)" }, 270 | { ATHEROS_PCI_VID, 0x0027, "AR9160 802.11abgn Wireless Adapter (PCI)" }, 271 | { ATHEROS_PCI_VID, 0x0029, "AR922X Wireless Adapter (PCI)" }, 272 | { ATHEROS_PCI_VID, 0x002A, "AR928X Wireless Adapter (PCI-E)" }, 273 | { ATHEROS_PCI_VID, 0x002B, "AR9285 Wireless Adapter (PCI-E)" }, 274 | { ATHEROS_PCI_VID, 0x002C, "AR2427 Wireless Adapter (PCI-E)" }, /* PCI-E 802.11n bonded out */ 275 | { ATHEROS_PCI_VID, 0x002D, "AR9287 Wireless Adapter (PCI)" }, 276 | { ATHEROS_PCI_VID, 0x002E, "AR9287 Wireless Adapter (PCI-E)" }, 277 | { 0, 0, "" } 278 | ``` 279 | 280 | And we add a line with our fake Intel ID: 281 | 282 | `{ INTEL_PCI_VID, 0x0085, "My wrong ID Wireless Adapter (PCI)" },` 283 | 284 | for the `INTEL_PCI_VID` word to be recognized, we add: 285 | 286 | `#define INTEL_PCI_VID 0x8086` at the begining of file ath9kio.c 287 | 288 | Now we compile iwleeprom `make` and we are ready to read or write the eeprom again. When we launch iwleeprom we should see `My wrong ID Wireless Adapter (PCI)` as choice of card. 289 | 290 | When everything is done, don't forget to: 291 | - restore the orginal atheros modules we've backed up. 292 | - remove the modified atheros modules from the `extra` folder. 293 | - launch `sudo depmod` 294 | 295 | Sources: 296 | 297 | [How to repair an Atheros 92xx based WiFi card, flashed with wrong IDs](https://www.tonymacx86.com/threads/rebranding-the-atheros-928x-cards-the-guide.115110/page-7#post-816640) 298 | 299 | [How (recipe) to build only one kernel module?](https://askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module#515408) 300 | 301 | [Atheros IDs whitelisted](https://github.com/ThiagoSchetini/AR9285-rebranding) 302 | --------------------------------------------------------------------------------