⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_cf.c

📁 marvell cf wifi driver source code CF-8385-linux-x86-5.0.4.p0-132-src.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (bits & HIS_CardEvent)
    tmp |= CF_CCR_CS_CardEvent;
  if (bits & HIS_CmdUpLdRdy)
    tmp |= CF_CCR_CS_CmdRspRdy;

  sbi_enable_host_int(priv, tmp);
  return 0;
}

int sbi_disable_host_int(wlan_private * priv, u8 int_mask)
{
  cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
  u16 mask = (u16) int_mask;

  ENTER();

  if (!mask)
    mask = CF_HCR_HIM_MASK;

  mask &= CF_HCR_HIM_MASK;  // check if this is rqrd?
  cardp.host_int_mask |= mask;
  PRINTK("host in mask in init = 0x%X\n", cardp.host_int_mask);

  outw(cardp.host_int_mask, reg->host.int_mask);

  // For debugging.

  mask = inw(reg->host.int_mask);

  LEAVE();
  return 0;
}

int sbi_enable_host_int(wlan_private * priv, u8 int_mask)
{
  cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
  u16 mask = int_mask;

  ENTER();

  if (!mask) 
    mask = CF_HCR_HIM_MASK;

  mask &= CF_HCR_HIM_MASK;

  PRINTK("mask bit = 0x%X\n", mask);
  PRINTK("before masking host_int_mask = 0x%X\n", cardp.host_int_mask);

  cardp.host_int_mask &= ~mask;

  PRINTK("host_int_mask=0x%x\n", cardp.host_int_mask);
  outw(cardp.host_int_mask, reg->host.int_mask);

  LEAVE();
  return 0;
}

int sbi_unregister_dev(wlan_private * priv)
{
  ENTER();
  kfree((void *)priv->wlan_dev.ioport);
  free_irq(priv->wlan_dev.netdev->irq, priv->wlan_dev.netdev);
  LEAVE();
  return 0;
}

int sbi_register_dev(wlan_private * priv)
{
  int ret;

  ENTER();

  strncpy(priv->wlan_dev.name, cfio_dev_info, sizeof(priv->wlan_dev.name));

  priv->wlan_dev.ioport   = (u32)kmalloc(sizeof(cfreg), GFP_KERNEL);
  priv->wlan_dev.upld_rcv = 0;
  priv->wlan_dev.upld_typ = 0;
  priv->wlan_dev.upld_len = 0;

  cardp.eth_dev = priv->wlan_dev.netdev;

  printk(KERN_DEBUG "IRQ %d\n", cardp.irq);

  ret = 
    request_irq(
      cardp.irq, 
      cf_interrupt, 
      SA_SHIRQ, 
      "cf_irq", 
      priv->wlan_dev.netdev
      );
           
  if (ret != 0)
  {
    PRINTK("Call to request_irq failed\n");
    priv->wlan_dev.card = NULL;
    LEAVE();
    return ret;
  }

  priv->wlan_dev.card               = (void *)&cardp;
  priv->wlan_dev.netdev->irq        = cardp.irq;
  priv->wlan_dev.netdev->base_addr  = cardp.port;
  priv->adapter->irq                = cardp.irq;

  init_cf_addr(priv);
  LEAVE();
  return 0;   /* success */
}

int sbi_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 len)
{
  int ret = -1;

  ENTER();

  if (type == MVMS_DAT) 
  {
    priv->wlan_dev.dnld_sent = DNLD_DATA_SENT;
    ret = cf_tx_block(priv, buf, (u16)len);
  } 
  else if (type == MVMS_CMD) 
  {
    ret = cf_send_cmd(priv, (u16 *)buf, len);
  } 
  else
  {
    ret = WLAN_STATUS_FAILURE;
  }

  LEAVE();
  return ret;
}

int sbi_get_cis_info(wlan_private *priv)
{
  wlan_adapter *Adapter = priv->adapter;
  client_handle_t handle = cisinfo.handle;
  tuple_t tuple;
  char buf[64], cisbuf[512];
  int ofs=0, count=6;

  ENTER();
  
  memset(cisbuf, 0x0, sizeof(cisbuf));

  tuple.Attributes = 0;
  tuple.TupleData = buf;
  tuple.TupleDataMax = sizeof(buf);
  tuple.TupleOffset = 0;

  CIS(CISTPL_CONFIG);
  CIS(CISTPL_CFTABLE_ENTRY);
  CIS(CISTPL_MANFID);
  CIS(CISTPL_FUNCID);
  CIS(CISTPL_FUNCE);

  do 
  {
    if (CardServices(GetNextTuple, handle, &tuple))
      goto error;
    if (CardServices(GetTupleData, handle, &tuple))
      goto error;
  
    cisbuf[ofs++] = tuple.TupleCode;
    cisbuf[ofs++] = tuple.TupleLink;
    memcpy(cisbuf+ofs, tuple.TupleData, tuple.TupleLink);
    ofs += tuple.TupleLink;
  } while (count--);
  
  CIS(CISTPL_VERS_1);
  CIS(CISTPL_DEVICE_A);
  CIS(CISTPL_DEVICE);

  memset(Adapter->CisInfoBuf, 0x0, sizeof(Adapter->CisInfoBuf));
  memcpy(Adapter->CisInfoBuf, cisbuf, ofs);
  Adapter->CisInfoLen = ofs;

error:

  PRINTK("card configuration failed...\n");

  LEAVE();
  return 0;
}

int sbi_probe_card(void *card_p)
{
  ENTER();

  /*
   * Here we simply return zero since we are already done with this
   * operation in the cf_config() function
   */

  LEAVE();
  return 0;
}

int sbi_verify_fw_download(wlan_private * priv)
{
  cfreg *reg = (cfreg *)priv->wlan_dev.ioport;

  u8 rev = inb(reg->card.product_id);
  priv->adapter->chip_rev = rev;

  PRINTK("chip rev is: %02x\n", rev);

  cardp.do_read_modify_write      = 0;
  cardp.do_get_int_work_around    = 0;

#if defined (CF8305)
  cardp.do_read_modify_write      = 1;
  cardp.do_get_int_work_around    = 1;
#elif defined (CF8381)
  if (rev < 0x04)
  {
    PRINTK("sbi_register_dev: cf8381 older than rev. B3.\n");
    PRINTK("sbi_register_dev: do r-m-w and intr w-around.\n");
    cardp.do_read_modify_write    = 1;
    cardp.do_get_int_work_around  = 1;
  }
#elif defined (CF8385)
  if (rev < 0x12)
  {
    PRINTK("sbi_register_dev: cf8385 older than rev. B1.\n");
    PRINTK("sbi_register_dev: do r-m-w and intr w-around.\n");
    cardp.do_read_modify_write    = 1;
    cardp.do_get_int_work_around  = 0;
  }
#endif

  return 0;
}

int sbi_prog_firmware(wlan_private * priv)
{
  cfreg *reg = (cfreg *)priv->wlan_dev.ioport;

  u32 size_total;
  u32 size_sent;
  u32 size_block;
  u8  buf[256];
  u8  temp;
  int r;

  temp = inb(reg->card.scratch);

  if (temp == CF_SCRATCH_FIRMWARE_READY)
    return 0;
 
  if (temp != CF_SCRATCH_HOST_BOOT_WAITING)
    return -1;

  size_total  = sizeof(init_image);
  size_sent   = 0;
  size_block  = FW_BLOCK_SIZE;

  while (size_sent < size_total) 
  {
    PRINTK("  loading %06d of %06d bytes\n", size_sent, size_total);

    if (size_total - size_sent < size_block)
      size_block = (size_total - size_sent);

    memcpy(buf, &init_image[size_sent], size_block);

    outw(FW_BLOCK_SIZE, reg->host.io_cmd_write_len);
    outsw(reg->host.io_cmd_write, buf, FW_BLOCK_SIZE / 2);

    outb(CF_HCR_HS_CmdDnLdOvr, reg->host.status);
    wmb();
    outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause);

    r = 
      poll_reg(
        reg->card.status, 
        CF_CCR_CS_CmdDnLdRdy, 
        FW_RETRY, 
        10
        );

    if (r != 0)
      return -1;

    size_sent += size_block;
  }

  outw(0x00,                  reg->host.io_cmd_write_len);
  outb(CF_HCR_HS_CmdDnLdOvr,  reg->host.status);
  wmb();
  outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause);
  return 0;
}

