/******************************************************************************
 *
 * Copyright(c) 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2014 Intel Mobile Communications GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
#include "iwl-dnt-dev-if.h"

#include <linux/export.h>
#include <linux/types.h>
#include <linux/vmalloc.h>

#include "iwl-csr.h"
#include "iwl-debug.h"
#include "iwl-dnt-cfg.h"
#include "iwl-io.h"
#include "iwl-prph.h"
#include "iwl-tm-gnl.h"
#include "iwl-trans.h"

static void iwl_dnt_dev_if_configure_mipi(struct iwl_trans* trans) {
  if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
    iwl_trans_set_bits_mask(trans, trans->dbg_cfg.dbg_mipi_conf_reg,
                            trans->dbg_cfg.dbg_mipi_conf_mask, trans->dbg_cfg.dbg_mipi_conf_mask);
    return;
  }

  /* ABB_CguDTClkCtrl - set system trace and mtm clock souce as PLLA */
  iowrite32(0x30303, (void __force __iomem*)0xe640110c);

  /* ABB_SpcuMemPower - set the power of the trace memory */
  iowrite32(0x1, (void __force __iomem*)0xe640201c);

  /* set MIPI2 PCL, PCL_26 - PCL_30 */
  iowrite32(0x10, (void __force __iomem*)0xe6300274);
  iowrite32(0x10, (void __force __iomem*)0xe6300278);
  iowrite32(0x10, (void __force __iomem*)0xe630027c);
  iowrite32(0x10, (void __force __iomem*)0xe6300280);
  iowrite32(0x10, (void __force __iomem*)0xe6300284);

  /* ARB0_CNF - enable generic arbiter */
  iowrite32(0xc0000000, (void __force __iomem*)0xe6700108);

  /* enable WLAN arbiter */
  iowrite32(0x80000006, (void __force __iomem*)0xe6700140);
}

static void iwl_dnt_dev_if_configure_marbh(struct iwl_trans* trans) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  uint32_t ret, reg_val = 0;

  if (cfg->dbg_marbh_access_type == ACCESS_TYPE_DIRECT) {
    iwl_trans_set_bits_mask(trans, cfg->dbg_marbh_conf_reg, cfg->dbg_marbh_conf_mask,
                            cfg->dbg_marbh_conf_mask);
  } else if (cfg->dbg_marbh_access_type == ACCESS_TYPE_INDIRECT) {
    ret = iwl_trans_read_mem(trans, cfg->dbg_marbh_conf_reg, &reg_val, 1);
    if (ret) {
      IWL_ERR(trans, "Failed to read MARBH conf reg\n");
      return;
    }
    reg_val |= cfg->dbg_marbh_conf_mask;
    ret = iwl_trans_write_mem(trans, cfg->dbg_marbh_conf_reg, &reg_val, 1);
    if (ret) {
      IWL_ERR(trans, "Failed to write MARBH conf reg\n");
      return;
    }
  } else {
    IWL_ERR(trans, "Invalid MARBH access type\n");
  }
}

static void iwl_dnt_dev_if_configure_dbgc_registers(struct iwl_trans* trans, uint32_t base_addr,
                                                    uint32_t end_addr) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;

  switch (trans->tmdev->dnt->cur_mon_type) {
    case SMEM:
      iwl_write_prph(trans, cfg->dbgc_hb_base_addr, cfg->dbgc_hb_base_val_smem);
      iwl_write_prph(trans, cfg->dbgc_hb_end_addr, cfg->dbgc_hb_end_val_smem);

      /*
       * SMEM requires the same internal configuration as MARBH,
       * which preceded it.
       */
      iwl_dnt_dev_if_configure_marbh(trans);
      break;

    case DMA:
    default:
      /*
       * The given addresses are already shifted by 4 places so we
       * need to shift by another 4.
       * Note that in SfP the end addr points to the last block of
       * data that the DBGC can write to, so when setting the end
       * register we need to set it to 1 block before.
       */
      iwl_write_prph(trans, cfg->dbgc_hb_base_addr, base_addr >> 4);
      iwl_write_prph(trans, cfg->dbgc_hb_end_addr, (end_addr >> 4) - 1);
      break;
  };
}

static void iwl_dnt_dev_if_configure_dbgm_registers(struct iwl_trans* trans, uint32_t base_addr,
                                                    uint32_t end_addr) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;

  /* If we're running a device that supports DBGC - use it */
  if (trans->cfg->dbgc_supported) {
    iwl_dnt_dev_if_configure_dbgc_registers(trans, base_addr, end_addr);
    return;
  }

  /* configuring monitor */
  iwl_write_prph(trans, cfg->dbg_mon_buff_base_addr_reg_addr, base_addr);
  iwl_write_prph(trans, cfg->dbg_mon_buff_end_addr_reg_addr, end_addr);
  iwl_write_prph(trans, cfg->dbg_mon_data_sel_ctl_addr, cfg->dbg_mon_data_sel_ctl_val);
  iwl_write_prph(trans, cfg->dbg_mon_mc_msk_addr, cfg->dbg_mon_mc_msk_val);
  iwl_write_prph(trans, cfg->dbg_mon_sample_mask_addr, cfg->dbg_mon_sample_mask_val);
  iwl_write_prph(trans, cfg->dbg_mon_start_mask_addr, cfg->dbg_mon_start_mask_val);
  iwl_write_prph(trans, cfg->dbg_mon_end_threshold_addr, cfg->dbg_mon_end_threshold_val);
  iwl_write_prph(trans, cfg->dbg_mon_end_mask_addr, cfg->dbg_mon_end_mask_val);
  iwl_write_prph(trans, cfg->dbg_mon_sample_period_addr, cfg->dbg_mon_sample_period_val);
  /* starting monitor */
  iwl_write_prph(trans, cfg->dbg_mon_sample_ctl_addr, cfg->dbg_mon_sample_ctl_val);
}

static int iwl_dnt_dev_if_retrieve_dma_monitor_data(struct iwl_dnt* dnt, struct iwl_trans* trans,
                                                    void* buffer, uint32_t buffer_size) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  uint32_t wr_ptr, wrap_cnt;
  bool dont_reorder = false;
  /* FIXME send stop command to FW */
  if (WARN_ON_ONCE(!dnt->mon_buf_cpu_addr)) {
    IWL_ERR(trans, "Can't retrieve data - DMA wasn't allocated\n");
    return -ENOMEM;
  }

  /* If we're running a device that supports DBGC - use it */
  if (trans->cfg->dbgc_supported) {
    wr_ptr = iwl_read_prph(trans, cfg->dbgc_dram_wrptr_addr);
  } else {
    wr_ptr = iwl_read_prph(trans, cfg->dbg_mon_wr_ptr_addr);
  }
  /* iwl_read_prph returns 0x5a5a5a5a when it fails to grab nic access */
  if (wr_ptr == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read write pointer - not reordering buffer\n");
    dont_reorder = true;
  }

  /* If we're running a device that supports DBGC.... */
  if (trans->cfg->dbgc_supported)
  /*
   * wr_ptr is given relative to the base address, in
   * DWORD granularity, and points to the next chunk to
   * write to - i.e., the oldest data in the buffer.
   */
  {
    wr_ptr <<= 2;
  } else {
    wr_ptr = (wr_ptr << 4) - dnt->mon_base_addr;
  }

  /* Misunderstanding wr_ptr can cause a page fault, so validate it... */
  if (wr_ptr > dnt->mon_buf_size) {
    IWL_ERR(trans, "Write pointer DMA monitor register points to invalid data - setting to 0\n");
    dont_reorder = true;
  }

  /* We have a problem with the wr_ptr, so just return the memory as-is */
  if (dont_reorder) {
    wr_ptr = 0;
  }

  if (cfg->dbgc_wrap_count_addr) {
    wrap_cnt = iwl_read_prph(trans, cfg->dbgc_wrap_count_addr);
  } else {
    wrap_cnt = 1;
  }

  if (wrap_cnt) {
    memcpy(buffer, dnt->mon_buf_cpu_addr + wr_ptr, dnt->mon_buf_size - wr_ptr);
    memcpy(buffer + dnt->mon_buf_size - wr_ptr, dnt->mon_buf_cpu_addr, wr_ptr);
  } else {
    memcpy(buffer, dnt->mon_buf_cpu_addr, wr_ptr);
    memset(buffer + wr_ptr, 0, dnt->mon_buf_size - wr_ptr);
  }

  return dnt->mon_buf_size;
}

static int iwl_dnt_dev_if_retrieve_marbh_monitor_data(struct iwl_dnt* dnt, struct iwl_trans* trans,
                                                      uint8_t* buffer, uint32_t buffer_size) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  int buf_size_in_dwords, buf_index, i;
  uint32_t wr_ptr, read_val;

  /* FIXME send stop command to FW */

  wr_ptr = iwl_read_prph(trans, cfg->dbg_mon_wr_ptr_addr);
  /* iwl_read_prph returns 0x5a5a5a5a when it fails to grab nic access */
  if (wr_ptr == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read write pointer\n");
    return -ENODEV;
  }

  read_val = iwl_read_prph(trans, cfg->dbg_mon_buff_base_addr_reg_addr);
  if (read_val == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read monitor base address\n");
    return -ENODEV;
  }
  dnt->mon_base_addr = read_val;

  read_val = iwl_read_prph(trans, cfg->dbg_mon_buff_end_addr_reg_addr);
  if (read_val == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read monitor end address\n");
    return -ENODEV;
  }
  dnt->mon_end_addr = read_val;

  wr_ptr = wr_ptr - dnt->mon_base_addr;
  iwl_write_prph(trans, cfg->dbg_mon_dmarb_rd_ctl_addr, 0x00000001);

  /* buf size includes the end_addr as well */
  buf_size_in_dwords = dnt->mon_end_addr - dnt->mon_base_addr + 1;
  for (i = 0; i < buf_size_in_dwords; i++) {
    /* reordering cyclic buffer */
    buf_index = (i + (buf_size_in_dwords - wr_ptr)) % buf_size_in_dwords;
    read_val = iwl_read_prph(trans, cfg->dbg_mon_dmarb_rd_data_addr);
    memcpy(&buffer[buf_index * sizeof(uint32_t)], &read_val, sizeof(uint32_t));
  }
  iwl_write_prph(trans, cfg->dbg_mon_dmarb_rd_ctl_addr, 0x00000000);

  return buf_size_in_dwords * sizeof(uint32_t);
}

static int iwl_dnt_dev_if_retrieve_smem_monitor_data(struct iwl_dnt* dnt, struct iwl_trans* trans,
                                                     uint8_t* buffer, uint32_t buffer_size) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  uint32_t i, bytes_to_end, calc_size;
  uint32_t base_addr, end_addr, wr_ptr_addr, wr_ptr_shift;
  uint32_t base, end, wr_ptr, pos, chunks_num, wr_ptr_offset, wrap_cnt;
  uint8_t* temp_buffer;

  /* assuming B-step or C-step */
  base_addr = cfg->dbg_mon_buff_base_addr_reg_addr_b_step;
  end_addr = cfg->dbg_mon_buff_end_addr_reg_addr_b_step;
  wr_ptr_addr = cfg->dbg_mon_wr_ptr_addr_b_step;
  wr_ptr_shift = 2;

  base = iwl_read_prph(trans, base_addr);
  /* iwl_read_prph returns 0x5a5a5a5a when it fails to grab nic access */
  if (base == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read base addr\n");
    return -ENODEV;
  }

  end = iwl_read_prph(trans, end_addr);
  /* iwl_read_prph returns 0x5a5a5a5a when it fails to grab nic access */
  if (end == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read end addr\n");
    return -ENODEV;
  }

  if (base == end) {
    IWL_ERR(trans, "Invalid base and end values\n");
    return -ENODEV;
  }

  wr_ptr = iwl_read_prph(trans, wr_ptr_addr);
  /* iwl_read_prph returns 0x5a5a5a5a when it fails to grab nic access */
  if (wr_ptr == 0x5a5a5a5a) {
    IWL_ERR(trans, "Can't read write pointer, not re-aligning\n");
    wr_ptr = base << 8;
  }

  pos = base << 8;
  calc_size = (end - base + 1) << 8;
  wr_ptr <<= wr_ptr_shift;
  bytes_to_end = ((end + 1) << 8) - wr_ptr;
  chunks_num = calc_size / DNT_CHUNK_SIZE;
  wr_ptr_offset = wr_ptr - pos;

  if (wr_ptr_offset > calc_size) {
    IWL_ERR(trans, "Invalid wr_ptr value, not re-aligning\n");
    wr_ptr_offset = 0;
  }

  if (calc_size > buffer_size) {
    IWL_ERR(trans, "Invalid buffer size\n");
    return -EINVAL;
  }

  temp_buffer = kzalloc(calc_size, GFP_KERNEL);
  if (!temp_buffer) {
    return -ENOMEM;
  }

  for (i = 0; i < chunks_num; i++)
    iwl_trans_read_mem(trans, pos + (i * DNT_CHUNK_SIZE), temp_buffer + (i * DNT_CHUNK_SIZE),
                       DNT_CHUNK_SIZE / sizeof(uint32_t));

  if (calc_size % DNT_CHUNK_SIZE)
    iwl_trans_read_mem(trans, pos + (chunks_num * DNT_CHUNK_SIZE),
                       temp_buffer + (chunks_num * DNT_CHUNK_SIZE),
                       (calc_size - (chunks_num * DNT_CHUNK_SIZE)) / sizeof(uint32_t));

  if (cfg->dbgc_wrap_count_addr) {
    wrap_cnt = iwl_read_prph(trans, cfg->dbgc_wrap_count_addr);
  } else {
    wrap_cnt = 1;
  }

  if (wrap_cnt) {
    memcpy(buffer, temp_buffer + wr_ptr_offset, bytes_to_end);
    memcpy(buffer + bytes_to_end, temp_buffer, wr_ptr_offset);
  } else {
    memcpy(buffer, temp_buffer, wr_ptr_offset);
    memset(buffer + wr_ptr_offset, 0, bytes_to_end);
  }

  kfree(temp_buffer);

  return calc_size;
}

int iwl_dnt_dev_if_configure_monitor(struct iwl_dnt* dnt, struct iwl_trans* trans) {
  uint32_t base_addr, end_addr;

  switch (dnt->cur_mon_type) {
    case NO_MONITOR:
      IWL_INFO(trans, "Monitor is disabled\n");
      dnt->iwl_dnt_status &= ~IWL_DNT_STATUS_MON_CONFIGURED;
      break;
    case MARBH_ADC:
    case MARBH_DBG:
      iwl_dnt_dev_if_configure_marbh(trans);
      dnt->mon_buf_size = DNT_MARBH_BUF_SIZE;
      break;
    case DMA:
      if (!dnt->mon_buf_cpu_addr) {
        IWL_ERR(trans, "Can't configure DMA monitor: no cpu addr\n");
        return -ENOMEM;
      }
      base_addr = dnt->mon_base_addr >> 4;
      end_addr = dnt->mon_end_addr >> 4;
      iwl_dnt_dev_if_configure_dbgm_registers(trans, base_addr, end_addr);
      break;
    case MIPI:
      iwl_dnt_dev_if_configure_mipi(trans);
      break;
    case SMEM:
      base_addr = 0;
      end_addr = 0;
      iwl_dnt_dev_if_configure_dbgm_registers(trans, base_addr, end_addr);
      dnt->mon_buf_size = DNT_SMEM_BUF_SIZE;
      break;
    case INTERFACE:
      base_addr = 0;
      end_addr = 0x400;
      iwl_dnt_dev_if_configure_dbgm_registers(trans, base_addr, end_addr);
      break;
    default:
      dnt->iwl_dnt_status &= ~IWL_DNT_STATUS_MON_CONFIGURED;
      IWL_INFO(trans, "Invalid monitor type\n");
      return -EINVAL;
  }

  dnt->iwl_dnt_status |= IWL_DNT_STATUS_MON_CONFIGURED;

  return 0;
}

static int iwl_dnt_dev_if_send_dbgm(struct iwl_dnt* dnt, struct iwl_trans* trans) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  struct iwl_host_cmd host_cmd = {
      .id = cfg->dbg_conf_monitor_cmd_id,
      .data[0] = cfg->dbg_conf_monitor_host_command.data,
      .len[0] = cfg->dbg_conf_monitor_host_command.len,
      .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  };
  int ret;

  ret = iwl_trans_send_cmd(trans, &host_cmd);
  if (ret) {
    IWL_ERR(trans, "Failed to send monitor command\n");
    dnt->iwl_dnt_status |= IWL_DNT_STATUS_FAILED_START_MONITOR;
  }

  return ret;
}

static int iwl_dnt_dev_if_send_ldbg(struct iwl_dnt* dnt, struct iwl_trans* trans, int cmd_index) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  struct iwl_host_cmd host_cmd = {
      .id = cfg->dbg_conf_monitor_cmd_id,
      .data[0] = cfg->ldbg_cmd[cmd_index].data,
      .len[0] = DNT_LDBG_CMD_SIZE,
      .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  };

  return iwl_trans_send_cmd(trans, &host_cmd);
}

int iwl_dnt_dev_if_start_monitor(struct iwl_dnt* dnt, struct iwl_trans* trans) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  int i, ret;

  switch (cfg->dbgm_enable_mode) {
    case DEBUG:
      return iwl_dnt_dev_if_send_dbgm(dnt, trans);
    case SNIFFER:
      ret = 0;
      for (i = 0; i < cfg->ldbg_cmd_nums; i++) {
        ret = iwl_dnt_dev_if_send_ldbg(dnt, trans, i);
        if (ret) {
          IWL_ERR(trans, "Failed to send ldbg command\n");
          break;
        }
      }
      return ret;
    default:
      WARN_ONCE(1, "invalid option: %d\n", cfg->dbgm_enable_mode);
      return -EINVAL;
  }
}

int iwl_dnt_dev_if_set_log_level(struct iwl_dnt* dnt, struct iwl_trans* trans) {
  struct iwl_dbg_cfg* cfg = &trans->dbg_cfg;
  struct iwl_host_cmd host_cmd = {
      .id = cfg->log_level_cmd_id,
      .data[0] = cfg->log_level_cmd.data,
      .len[0] = cfg->log_level_cmd.len,
      .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  };
  int ret;

  ret = iwl_trans_send_cmd(trans, &host_cmd);
  if (ret) {
    IWL_ERR(trans, "Failed to send log level cmd\n");
  }

  return ret;
}

int iwl_dnt_dev_if_retrieve_monitor_data(struct iwl_dnt* dnt, struct iwl_trans* trans,
                                         uint8_t* buffer, uint32_t buffer_size) {
  switch (dnt->cur_mon_type) {
    case DMA:
      return iwl_dnt_dev_if_retrieve_dma_monitor_data(dnt, trans, buffer, buffer_size);
    case MARBH_ADC:
    case MARBH_DBG:
      return iwl_dnt_dev_if_retrieve_marbh_monitor_data(dnt, trans, buffer, buffer_size);
    case SMEM:
      return iwl_dnt_dev_if_retrieve_smem_monitor_data(dnt, trans, buffer, buffer_size);
    case INTERFACE:
    default:
      WARN_ONCE(1, "invalid option: %d\n", dnt->cur_mon_type);
      return -EINVAL;
  }
}

int iwl_dnt_dev_if_read_sram(struct iwl_dnt* dnt, struct iwl_trans* trans) {
  struct dnt_crash_data* crash = &dnt->dispatch.crash;
  int ofs, len = 0;

  ofs = dnt->image->sec[IWL_UCODE_SECTION_DATA].offset;
  len = dnt->image->sec[IWL_UCODE_SECTION_DATA].len;

  crash->sram = vmalloc(len);
  if (!crash->sram) {
    return -ENOMEM;
  }

  crash->sram_buf_size = len;
  return iwl_trans_read_mem(trans, ofs, crash->sram, len / sizeof(uint32_t));
}
IWL_EXPORT_SYMBOL(iwl_dnt_dev_if_read_sram);

int iwl_dnt_dev_if_read_rx(struct iwl_dnt* dnt, struct iwl_trans* trans) {
  struct dnt_crash_data* crash = &dnt->dispatch.crash;
  int i, reg_val;
  uint32_t buf32_size, offset = 0;
  uint32_t* buf32;
  unsigned long flags;

  /* reading buffer size */
  reg_val = iwl_trans_read_prph(trans, RXF_SIZE_ADDR);
  crash->rx_buf_size = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;

  /* the register holds the value divided by 128 */
  crash->rx_buf_size = crash->rx_buf_size << 7;

  if (!crash->rx_buf_size) {
    return -ENOMEM;
  }

  buf32_size = crash->rx_buf_size / sizeof(uint32_t);

  crash->rx = vmalloc(crash->rx_buf_size);
  if (!crash->rx) {
    return -ENOMEM;
  }

  buf32 = (uint32_t*)crash->rx;

  if (!iwl_trans_grab_nic_access(trans, &flags)) {
    vfree(crash->rx);
    return -EBUSY;
  }
  for (i = 0; i < buf32_size; i++) {
    iwl_trans_write_prph(trans, RXF_LD_FENCE_OFFSET_ADDR, offset);
    offset += sizeof(uint32_t);
    buf32[i] = iwl_trans_read_prph(trans, RXF_FIFO_RD_FENCE_ADDR);
  }
  iwl_trans_release_nic_access(trans, &flags);

  return 0;
}
IWL_EXPORT_SYMBOL(iwl_dnt_dev_if_read_rx);
