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

📄 dec21140.c

📁 基于psos操作系统的dec21140驱动
💻 C
📖 第 1 页 / 共 5 页
字号:

    /*-----------------------------------------------------------------*/
    /* Set tx_hdr to the transmit header associated with the frame,    */
    /* and return the message block triplet.                           */
    /*-----------------------------------------------------------------*/
    tx_hdr = TxUsedBD->buffAddr1;
    if (tx_hdr->NoRetFlag == 0)
      NiFuncs.freemsg(tx_hdr->msg_ptr);

    /*-----------------------------------------------------------------*/
    /* Advance TxUsedBD to next descriptor following this frame.       */
    /*-----------------------------------------------------------------*/
    for (i = 0; i < tx_hdr->num_desc; ++i)
    {
      TxUsedBD->buffAddr1 = NULL;
      TxUsedBD->status = NULL;
      TxUsedBD->ctrlNsize = LAN_XMTD_TCH;
      COPYBACK((void *)TxUsedBD, 1);
      TxUsedBD = TxUsedBD->nextDesc;
      ++TxFreeDesc;
    }

    /*-----------------------------------------------------------------*/
    /* Finally, return the transmit header to the free list.           */
    /*-----------------------------------------------------------------*/
    tx_hdr->next = TxHdrFreeHead;
    TxHdrFreeHead  = tx_hdr;

    /*-----------------------------------------------------------------*/
    /* Here's a window for interrupts                                  */
    /*-----------------------------------------------------------------*/
    intRESTORE_IEN(ien);
    ien = intCLEAR_IEN();
  }

  intRESTORE_IEN(ien);
}

/***********************************************************************/
/* TxFillDesc: Move from outgoing queue to transmit descriptor ring    */
/*                                                                     */
/* OUTPUTS: TxUsedBD is updated                                        */
/*                                                                     */
/***********************************************************************/
static void TxFillDesc(void)
{
  LAN_BUFF_DESC *first_desc;
  LAN_TX_HDR    *tx_hdr;
  mblk_t        *msgBlk;
  ULONG         length, frameLen;
  Bool ien;

  if (FlushFlag) return;

  /*-------------------------------------------------------------------*/
  /* Free up some descriptors if possible.                             */
  /*-------------------------------------------------------------------*/
  TxBufDetach();

  for (;;)
  {
    /*-----------------------------------------------------------------*/
    /*-----------------------------------------------------------------*/
    ien = intCLEAR_IEN();

    /*-----------------------------------------------------------------*/
    /* If no messages queued or not enough descriptors available for   */
    /* the first queued frame, we can't do anything.                   */
    /*-----------------------------------------------------------------*/
    if ((TxHdrOutHead == NULL) || (TxFreeDesc < TxHdrOutHead->num_desc))
      break;

    /*-----------------------------------------------------------------*/
    /* Extract first message.                                          */
    /*-----------------------------------------------------------------*/
    tx_hdr = TxHdrOutHead;
    TxHdrOutHead = TxHdrOutHead->next;

    /*-----------------------------------------------------------------*/
    /* Fill first transmit descriptor.  We save a pointer to this      */
    /* buffer descriptor and we don't give ownership to the MAC for    */
    /* this first descriptor until after all the other descriptors for */
    /* this frame are set up.                                          */
    /*-----------------------------------------------------------------*/
    first_desc = TxNewBD;
    TxBufAttach((void *)tx_hdr, 14, LAN_XMTD_FS, 0);
    frameLen = 14;

    /*-----------------------------------------------------------------*/
    /* Now add buffers pointed to by message block triplet.            */
    /*-----------------------------------------------------------------*/
    msgBlk = tx_hdr->msg_ptr;
    while (msgBlk)
    {
      length    = msgBlk->b_wptr - msgBlk->b_rptr;
      frameLen += length;

      /*---------------------------------------------------------------*/
      /* Interrupt bit is set only for last descriptor in frame.       */
      /*---------------------------------------------------------------*/
      if (msgBlk->b_cont)
      {
        TxBufAttach(msgBlk->b_rptr, length, 0, MAC_OWNS_DESC);
      }
      else
      {
        if (frameLen < 64)
          length += (64 - frameLen);

        TxBufAttach(msgBlk->b_rptr, length, LAN_XMTD_IC | LAN_XMTD_LS,
                    MAC_OWNS_DESC);
      }

      msgBlk = msgBlk->b_cont;
    }

    /*-----------------------------------------------------------------*/
    /* Give descriptor to MAC and request transmission.                */
    /*-----------------------------------------------------------------*/
    first_desc->status = MAC_OWNS_DESC;
    COPYBACK((void *)first_desc, 1);
    ioLongWrite(CSR1, 1);

    /*-----------------------------------------------------------------*/
    /*-----------------------------------------------------------------*/
    intRESTORE_IEN(ien);
  }

  intRESTORE_IEN(ien);
}

