Skip to content

Instantly share code, notes, and snippets.

@matiaspl
Last active June 5, 2024 17:04
Show Gist options
  • Save matiaspl/019e4d98337fe4cb1a843625d9692bc7 to your computer and use it in GitHub Desktop.
Save matiaspl/019e4d98337fe4cb1a843625d9692bc7 to your computer and use it in GitHub Desktop.
Replace VID, PID, MAC and channel plan on Realtek USB wifi dongles (e.g. 8811AU)

Why would you even want to do that?

Well, there are some vendor locked dongles out there (I'm looking at you Panasonic!) that use regular off-the-shelf chips but cost a lot of money and not $5 that they're really worth. E.g. there's the AJ-WM50E dual band AC dongle (sold for 160 USD) that you should use with AG-UX180 camera to get wifi CCU running.

I happen to have one such dongle, couple of summer holiday nights and family far, far away. Why not do some hacking then?

The camera is - as far as I can tell - running Linux or a similar system. If so, it has a limited set of tools to get to know what's getting connected to it.

Ultimate goal

Make the not-so-Panasonic dongle resemble the Panasonic one as much as possible, so that the camera just enables it thinking it's legit.

Contrary to what some internet forums state, both Panasonic dongle and ASUS USB-N53 (rev A1) utilize the same Realtek 8811AU chipset (and not Ralink). They are the only Panasonic-compatible dongles out there, according to https://pro-av.panasonic.net/en/sales_o/p2/server/wireless_module.html

Judging by the FCC ID sticker - OEM ASUS (LiteOn?) WN4509L dongle from AliExpress is also based on 8811AU, so this will be our donor.

WN4509L

How much do the dongles differ?

AJ-WM50E USB\VID_0BDA&PID_0811\5&1E92747D&0&9 74:da:38:99:a0:76

OEM USB\VID_0BDA&PID_A811\00E04C000001 ac:e0:10:f9:c9:38

As far as I know both use the very same chipset. So - at first glympse - it should only be a matter of overwriting the internal eeprom in the chip. Great.

TL;DR

To create a cheap replacement for the AJ-WM50E you have to

  • get a cheap rtl8812au dongle (not that easy, but doable)
  • modify internal eFuse EEPROM:
    • change the PID to 0x0811
    • change the channel plan to 0xC2

Prerequisites

  • a decent linux distro (i.e. Ubuntu 18 or 19) with rtl8812au-dkms package installed
  • drivers to support your not-so-regular donor dongle (in my case https://github.com/gnab/rtl8812au)
  • iwpriv from wireless-tools package
  • root privileges (iwpriv needs them to work)

A linux VM on a Windows host is more than enough to do all the work.

Getting to know around

First, let's look what the eFuse (the internal memory) on the "good" dongle looks like. To do that one has to browse through a whole a lot of internet sites aggregating information from various datasheets from the single vendor. I did my homework (three sleepless nights...) so now I know it usually is enough to call iwpriv *dev* efuse_get realmap (where dev means the network device name). I say usually, because depending on the driver version either > 0x100 eeprom cells are mapped out or not.

If your device name starts with wlx it most likely will show up like this (and if not, everything over 0x100 will be blank):

   0x00    29 81 00 7C 01 00 01 00         4C 00 04 00 10 00 00 00
   0x10    24 24 25 25 26 26 2C 2C         2D 2E 2E F0 FF FF FF FF
   0x20    FF FF 2A 28 25 23 2D 2C         2B 29 28 29 29 26 23 20
   0x30    01 FF FF FF FF FF CC FF         FF FF FF FF FF FF FF FF
   0x40    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x50    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x60    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x70    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x80    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x90    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0xa0    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0xb0    FF FF FF FF FF FF FF FF         C2 0B 1F 00 00 00 FF 00
   0xc0    FF 08 00 FF 00 00 00 55         00 FF FF FF FF FF FF FF
   0xd0    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0xe0    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0xf0    FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x100   DA 0B 11 08 E7 47 03 74         DA 38 99 A0 76 0A 03 52
   0x110   65 61 6C 74 65 6B 20 18         03 38 30 32 2E 31 31 61
   0x120   63 20 57 4C 41 4E 20 41         64 61 70 74 65 72 20 00
   0x130   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x140   FF FF FF FF FF FF FF 0F         FF FF FF FF FF FF FF FF
   0x150   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x160   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x170   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x180   FF FF FF FF FF FF FF FF         83 AB 99 2D 03 93 98 A0
   0x190   FC 8C 00 11 9B C4 00 FF         FF FF FF FF FF FF FF FF
   0x1a0   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x1b0   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x1c0   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x1d0   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x1e0   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF
   0x1f0   FF FF FF FF FF FF FF FF         FF FF FF FF FF FF FF FF

A cautious reader will notice the four byte in total little-endian VID and PID at 0x100:

# iwpriv wlx74da3899a076 efuse_get rmap,0x100,4
enx74da3899a076  efuse_get:0xDA 0x0B 0x11 0x08

and big-endian six byte MAC address at 0x107:

# iwpriv wlx74da3899a076 efuse_get rmap,0x107,6
enx74da3899a076  efuse_get:0x74 0xDA 0x38 0x99 0xA0 0x76

Work work work

While reading from efuse is done by efuse_get rmap, while efuse_set wmap is responsible for writing. The syntax is efuse_get rmap,address,decimal_number_of_bytes and efuse_set wmap,address,single_or_multiple_bytes_in_hex accordingly.

So, lets do this!

First, get the system to see your donor dongle. This means e.g. installing and loading rtl8812au DKMS drivers if the regular Ubuntu provided drivers are not able to detect it. Or the drivers from github, which support a wider range of devices.

As a result, the name prefix for Realtek devices will change from wlx* to enx*. From now on we don't get to see the whole realmap, but we can read and write to all adresses above and below 0x100.

Set first byte of PID (VID is fine), so that it's 08 not a8:

# iwpriv enxace010f9c938 efuse_set wmap,0x103,08

The changes are persistent between and can be done multiple times (luckily it's not OTP memory).

Let's now connect the dongle to the camera and see if this is enough.

If at first you don't succeed...

Nada. Not working. Bad luck... what's different? MAC and serial number! Funnily enough linux tends to show the same serial number (00E04C000001) for both dongles. On Windows the first one has the following S/N (or whatever it is): 5&1E92747D&0&9. It has to be saved somewhere in the eeprom...

Actually it looks like the Panasonic dongle doesn't have any serial number, and the OEM has a default one. However the serial number doesn't seem to be present in the OEM dongle eeprom. At least not in a readable form. Wrong track again. Oh, if you ever need to change the MAC address, here's how:

# iwpriv enxace010f9c938 efuse_set wmap,0x107,0011aabbccdd

I tried changing it to the Panasonic MAC but still no luck.

Unfortunately there's no memory map for the chip floating on the internet, so the last thing to try is to do a full dump and clone of the eFuse... Hold on, we have the open source drivers! :)

A few moments later... EUREKA!

I dumped all the eeproms, did some diffing and was left with only a few bytes that differed. I cross-referenced them with https://github.com/gnab/rtl8812au/blob/master/include/hal_pg.h and tried to change the ones that are meaningful to get the dongle to work.

efuse diff

In the end I found out, that it's only important to set the EEPROM_ChannelPlan (0xB8) to the same value as the Panasonic dongle (0xC2):

# iwpriv enxace010f9c956 efuse_set wmap,0xb8,c2

Presto-change-o - we have wifi! All in all a two byte hack. :)

@asitjain
Copy link

Hi!

Thanks for your article.

"If your device name starts with wlx it most likely will show up like this (and if not, everything over 0x100 will be blank):"

My device (TP-Link Archer T2U Nano) starts with enx and as you said, everything after 0xf0 is blank. I tried different drivers but only the driver link you provided gave the efuse_set/get.

Can you help me with some hints on what I need to do next?

Warm regards from India.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment