firmware icon indicating copy to clipboard operation
firmware copied to clipboard

IF-SD-WIFI (ex. IPC_38x38-WIFI-if v1.02) support and reverse engineering

Open thedeadliestcatch opened this issue 1 year ago • 4 comments

References:

https://github.com/OpenIPC/firmware/issues/993#issuecomment-2059540801 (by @csvke)

This is tracking the effort to support the IF-SD-WIFI board support. Currently it carries an Altobeam 60321s WiFi IC, communicating through the USB bus.

Generic support is present in the firmware already but unfortunately this does not seem to enable the card:

# Generic ATBM603x
if [ "$1" = "atbm603x-generic-usb" ]; then
	modprobe atbm603x_wifi_usb
	exit 0
fi

(...)

# T31 ZTE K540
if [ "$1" = "atbm603x-t31-zte-k540" ]; then
	set_gpio 51 0
	modprobe atbm603x_wifi_usb
	exit 0
fi

After compiling a custom firmware with the following options:

BR2_PACKAGE_ATBM60XX=y
BR2_PACKAGE_ATBM60XX_MODEL_603X=y
BR2_PACKAGE_ATBM60XX_INTERFACE_USB=y

There is no apparent USB device listed in my case:

root@openipc-gk7205v300:~# lsusb
Bus 001 Device 001: ID 1d6b:0002
Bus 002 Device 001: ID 1d6b:0003

The original firmware did not contain any JSON files with explicit GPIO mentions for the duahgterboard:

        "Gpios2Env":
        {
        },
        "ChipPinsDemuxFixed":
        {
                "UART1_TXD": 0,
                "I2C1_SCL": 0,
                "UART1_RXD": 0,
                "I2C1_SDA": 0,
                "EMMC_CLK": 0,
                "SFC_CLK": "0x100C0014",
                "EMMC_CMD": 0,
                "SFC_MOSI_IO0": "0x100C0018",
                "EMMC_DATA0": 0,
                "SFC_MISO_IO1": "0x100C001C",
                "EMMC_DATA3": 0,
                "SFC_WP_IO2": "0x100C0020",
                "EMMC_DATA2": 0,
                "SFC_HOLD_IO3": "0x100C0024",
                "EMMC_DATA1": 0,
                "SFC_CSN": "0x100C0028",
                "SDIO1_CCLK_OUT": 0,
                "JTAG_TCK": 0,
                "SDIO1_CCMD": 0,
                "SDIO1_CDATA3": 0,
                "JTAG_TMS": 0,
                "SDIO1_CDATA2": 0,
                "JTAG_TDO": 0,
                "SDIO1_CDATA1": 0,
                "JTAG_TDI": 0,
                "SDIO1_CDATA0": 0,
                "JTAG_TRSTN": 0,
                "SDIO0_CARD_POWER_EN_N": 0,
                "SPI1_SCLK": 0,
                "SPI1_SDO": 0,
                "SPI1_CSN0": 0,
                "SPI1_SDI": 0,
                "PWM2": 0,
                "PWM3": 0,
                "SENSOR_CLK": "0x112C0028",
                "SENSOR_RSTN": "0x112C002C",
                "I2C0_SDA": "0x112C0030",
                "I2C0_SCL": "0x112C0034",
                "VI_HS": 0,
                "I2C2_SDA": 0,
                "SPI0_SDO": 0,

(...)

PCB photos: image

Example mainboard: image

thedeadliestcatch avatar Jul 07 '24 18:07 thedeadliestcatch

@funkypozzy's backup contains the WiFI support:

        },
    "WlanParams": {
    "ResetGpio": [8, 3],
    "PowerGpio": [0, 7],
    "KeyCounts": 3
        }

undefined4 LibXmDvr_WlanGpioInit(int *param_1)

{
  undefined *product_params;
  undefined4 uVar1;
  
  product_params = XmDvr_JsonParser_getProductParams();
  if (param_1 == NULL) {
    uVar1 = 0xffffffff;
  }
  else {
    *param_1 = *(int *)(product_params + 0x288) + *(int *)(product_params + 0x284) * 0x10;
    param_1[1] = *(int *)(product_params + 0x290) + *(int *)(product_params + 0x28c) * 0x10;
    uVar1 = 0;
    param_1[2] = *(int *)(product_params + 0x294);
  }
  return uVar1;
}


undefined4 LibXmDvr_WlanPowerGpioLevelInit(undefined4 *param_1)

{
  undefined *puVar1;
  undefined4 uVar2;
  
  puVar1 = XmDvr_JsonParser_getProductParams();
  if (param_1 == NULL) {
    uVar2 = 0xffffffff;
  }
  else {
    uVar2 = 0;
    *param_1 = *(undefined4 *)(puVar1 + 0x298);
  }
  return uVar2;
}

The initialization is done by XmWlanDaemon:

LAB_000127d8:
        LibXmDvr_WlanGpioInit(&WlanGpio_0004328c);
        LibXmDvr_WlanPowerGpioLevelInit(&WlanPowerGpioLevel_00043298);
        printf("g_wifiState.keyShortTimes[%d], gpioPower[%#x], gpioPowerLevel[%d]\n",
               keySHortTimes_00043294,WifiGpioPower_00043290,WlanPowerGpioLevel_00043298);
        LibXmDvr_WlanTxPowerInit(&WlanTxPower_0004326c);
        if (DAT_00043670 == 0) {
          if (DAT_00043704 == '\0') {
            pthread_create(&local_308,NULL,FUN_00017534,NULL);
          }
          pthread_create(&local_300,NULL,AutoSwitchAPSTA,NULL);
          pthread_create(&local_304,NULL,CheckNetState,NULL);
          DAT_00043670 = 1;
        }
        FUN_00016048("rm /dev/random","eth2",0,1);
        FUN_00016048("ln -s /dev/urandom /dev/random","eth2",0,1);
        FUN_00016048("mkdir /var/run/hostapd -p","eth2",0,1);
        FUN_00016048("mkdir /var/run/wpa_supplicant -p","eth2",0,1);
        if (WifiType == 1) {
          system("echo \"set ps 1\" > /proc/lynx ");
        }
        bVar1 = false;
        bVar16 = false;
        local_338 = 0;
        local_330 = 0;
        iVar3 = -1;

thedeadliestcatch avatar Jul 07 '24 19:07 thedeadliestcatch

This PR contains the necessary bits (except for the atbm603x specific support)

https://github.com/OpenIPC/firmware/pull/1329/commits/ab86bc420fb332cbde4a9184df9291263f5ee457

       gpio clear 7
        devmem 0x100C0080 32 0x00000530

Older models (200 series) had an user reporting a different GPIO pin set:

https://github.com/OpenIPC/firmware/issues/1460

After successful GPIO + memory register setup:

[  881.164725] usb 1-1: new high-speed USB device number 2 using xhci-hcd
[  881.336303] [atbm_log]:Probe called -1 v1
[  881.336321] [atbm_log]:not CONFIG_USE_DMA_ADDR_BUFFER
[  881.336420] [atbm_log]:CONFIG_TX_NO_CONFIRM
[  881.336512] [atbm_log]:Allocated hw_priv @ c0b46ec0
[  881.345262] [atbm_log]:atbmwifi USB_USE_TASTLET_TXRX enable (c0b46ec0)
[  881.345271] [atbm_log]:atbmwifi USB_USE_TASTLET_TXRX enable (c0b46ec0)
[  881.345275] [atbm_log]:atbm_before_load_firmware++
[  881.345706] [atbm_log]:atbm_HwGetChipType, chipver=0x49, g_wifi_chip_type[10]

Power inputs in the module can be verified with a DMM.

thedeadliestcatch avatar Jul 07 '24 20:07 thedeadliestcatch

@funkypozzy's backup contains the WiFI support:

        },
    "WlanParams": {
    "ResetGpio": [8, 3],
    "PowerGpio": [0, 7],
    "KeyCounts": 3
        }
undefined4 LibXmDvr_WlanGpioInit(int *param_1)

{
  undefined *product_params;
  undefined4 uVar1;
  
  product_params = XmDvr_JsonParser_getProductParams();
  if (param_1 == NULL) {
    uVar1 = 0xffffffff;
  }
  else {
    *param_1 = *(int *)(product_params + 0x288) + *(int *)(product_params + 0x284) * 0x10;
    param_1[1] = *(int *)(product_params + 0x290) + *(int *)(product_params + 0x28c) * 0x10;
    uVar1 = 0;
    param_1[2] = *(int *)(product_params + 0x294);
  }
  return uVar1;
}


undefined4 LibXmDvr_WlanPowerGpioLevelInit(undefined4 *param_1)

{
  undefined *puVar1;
  undefined4 uVar2;
  
  puVar1 = XmDvr_JsonParser_getProductParams();
  if (param_1 == NULL) {
    uVar2 = 0xffffffff;
  }
  else {
    uVar2 = 0;
    *param_1 = *(undefined4 *)(puVar1 + 0x298);
  }
  return uVar2;
}

The initialization is done by XmWlanDaemon:

LAB_000127d8:
        LibXmDvr_WlanGpioInit(&WlanGpio_0004328c);
        LibXmDvr_WlanPowerGpioLevelInit(&WlanPowerGpioLevel_00043298);
        printf("g_wifiState.keyShortTimes[%d], gpioPower[%#x], gpioPowerLevel[%d]\n",
               keySHortTimes_00043294,WifiGpioPower_00043290,WlanPowerGpioLevel_00043298);
        LibXmDvr_WlanTxPowerInit(&WlanTxPower_0004326c);
        if (DAT_00043670 == 0) {
          if (DAT_00043704 == '\0') {
            pthread_create(&local_308,NULL,FUN_00017534,NULL);
          }
          pthread_create(&local_300,NULL,AutoSwitchAPSTA,NULL);
          pthread_create(&local_304,NULL,CheckNetState,NULL);
          DAT_00043670 = 1;
        }
        FUN_00016048("rm /dev/random","eth2",0,1);
        FUN_00016048("ln -s /dev/urandom /dev/random","eth2",0,1);
        FUN_00016048("mkdir /var/run/hostapd -p","eth2",0,1);
        FUN_00016048("mkdir /var/run/wpa_supplicant -p","eth2",0,1);
        if (WifiType == 1) {
          system("echo \"set ps 1\" > /proc/lynx ");
        }
        bVar1 = false;
        bVar16 = false;
        local_338 = 0;
        local_330 = 0;
        iVar3 = -1;

@thedeadliestcatch Could you please make clear to me if the issue is now closed or witch further steps are needed to make this IF-SD-WIFI (ex. IPC_38x38-WIFI-if v1.02) board working? Thanks.

funkypozzy avatar Jul 19 '24 16:07 funkypozzy

@Nuts-Underline @csvke @thedeadliestcatch

After the following modification to \etc\wireless\usb it works for me: https://github.com/OpenIPC/firmware/pull/1497/files

Need also to

  1. build firmware with proper drivers for ATBM603x

  2. define the wlandev variable accordingly: fw_setenv wlandev IPC-38x38-WIFI-atbm603x-usb

  3. define SSID and Password fw_setenv wlanssid MySSID fw_setenv wlanpass MyPassword

In case of issue try also to run: ifup -v wlan0 ifup -v eth0 (if you need ethernet)

funkypozzy avatar Jul 23 '24 09:07 funkypozzy