/***********************************************************************/
/*       bzero: Zero memory at specified address                       */
/*                                                                     */
/***********************************************************************/
static void bzero(UCHAR *ptr, int length)
{
  while (length--)
    *ptr++ = 0;
}

static struct ether_addr
{
  ULONG word_1;     /* first 2 bytes of address in least sig 16-bits */
  ULONG word_2;     /* next 2 bytes of address in least sig 16-bits */
  ULONG word_3;     /* last 2 bytes of ethernet in least sig 16-bits */
} EtherBlock[16];
static struct eth_other
{
  UCHAR count;      /* open count */
  UCHAR next;       /* index of next free address slot */
} EtherOther[16];
static ULONG EtherAddrNum;
static ULONG EtherAddrEmpty;

/***********************************************************************/
static void lan_addr_clear(void)
{
  int i;

  for (i = 0; i < 16; ++i)
  {
    EtherBlock[i].word_1 = 0xFFFF;
    EtherBlock[i].word_2 = 0xFFFF;
    EtherBlock[i].word_3 = 0xFFFF;
    EtherOther[i].count = 0;
    EtherOther[i].next = i + 1;
  }
  EtherOther[15].next = 0;  /* points to nothing else */
  EtherOther[0].count = 1;  /* this one is also considered used */

  EtherAddrNum = 1;
  EtherAddrEmpty = 1;
}

/***********************************************************************/
static ULONG lan_add_mcast(UCHAR *addr)
{
  ULONG i;
  USHORT addr1, addr2, addr3;
  Bool ien;

  addr1 = (addr[1] << 8) | addr[0];
  addr2 = (addr[3] << 8) | addr[2];
  addr3 = (addr[5] << 8) | addr[4];

  ien = intCLEAR_IEN();

  /* If the address is already in the list, merely increment its counter */

  for (i = 1; i < 16; ++i)      /* Skip the broadcast address in slot 0 */
  {
    if ((addr3 == EtherBlock[i].word_3) &&
        (addr2 == EtherBlock[i].word_2) &&
        (addr1 == EtherBlock[i].word_1))
    {
      /* The address is in the list */
      EtherOther[i].count++;
      intRESTORE_IEN(ien);
      return 0;
    }
  }

  if (EtherAddrEmpty)
  {
    EtherAddrEmpty = EtherOther[EtherAddrEmpty].next;
    EtherBlock[EtherAddrEmpty].word_1 = addr1;
    EtherBlock[EtherAddrEmpty].word_2 = addr2;
    EtherBlock[EtherAddrEmpty].word_3 = addr3;
    EtherOther[EtherAddrEmpty].count = 1;
    ++EtherAddrNum;
    intRESTORE_IEN(ien);
    lan_addr_write();
    return 0;
  }

  intRESTORE_IEN(ien);
  return ENFILE;
}

/***********************************************************************/
static ULONG lan_del_mcast(UCHAR *addr)
{
  ULONG i;
  USHORT addr1, addr2, addr3;
  Bool ien;

  addr1 = (addr[1] << 8) | addr[0];
  addr2 = (addr[3] << 8) | addr[2];
  addr3 = (addr[5] << 8) | addr[4];

  ien = intCLEAR_IEN();

  /* Find the address in the list */

  for (i = 1; i < 16; ++i)      /* Skip the broadcast address in slot 0 */
  {
    if ((addr3 == EtherBlock[i].word_3) &&
        (addr2 == EtherBlock[i].word_2) &&
        (addr1 == EtherBlock[i].word_1))
    {
      /* The address is in the list.  Write the broadcast pattern */
      /* Into the address slot to tag it 'empty' */

      if (--EtherOther[i].count == 0)
      {
        EtherBlock[i].word_1 = 0xFFFF;
        EtherBlock[i].word_2 = 0xFFFF;
        EtherBlock[i].word_3 = 0xFFFF;
        EtherOther[i].next = EtherAddrEmpty;
        EtherAddrEmpty = i;
        --EtherAddrNum;
        intRESTORE_IEN(ien);
        lan_addr_write();
      }
      else
        intRESTORE_IEN(ien);
      return 0;
    }
  }
  intRESTORE_IEN(ien);
  return ENXIO;
}

/***********************************************************************/
/* enable_tm_sdram_access:                                             */
/*                                                                     */
/***********************************************************************/
static void enable_tm_sdram_access(void)
{
  unsigned cfg_data;

  cfg_data = pci_read_config_dword(0, 9, 0, 4);
  pci_write_config_dword(0, 9, 0, 4, cfg_data | 2);
  cfg_data = pci_read_config_dword(0, 9, 0, 4);
}

/***********************************************************************/
/* lan_addr_write: "Send" the setup packet to the chip                 */
/*                                                                     */
/***********************************************************************/
static void lan_addr_write(void)
{
  int command;
  volatile ULONG i;
  ULONG saved_csr6, saved_csr7;

  /*-------------------------------------------------------------------*/
  /* Stops TxFillDesc() from filling any more descriptors              */

⌨️ 快捷键说明

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