#ifdef HELPER_IMAGE
int sbi_prog_helper(wlan_private * priv)
{
  return sbi_prog_firmware(priv);
}
#endif

#ifdef HELPER_IMAGE
int sbi_download_wlan_fw(wlan_private * priv)
{
  cfreg *reg = (cfreg *)priv->wlan_dev.ioport;

  u16 len;
  int i;
  int r;
  int retry;

  r = poll_reg(reg->card.sq_raddr0, 0x0010, HP_RETRY, 1000);

  if (r < 0)
    return -1;

  retry = 0;

  for (i = 0; i < sizeof(fmimage); i += len)
  {
    len = inw(reg->card.sq_raddr0);

    retry = (len & 0x0001) ? retry + 1: 0;

    if (retry > 20)
      return -1;

    if (retry > 0) 
      i -= len;

    PRINTK("  loading %06d of %06d bytes\n", i, sizeof(fmimage));

    outw(len + 1, reg->host.io_cmd_write_len);
    outsw(reg->host.io_cmd_write, &fmimage[i], len / 2);
    outb(CF_HCR_HS_CmdDnLdOvr,  reg->host.status);
    outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause);

    r = 
      poll_reg(
        reg->card.status, 
        CF_CCR_CS_CmdDnLdRdy, 
        FW_RETRY, 
        0
        );

    if (r < 0) 
    {
      PRINTK("  failed  %06d bytes\n", i);
      return -1;
    }
  }

  r = poll_reg(reg->card.scratch, CF_SCRATCH_FIRMWARE_READY, FW_RETRY, 50);

  if (r < 0) 
  {
    PRINTK("  firmware failed!\n");
    return -1;
  }

  PRINTK("  firmware started!\n");
  return 0;
}
#endif // HELPER_IMAGE

#ifdef DEEP_SLEEP
inline int sbi_enter_deep_sleep(wlan_private * priv)
{
  ENTER();
  
  LEAVE();
  return 0;
}

inline int sbi_exit_deep_sleep(wlan_private* priv)
{
  cfreg *reg = (cfreg *)priv->wlan_dev.ioport;

  outb(CF_SCRATCH_DEEPSLEEP_EXIT, reg->card.scratch);
  cfio_read_cfg_reg(priv);

  return 0;
}

inline int sbi_reset_deepsleep_wakeup(wlan_private * priv)
{
  ENTER();
  
  LEAVE();
  return 0;
}
#endif  // DEEP_SLEEP

int sbi_read_ioreg(wlan_private *priv, u8 func, u32 reg, u8 *dat)
{
  /* TODO Remove this after correcting errors in WLAN layer
   * This function is dummy for CF this is defined only
   * to resolve undefined symbol errors while loading the
   * module
   */
  return 1;
}

int sbi_write_ioreg(wlan_private * priv, u8 func, u32 reg, u8 dat)
{
  /* TODO Remove this after correcting errors in WLAN layer
   * This function is dummy for CF this is defined only
   * to resolve undefined symbol errors while loading the
   * module
   */
  return 1;
}

int sbi_read_cfreg(wlan_private * priv, int offset)
{
  u16 usval;

  ENTER();

  usval = inw(priv->wlan_dev.netdev->base_addr + offset);

  LEAVE();
  return usval;
}

int sbi_write_cfreg(wlan_private * priv, int offset, u16 value)
{
  ENTER();

  outw(value, priv->wlan_dev.netdev->base_addr + offset);

  LEAVE();
  return 0;
}

void sbi_trigger_rx(wlan_private * priv)
{
  ENTER();

  if (priv->adapter->CurrentTxSkb) 
    priv->adapter->HisRegCpy |= HIS_TxDnLdRdy;
  else 
    cf_KickstartRX(priv);

  LEAVE();
}

#ifdef CONFIG_MARVELL_PM

int sbi_suspend(wlan_private * priv)
{
  ENTER();
  
  LEAVE();
  return 0;
}

int sbi_resume(wlan_private * priv)
{
  ENTER();
  
  LEAVE();
  return 0;
}

#endif

/* End of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -