目前共有13篇帖子。 字体大小:较小 - 100% (默认)▼  内容转换:不转换▼
 
点击 回复
71 12
【笔记】whd_chip_specific_init
一派掌门 二十级
1楼 发表于:2025-11-30 17:43

whd_chip_specific_init = whd_enable_save_restore
  whd_is_fw_sr_capable
    read backplane CHIPCOMMON_SR_CONTROL1(0x18000508),4 = 0x000001F8
    return WHD_TRUE
 
  // Configure WakeupCtrl register to set HtAvail request bit in chipClockCSR register
  // after the sdiod core is powered on.
  read func1 SDIO_WAKEUP_CTRL(0x0001001E),1 = 0x00
  write func1 SDIO_WAKEUP_CTRL(0x0001001E),1 = 0x02

  // Set brcmCardCapability to noCmdDecode mode.
  // It makes sdiod_aos to wakeup host for any activity of cmd line, even though

  // module won't decode cmd or respond

  write func0 0xF0,1 = 0x08
  write func1 0x1000E,1 = 0x02

  // Enable KeepSdioOn (KSO) bit for normal operation
  read func1 0x1001F,1 = 0x03

  // SPI bus can be configured for sleep by default.
  // KSO bit solely controls the wlan chip sleep
  whd_bus_sleep
    return WHD_SUCCESS

  // Put SPI interface block to sleep
  write func1 0x1000F,1 = 0x0f

whd_ensure_wlan_bus_is_up
  whd_bus_is_up
    return whd_driver->bus_common_info->bus_is_up (=0)

  whd_kso_enable
    write_value = SBSDIO_SLPCSR_KEEP_WL_KSO (=0x01)
    // 1st KSO write goes to AOS wake up core if device is asleep
    // Possibly device might not respond to this cmd. So, don't check return value here
    // 2 Sequential writes to KSO bit are required for SR module to wakeup, both write can fail
    write func1 0x1001F,1 = 0x01
    write func1 0x1001F,1 = 0x01
   
    // device WAKEUP through KSO:
 write bit 0 & read back until both bits 0(kso bit) & 1 (dev on status) are set
    compare_value = SBSDIO_SLPCSR_KEEP_WL_KSO | SBSDIO_SLPCSR_WL_DEVON (=0x03)
    bmask = compare_value;
   
    do:
      // Reliable KSO bit set/clr:
      // Sdiod sleep write access appears to be in sync with PMU 32khz clk
      // just one write attempt may fail,(same is with read ?)
      // in any case, read it back until it matches written value

      read func1 0x1001F,1 = 0x03
    while ((read_value & bmask) != compare_value || read_value == 0xFF)

whd_proto_attach
  whd_cdc_bdc_info_init

