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

📄 ns8390x.c

📁 基于psos操作系统的ns8390驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
register long dev_num;

/*---------------------------------------------------------------------*/
/* Set up the device number from the packet structure                  */
/*---------------------------------------------------------------------*/
dev_num = rcvHdrPtr->dev_num;

/*---------------------------------------------------------------------*/
/* Determine the # of bytes from this buff to the end of the ring      */
/*---------------------------------------------------------------------*/
numBytes = ((LAN_RXSTOP - rcvHdrPtr->pageNum) * sizeof(STNIC_RING_BUFF));

/*---------------------------------------------------------------------*/
/* If the # of bytes >= length the data is in contiguous addresses     */
/*---------------------------------------------------------------------*/
if (numBytes >= (rcvHdrPtr->dataLen + sizeof(RCV_BUFF_STAT)))
   {
   remDmaSetup(dev_num, ((rcvHdrPtr->pageNum) << 8) + sizeof(RCV_BUFF_STAT),
                               (ULONG)rcvHdrPtr->dataLen, REMOTE_READ);
   remDmaDo(dev_num, ((UCHAR *) &(rcvHdrPtr->daddr)),
                               (ULONG)rcvHdrPtr->dataLen, REMOTE_READ);
   }
else
   {
   numBytes -= sizeof(RCV_BUFF_STAT);

   remDmaSetup(dev_num, ((rcvHdrPtr->pageNum) << 8) + sizeof(RCV_BUFF_STAT),
                                              numBytes, REMOTE_READ);
   remDmaDo(dev_num, ((UCHAR *) &(rcvHdrPtr->daddr)),  numBytes, REMOTE_READ);

   remDmaSetup(dev_num, (LAN_RXSTART << 8) + 0,
                          rcvHdrPtr->dataLen - numBytes, REMOTE_READ);
   remDmaDo(dev_num, (UCHAR *) (((ULONG) &(rcvHdrPtr->daddr)) + numBytes),
                          rcvHdrPtr->dataLen - numBytes, REMOTE_READ);
   }
}

/***********************************************************************/
/* remDmaSetup: Set up The remote DMA channel for Reading or Writing   */
/*              the specified number of bytes remote DMA channel       */
/*                                                                     */
/* INPUTS:  long dev_num   = Device number                             */
/*          ULONG  PageNum = Ring buffer page # + offset in page       */
/*          ULONG  len     = Number of bytes to read/write             */
/*          ULONG  Op      = Remote READ or Remote WRITE               */
/* OUTPUTS: None                                                       */
/*                                                                     */
/***********************************************************************/
STATIC void remDmaSetup(long dev_num, ULONG Pg, ULONG len, ULONG Op)
{
if (len & 0x1)
    len++;

/*---------------------------------------------------------------------*/
/* For remote writes setup Xfr as read first. !?! - The manual says so */
/*---------------------------------------------------------------------*/
wrStNicCR(dev_num, LAN_PG0_CR_RD2+LAN_PAGE0+LAN_PG0_CR_STA);

/*---------------------------------------------------------------------*/
/* Set up the remote DMA channel - Byte count & Page address           */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_RBCR0, (UCHAR)(len & 0xFF), LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_RBCR1, (UCHAR)((len >> 8) & 0xFF), LAN_PAGE0);

wrStNicReg(dev_num, LAN_PG0_RSAR0, (UCHAR)(Pg  & 0xFF), LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_RSAR1, (UCHAR)((Pg >> 8) & 0xFF), LAN_PAGE0);

/*---------------------------------------------------------------------*/
/* Set up requested transfer type                                      */
/*---------------------------------------------------------------------*/
if (Op == REMOTE_READ)
   wrStNicCR(dev_num, LAN_PG0_CR_RD0|LAN_PG0_CR_STA);
else
   wrStNicCR(dev_num, LAN_PG0_CR_RD1);
}

/***********************************************************************/
/* remDmaDo: Perform the transfer of the specified number of bytes     */
/*                                                                     */
/* INPUTS:  long dev_num   = Device number                             */
/*          UCHAR *bufPtr = Address of transfer buffer                 */
/*          ULONG  len    = Number of bytes to read/write              */
/*          ULONG  Op     = Remote READ or Remote WRITE                */
/* OUTPUTS: None                                                       */
/*                                                                     */
/* NOTES: Optimized in assembly in asm.s                               */
/*                                                                     */
/***********************************************************************/
STATIC void remDmaDo(long dev_num, UCHAR *bufPtr, ULONG len, ULONG Op)
{
USHORT svar, *bptr = (USHORT *)bufPtr;
int count;

count = len >> 1;

if (Op == REMOTE_READ)
   {
   while (count-- != 0)
         {
         *bptr = inw(portPtr[dev_num]);
         bptr++;
         }
   if (len & 0x1)
      {
      svar = inw(portPtr[dev_num]);
      *((char *) bptr) = (char) svar;
      }
   }
else
   {
   /* REMOTE_WRITE always called with even length (len) */
   while (count-- != 0)
         {
         outw(portPtr[dev_num], *bptr);
         bptr++;
         }
   }
}

/***********************************************************************/
/* TxCpyData: Copy data to Transmit buffers from a transmit header     */
/*                                                                     */
/* INPUTS:  curtxPtr: Current transmit header                          */
/*          pageNum:  Trasmit page number                              */
/* OUTPUTS: None                                                       */
/*                                                                     */
/***********************************************************************/
STATIC void TxCpyData(LAN_TX_HDR *curtxPtr, ULONG pageNum)
{
mblk_t *msgBlk;
ULONG  i, length, frameLen, write_flag=0;
long dev_num;
unsigned short prev_word=0;

/*---------------------------------------------------------------------*/
/* Set up the device number from the packet structure                  */
/*---------------------------------------------------------------------*/
dev_num = curtxPtr->dev_num;

/*---------------------------------------------------------------------*/
/* Update min transmit count if required                               */
/*---------------------------------------------------------------------*/
if (curtxPtr->numBytes < 64)
   curtxPtr->numBytes = 64;

/*---------------------------------------------------------------------*/
/* Copy transmit header info into remote buffer area                   */
/*---------------------------------------------------------------------*/
remDmaSetup(dev_num, (pageNum << 8) + 0, curtxPtr->numBytes, REMOTE_WRITE);

remDmaDo(dev_num, (UCHAR *) &(curtxPtr->daddr), 0x06, REMOTE_WRITE);
remDmaDo(dev_num, (UCHAR *) &(curtxPtr->saddr), 0x06, REMOTE_WRITE);
remDmaDo(dev_num, (UCHAR *) &(curtxPtr->type),  0x02, REMOTE_WRITE);

/*---------------------------------------------------------------------*/
/* Now copy the buffers pointed to by the message block triplet in.    */
/*---------------------------------------------------------------------*/
frameLen = 14;
msgBlk   = curtxPtr->msg_ptr;

while (msgBlk)
      {
      length    = msgBlk->b_wptr - msgBlk->b_rptr;

      /*---------------------------------------------------------------*/
      /* Combine last byte of previous mblk with first byte of current */
      /* Note length > 0, since zero blocks are freed initially        */
      /*---------------------------------------------------------------*/
      if (write_flag)
	 {
	 prev_word = prev_word | ((USHORT)(msgBlk->b_rptr[0]) << 8);
         frameLen += 2;
	 remDmaDo(dev_num, (UCHAR *) &prev_word, 2, REMOTE_WRITE);
         length--;
	 msgBlk->b_rptr++;
	 write_flag = 0;
	 }

      /*---------------------------------------------------------------*/
      /* Copy the last byte. Send it out in next DmaDo                 */
      /*---------------------------------------------------------------*/
      if (length & 0x1)
	 {
	 write_flag = 1;
	 prev_word = msgBlk->b_wptr[-1];
	 length--;
	 }

      frameLen += length;

      /*---------------------------------------------------------------*/
      /* Copy the message block data                                   */
      /*---------------------------------------------------------------*/
      remDmaDo(dev_num, (UCHAR *) msgBlk->b_rptr, length, REMOTE_WRITE);
          
      msgBlk = msgBlk->b_cont;
      }

/*---------------------------------------------------------------------*/
/* Last byte left in the last mblk. Pad it to 2 bytes and send it out  */
/*---------------------------------------------------------------------*/
if (write_flag)
   {
   prev_word = prev_word | 0;
   frameLen += 2;
   remDmaDo(dev_num, (UCHAR *) &prev_word, 2, REMOTE_WRITE);
   }

/*---------------------------------------------------------------------*/
/* If the frame length is less than 64 pad till 64                     */
/*---------------------------------------------------------------------*/
if (frameLen < 64)
   {
   length = 64 - frameLen;

   /* Note length is always even, since frameLen is even */
   for (i = 0; i < (length >> 1); i++)
       {
       outw(portPtr[dev_num], 0x0000);
       }
   }
}

/***********************************************************************/
/* TxFillBuffs_isr: Called from isr on trasmit completion              */
/*              Move outgoing packets from the outgoing queue to the   */
/*              transmit buffers ring, if possible.                    */
/*                                                                     */
/* INPUTS:  long dev_num                                               */
/* OUTPUTS: None                                                       */
/*                                                                     */
/***********************************************************************/
STATIC void TxFillBuffs_isr(long dev_num)
{
if (TxCurrHdrPtr[dev_num][0] == (struct TxHdr *) -1)
   {
   if (TxAbortpageNum[dev_num] == LAN_TXSTART)
      {
      TxAbortpageNum[dev_num] = -1;
      ns8390_trigger_send(dev_num, LAN_TXSTART,
                          (ULONG)TxAbortnumBytes[dev_num]);
      }
   else
      TxCurrHdrPtr[dev_num][0] = NULL;
   }
if (TxCurrHdrPtr[dev_num][1] == (struct TxHdr *) -1)
   {
   if (TxAbortpageNum[dev_num] == (LAN_TXSTART + 6))
      {
      TxAbortpageNum[dev_num] = -1;
      ns8390_trigger_send(dev_num, LAN_TXSTART + 6, 
                          (ULONG)TxAbortnumBytes[dev_num]);
      }
   else
      TxCurrHdrPtr[dev_num][1] = NULL;
   }

TxFillBuffs(dev_num);
}

/***********************************************************************/
/* TxFillBuffs: Move outgoing packets from the outgoing queue to the   */
/*              transmit buffers ring, if possible.                    */
/*                                                                     */
/* INPUTS:  long dev_num   = Device number                             */
/* OUTPUTS: TxUsedPtr is updated                                       */
/*                                                                     */
/***********************************************************************/
STATIC void TxFillBuffs(long dev_num)
{
ULONG i, iLevel;
ULONG pageNum;
LAN_TX_HDR **currtxpptr;
ULONG numBytes;

for (;;)
    {
    /*-----------------------------------------------------------------*/
    /* Disable Interrupts for critical processing                      */
    /*----------------------------

⌨️ 快捷键说明

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