ARM and SDIO WiFi Card

Some days ago I tried to disassemble the IPN2128 driver:

WLAN11b.dll, MD5 hash 3b8de73e7ed8cd7d8e930e9dea3ac10b

(the SDW-820 Windows Mobile 6 version from Spectec’s website)

It took me a bit of time to understand how the interface to the SD host works.

There is only one import from sdbus.dll named SDGetClientFunctions.

This is an undocumented function called by SDRegisterClient.

It will fill a structure at 0x10023960 with function pointers:

0x10023960+4 completes SDRegisterClient call

0x10023960+8 SDSynchronousBusRequest

0x10023960+20 SDCardInfoQuery

0x10023960+32 SDGetTuple

0x10023960+36 SDIOConnectInterrupt

0x10023960+40 SDIODisconnectInterrupt

0x10023960+44 SDSetCardFeature

See msdn.microsoft.com for documentation.

SDIODisconnectInterrupt is called by the functions at 0x100031bc and 0x100034a8

SDIOConnectInterrupt by 0x10003608 (=MiniportInitialize)

SDGetTuple by 0x1001be80

SDCardInfoQuery by 0x1001bfac

SDSetCardFeature by 0x1001bfac and 0x1001c1cc

SDSynchronousBusRequest is always called with Command=53 and Flags=0.

This implies use of BUILD_IO_RW_EXTENDED_ARG.

IncrementAddress is always 1.

Bulk reads and writes are done by 0x1001c590.

Bulk reads are always from address 0x6000 and

Bulk writes are always to address 0x3000, so these should be the frame buffers.

Single registers are 4 bytes long. They are read by 0x1001c40c and written by 0x1001c4d4.

These are adresses of registers that are read:

0, 8, 0x40, 0x48, 0x84, 0x104, 0x118, 0x194, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x224, 0x228, 0x240, 0x248, 0x294, 0x2a4, 0x304, 0x360, 0x364, 0x368, 0x36c, 0x374, 0x410, 0x41c, 0x440, 0x444, 0x478, 0x480, 0x484, 0x488, 0x48c, 0x490, 0x494, 0x498, 0x49c

These are adresses of registers that are written:

0, 8, 0xc, 0x14, 0x40, 0x44, 0x48, 0x80, 0x8c, 0x100, 0x108, 0x110, 0x114, 0x118, 0x12c, 0x188, 0x18c, 0x194, 0x200, 0x204, 0x208, 0x20c, 0x210, 0x214, 0x218, 0x224, 0x228, 0x248, 0x294, 0x2a4, 0x2a8, 0x300, 0x304, 0x308, 0x30c, 0x314, 0x360, 0x3a0, 0x3a4, 0x3a8, 0x3ac, 0x410, 0x41c, 0x420, 0x448, 0x44c, 0x450, 0x478, 0x480, 0x484, 0x488, 0x48c

These lists are probably incomplete.

(Does this look like Prism? If divided by four?)

There is a fourth function at 0x1001c658 doing transfers. It can read and write up to 511 bytes in byte mode.

It is called to

  • read 140 bytes from 0x104

  • read 16 bytes from 0x4000

  • read 52 bytes from 0x5000

  • read from 0x6000

  • write to 0x3000

  • write to and read from 0xa000

Many functions appear to be methods of a C++ class.

The NDIS adapter context appears to have an element of another class at offset 0x114AC.

class MiniportAdapterContext{
  ...
  NDIS_HANDLE MiniportAdapterHandle; // at 0x15c
  short NdisVersion; // at 0x160
  ...
  class {
    SD_DEVICE_HANDLE handle;
    uint8_t cardFunctionNumber;
    ...
  } atOffset0x114AC;
  ...
}; // 71296 bytes

Registered miniport callbacks are:

0x10003170 MiniportReset

0x100032c4 MiniportCheckForHang

0x100034a8 MiniportHalt

0x100035d4 MiniportPnPEventNotify

0x10003608 MiniportInitialize

0x100072d4 MiniportSendPackets

0x10009818 MiniportReturnPacket

0x1000a8fc MiniportSetInformation

0x1000b2d0 MiniportQueryInformation

0x1000bf8c MiniportShutdown

The SDIO interrupt callback is at 0x1001bd30.