/* Download blob file if exists */
whd_process_clm_data
  clm_blob_size = 7222
  blocks_count = 8
  data_offset = 12
  size2alloc = 12+1024 = 1036

  C:\Users\Octopus\Desktop\test\f4_20251119_4bit\Middlewares\Third_Party\Infineon_Wireless_Connectivity\wifi-host-driver\COMPONENT_WIFI5\resources\clm\COMPONENT_43439\COMPONENT_MURATA-1YN\43439A0_clm_blob.c
  wifi_firmware_clm_blob
    dl_flag = DL_BEGIN
    if (end)
      dl_flag |= DL_END
    whd_download_wifi_clm_image(ifp, IOVAR_STR_CLMLOAD, dl_flag, DL_TYPE_CLM, chunk_buf, data_offset + chunk_len)
      dload_ptr->flag = (1 << 12) | dl_flag = 0x1002
      dload_ptr->dload_type = DL_TYPE_CLM (=2)
      dload_ptr->len = 1036-12=1024
      crc = ?
      len = size2alloc = 1036
      len = len + 8 - (len % 8) = 1036+8-(1036%8)=1036+8-4=1040
      name = "clmload"
      name_length = 8
      name_length_alignment_offset = 0
      pbuf->len = IOCTL_OFFSET(36) + data_length(1040) + name_length(8) + name_length_alignment_offset = 1084
      iov_data = &pbuf->payload[IOCTL_OFFSET + name_length + name_length_alignment_offset] = &pbuf->payload[44]
      memcpy(iov_data, (wl_dload_data_t *)dload_ptr, 1040)
      whd_proto_set_iovar(pbuf)
        whd_cdc_set_iovar
          whd_cdc_send_iovar
            whd_cdc_send_ioctl (type=CDC_SET=2, command=WLC_SET_VAR=263)
              data_length = pbuf->len - sizeof(bus_common_header_t) - sizeof(cdc_header_t) = 1048
              send_packet = pbuf->payload
              data = (uint8_t *)send_packet + sizeof(control_header_t) = &pbuf->payload[36] = &pbuf->payload[IOCTL_OFFSET]
              /* Calculate the offset added to compensate for IOVAR string creating unaligned data section */
              // remove name_length_alignment_offset
              memmove(data, data + name_length_alignment_offset, data_length - name_length_alignment_offset)
              data_length -= name_length_alignment_offset
              /* Prepare the CDC header */
              send_packet->cdc_header.cmd = 263
              send_packet->cdc_header.len = 1048 = data_length(1040) + name_length(8)
              send_packet->cdc_header.flags = 0x50002
              send_packet->cdc_header.status = 0
              whd_send_to_bus
                size=pbuf->len-sizeof(whd_buffer_header_t)=1084-8=1076
                (control_header_t *)(pbuf->payload)->common.bus_header = (sdpcm_header_t)sdpcm_header // sizeof(sdpcm_header_t)=12
                prio=8 // prio 8   : Control(4)(ex: IOVAR/IOCTL)
                ac=4
                cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE)
                whd_thread_notify(whd_driver)
                  cy_rtos_set_semaphore(&whd_driver->thread_info.transceive_semaphore, WHD_FALSE)
*               whd_thread_send_one_packet
                  whd_sdpcm_get_packet_to_send
                    send_packet->common.bus_header.sw_header.sequence = sdpcm_info->tx_seq
                  whd_bus_send_buffer
                    whd_bus_transfer_bytes(pbuf->payload + sizeof(struct pbuf *), pbuf->len - sizeof(struct pbuf *)) // pbuf->payload+4, 1084-4=1080
                      whd_bus_sdio_transfer_bytes(((whd_transfer_bytes_packet_t *)data)->data, 1080) // pbuf->payload+8, 1080
                        CMD53 WRITE func2 addr=0 size=1024 BLOCK_MODE
                        CMD53 WRITE func2 addr=1024 size=56 MULTIBYTE_MODE
*               whd_bus_packet_available_to_read
                  whd_bus_sdio_packet_available_to_read
                    // Read the IntStatus
                    read backplane SDIO_INT_STATUS(0x18002020),4 = 0x00820040
                    #define SDIO_INT_STATUS(wd) GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x20 (=0x18002000+0x20)
                    // Clear any interrupts
                    write backplane SDIO_INT_STATUS(0x18002020),4 = (int_status & HOSTINTMASK)
                    if (int_status & I_HMB_FRAME_IND) // &0x40
                      whd_thread_receive_one_packet
                        whd_bus_read_frame
                          whd_bus_sdio_read_frame
                            hwtag = CMD53 READ func2 addr=0 size=4 MULTIBYTE_MODE
                            if (*(uint16_t *)data != 12)
                              extra_space_required = hwtag - INITIAL_READ;
                              alloc buffer(INITIAL_READ + extra_space_required + sizeof(whd_buffer_header_t)) //(1084)
                              // the first byte read is the first byte of sdpcm_header_t
                              memcpy(packet->common.bus_header, hwtag, 4)
                              CMD53 READ func2 addr=0 size=extra_space_required
                              if (failed)
                                whd_bus_sdio_abort_read
*               whd_thread_receive_one_packet
    dl_flag &= ~DL_BEGIN

一派掌门 二十级
2楼 发表于:2025-11-30 17:43

typedef struct
{

  bus_common_header_t common; //=20
  cdc_header_t cdc_header; //=4*4=16
} control_header_t; //=36

typedef struct
{
  whd_buffer_header_t buffer_header;
 //=8
  uint8_t bus_header[BUS_HEADER_LEN]; //=12 (sdpcm_header_t)
} bus_common_header_t;

typedef struct
{

  whd_buffer_queue_ptr_t queue_next; //=4 (struct pbuf *)
  char bus_header[MAX_BUS_HEADER_SIZE]; //=4 (whd_transfer_bytes_packet_t::bus_header)

} whd_buffer_header_t;

typedef struct
{

  uint32_t cmd;    /* ioctl command value */

  uint32_t len;    /* lower 16: output buflen; upper 16: input buflen (excludes header) */

  uint32_t flags;  /* flag defns given in bcmcdc.h */

  uint32_t status; /* status code returned from the device */

} cdc_header_t;


typedef struct
{
  uint16_t frametag[2]; //=4 ={size, ~size}
  sdpcm_sw_header_t sw_header; //=6+2=8 (channel_and_flags, header_length, sequence)

} sdpcm_header_t; //=12
typedef struct
{
  uint8_t sequence;               /* Rx/Tx sequence number */
  uint8_t channel_and_flags;      /*  4 MSB Channel number, 4 LSB arbitrary flag */

  uint8_t next_length;            /* Length of next data frame, reserved for Tx */

  uint8_t header_length;          /* Data offset */

  uint8_t wireless_flow_control;  /* Flow control bits, reserved for Tx */

  uint8_t bus_data_credit;        /* Maximum Sequence number allowed by firmware for Tx */

  uint8_t _reserved[2];           /* Reserved */

} sdpcm_sw_header_t;

typedef struct
{

  uint8_t bus_header[MAX_BUS_HEADER_SIZE]; // 4
  uint32_t data[1];

} whd_transfer_bytes_packet_t;

 
一派掌门 二十级
3楼 发表于:2025-11-30 20:52

下载CLM固件时,CMD53发送的数据是pbuf->payload[8~1087], 共1080字节数据,分两次发送。
第一次:CMD53 WRITE func2 addr=0 size=1024 BLOCK_MODE
第二次:CMD53 WRITE func2 addr=1024 size=56 MULTIBYTE_MODE


pbuf->payload=malloc(1084)
pbuf->len=1084


pbuf->payload数据结构:
[0-35] control_header_t
[36-43] 8字节name="clmload"字符串
[44-55] 12字节clm固件头部信息(struct wl_dload_data)
[56-1079] 1024字节clm固件数据
[1080-1083] padding(填充字节)

 
巨大八爪鱼:最后pbuf->payload[1084~1087]这四字节内容是在malloc内存区以外,是随机数据。
  2025-11-30 20:59 回复
一派掌门 二十级
4楼 发表于:2025-11-30 20:55

前36字节([0-35)的数据结构:

typedef struct
{

  bus_common_header_t common; // 20字节 [0~19]
  cdc_header_t cdc_header; // 16字节 [20~35]
} control_header_t; // 36字节


typedef struct
{
  whd_buffer_header_t buffer_header; // 8字节 [0~7](CMD53不发送此数据)
  uint8_t bus_header[BUS_HEADER_LEN]; // 12字节 (sdpcm_header_t) [8~19]
} bus_common_header_t;


typedef struct
{

  whd_buffer_queue_ptr_t queue_next; // 4字节 (struct pbuf *) [0~3](CMD53不发送此数据)
  char bus_header[MAX_BUS_HEADER_SIZE]; // 4字节 (whd_transfer_bytes_packet_t::bus_header) [4~7](CMD53不发送此数据)
} whd_buffer_header_t;


typedef struct
{

  uint8_t bus_header[MAX_BUS_HEADER_SIZE]; // [4-7]
  uint32_t data[1]; // [8-]

} whd_transfer_bytes_packet_t;


typedef struct
{
  uint16_t frametag[2]; // 4字节 {size, ~size} [8~11]
  sdpcm_sw_header_t sw_header; // 6+2=8字节 (channel_and_flags, header_length, sequence) [12~19]

} sdpcm_header_t; // 共12字节


typedef struct
{
  uint8_t sequence;               /* Rx/Tx sequence number */ // [12]
  uint8_t channel_and_flags;      /*  4 MSB Channel number, 4 LSB arbitrary flag */ // [13]
  uint8_t next_length;            /* Length of next data frame, reserved for Tx */ // [14]
  uint8_t header_length;          /* Data offset */ // [15]
  uint8_t wireless_flow_control;  /* Flow control bits, reserved for Tx */ // [16]
  uint8_t bus_data_credit;        /* Maximum Sequence number allowed by firmware for Tx */ // [17]
  uint8_t _reserved[2];           /* Reserved */ // [18-19]

} sdpcm_sw_header_t;


typedef struct
{

  uint32_t cmd;    /* ioctl command value */ // [20~23]
  uint32_t len;    /* lower 16: output buflen; upper 16: input buflen (excludes header) */ // [24~27]
  uint32_t flags;  /* flag defns given in bcmcdc.h */ // [28~31]
  uint32_t status; /* status code returned from the device */ // [32~35]

} cdc_header_t;

 
一派掌门 二十级
5楼 发表于:2025-11-30 20:56

[44-55] 12字节clm固件头部信息(struct wl_dload_data)的数据结构:

struct wl_dload_data
{

  uint16_t flag; // [44~45]
  uint16_t dload_type; // [46~47]
  uint32_t len; // [48~51]
  uint32_t crc; // [52~55]
};

 
一派掌门 二十级
6楼 发表于:2025-11-30 21:09

sdpcm_header.frametag({size, ~size})是在whd_send_to_bus函数里面填写的。
其中size=pbuf->len-sizeof(whd_buffer_header_t)=1084-8=1076,表示pbuf->payload里面CMD53要发送的部分的大小。CMD53不发送pbuf->payload前8个字节。

 
一派掌门 二十级
7楼 发表于:2025-11-30 21:18
CMD53接收回应时,分配的内存空间仍然是1084字节,CMD53只接收1076字节数据,保存到pbuf->payload[8:1083]。
pbuf->payload数据结构:
[0-7] whd_buffer_header_t
[8-11] INITIAL_READ hwtag {size, ~size} 表示收到的数据包大小
[12-1083] extra_space_required 剩余数据内容
 
一派掌门 二十级
8楼 发表于:2025-11-30 21:22
CMD53无论是发送还是接收,前四个字节都是frametag[2] {size, ~size}。
 
一派掌门 二十级
9楼 发表于:2025-11-30 21:28

扫描热点时CMD53发送的数据结构:

[12-byte sdpcm_header_t] (filled) 0x24015d2c
[16-byte cdc_header_t] (filled)
[6-byte name with \0] (filled)
[72-byte scan_params] (filled)
[4-byte] 随机数据
共12+16+6+72+4=110字节。


pbuf=0x24015d14
pbuf->tot_len=114
pbuf->len=114
pbuf->payload=0x24015d24


pbuf payload structure:
[4-byte ((whd_buffer_header_t)buffer_header).queue_next] (filled) 0x24015d24
[4-byte ((whd_buffer_header_t)buffer_header).bus_header] (not filled) 0x24015d28
[12-byte sdpcm_header_t] (filled) 0x24015d2c
[16-byte cdc_header_t] (filled)
[6-byte name with \0] (filled)
[72-byte scan_params] (filled)
4+4+12+16+6+72=114


CMD53发送的是pbuf->payload[8-113]和后续的[114-117]随机数据。

 
巨大八爪鱼:其中name="escan",共6字节。
  2025-11-30 21:30 回复
一派掌门 二十级
10楼 发表于:2025-12-4 22:18
send_packet->cdc_header.len = 1048 = data_length(1040) + name_length(8)写错了,应该是send_packet->cdc_header.len = 1048 = data_length(1048)才对。
 
一派掌门 二十级
11楼 发表于:2025-12-4 22:22

pbuf->len = IOCTL_OFFSET(36) + data_length(1040) + name_length(8) + name_length_alignment_offset = 1084写错了,应该是pbuf->len = IOCTL_OFFSET(36) + data_length(1048) + name_length_alignment_offset = 1084才对。

data_length=1048是包含了8字节的name_length的。

 

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:71 回复数:12
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2025-12-4 22:22
 
©2010-2025 Purasbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。