📄 ns8390x.c
字号:
/* Mask interrupts */
/*---------------------------------------------------------------------*/
iLevel = splhigh();
dev_num = hdrPtr->dev_num;
/*---------------------------------------------------------------------*/
/* Link returned envelope to the envelope previously at the top of the */
/* free queue and point "free_head" to the newly returned envelope. */
/*---------------------------------------------------------------------*/
hdrPtr->next = RxLstFreeHead[dev_num];
RxLstFreeHead[dev_num] = hdrPtr;
RxLstFreeCount[dev_num]++;
/*---------------------------------------------------------------------*/
/* Unmask interrupts */
/*---------------------------------------------------------------------*/
splx(iLevel);
if (RxLstFreeCount[dev_num] == (RxLowWaterMark[dev_num] + 1))
return (NI_RX_ABOVE_LOW_WATERMARK | (lan_intfs[dev_num].if_num << 16));
else
return (0);
}
/***********************************************************************/
/* RxPktRcv: Accept good packets and set up copying of data. */
/* */
/* INPUTS: long dev_num = Device number */
/* OUTPUTS: None */
/* */
/***********************************************************************/
STATIC void RxPktRcv(long dev_num)
{
LAN_RXPKT_LIST *rcvHdrPtr;
ULONG iLevel;
ULONG rxing_page, next_page, this_page;
ULONG tmp = 0;
for (;;)
{
/*-----------------------------------------------------------------*/
/* Disable Interrupts */
/*-----------------------------------------------------------------*/
iLevel = splhigh();
if (!((tmp = rdStNicReg(dev_num, LAN_PG0_RSR, LAN_PAGE0)) & LAN_PG0_RSR_PRXS))
{
if (tmp & LAN_PG0_RSR_FO)
{
G_stat[dev_num].r_orun++;
RxOflow(dev_num);
}
else
G_stat[dev_num].r_other++;
splx(iLevel);
return;
}
/*-----------------------------------------------------------------*/
/* Get the boundary page and current page */
/*-----------------------------------------------------------------*/
rxing_page = rdStNicReg(dev_num, LAN_PG1_CURR, LAN_PAGE1);
this_page = rdStNicReg(dev_num, LAN_PG0_BNRY, LAN_PAGE0) + 1;
if (this_page >= LAN_RXSTOP)
this_page = LAN_RXSTART;
/*-----------------------------------------------------------------*/
/* If the boundary ptr equals the current ptr break. */
/*-----------------------------------------------------------------*/
if (this_page == rxing_page)
{
splx (iLevel);
return;
}
RxPktPagePtr[dev_num] = this_page; /* current page */
/*-----------------------------------------------------------------*/
/* Allocate a header from the RxFreeHdr list. If there a no */
/* headers available get out of the loop. */
/*-----------------------------------------------------------------*/
if (RxLstFreeHead[dev_num] != NULL)
{
rcvHdrPtr = RxLstFreeHead[dev_num];
RxLstFreeHead[dev_num] = RxLstFreeHead[dev_num]->next;
RxLstFreeCount[dev_num]--;
/*--------------------------------------------------------------*/
/* Read four bytes from the boundary pointer */
/*--------------------------------------------------------------*/
remDmaSetup(dev_num, (RxPktPagePtr[dev_num] << 8) + 0, 4, REMOTE_READ);
remDmaDo(dev_num, (UCHAR *) &(rcvHdrPtr->bufStat), 4, REMOTE_READ);
/*--------------------------------------------------------------*/
/* Per packet initialization. */
/*--------------------------------------------------------------*/
rcvHdrPtr->dataLen = (rcvHdrPtr->bufStat.sizeLsb
+ ((USHORT)(rcvHdrPtr->bufStat.sizeMsb) << 8));
rcvHdrPtr->pageNum = RxPktPagePtr[dev_num];
/*--------------------------------------------------------------*/
/* Check if this nextPage value is not bogus */
/*--------------------------------------------------------------*/
next_page = rcvHdrPtr->pageNum + 1 + (rcvHdrPtr->dataLen >> 8);
/*--------------------------------------------------------------*/
/* Advance Page Pointer */
/*--------------------------------------------------------------*/
RxPktPagePtr[dev_num] = rcvHdrPtr->bufStat.nextPage;
/*--------------------------------------------------------------*/
/* Determine if this packet is okay. */
/* Packets with CRC & Frame alignment errors & runt errors are */
/* rejected. See RCR setup in StNicInit() */
/*--------------------------------------------------------------*/
if ((rcvHdrPtr->bufStat.nextPage != next_page) &&
(rcvHdrPtr->bufStat.nextPage != next_page + 1) &&
(rcvHdrPtr->bufStat.nextPage != next_page - LAN_NUM_RXBUFFS) &&
(rcvHdrPtr->bufStat.nextPage != next_page + 1 - LAN_NUM_RXBUFFS))
{
/*----------------------------------------------------------*/
/* Update MIB stats */
/*----------------------------------------------------------*/
G_stat[dev_num].r_oflo++;
/*----------------------------------------------------------*/
/* Free the header */
/*----------------------------------------------------------*/
RxPktDetach(rcvHdrPtr);
/*----------------------------------------------------------*/
/* Reset current/boundary page */
/*----------------------------------------------------------*/
RxPktPagePtr[dev_num] = rxing_page;
}
else if (((rcvHdrPtr->bufStat.frameStat & (LAN_PG0_RSR_CRCE |
LAN_PG0_RSR_FAE |
LAN_PG0_RSR_FO |
LAN_PG0_RSR_MPA)) != 0)
|| (rcvHdrPtr->dataLen > (BSP_LAN1_MTU + 18)))
{
UCHAR frameStat = rcvHdrPtr->bufStat.frameStat;
/*----------------------------------------------------------*/
/* Update MIB stats */
/*----------------------------------------------------------*/
if (frameStat & LAN_PG0_RSR_CRCE)
G_stat[dev_num].r_crc++;
else if (frameStat & LAN_PG0_RSR_FAE)
G_stat[dev_num].r_fram++;
else if (frameStat & LAN_PG0_RSR_FO)
G_stat[dev_num].r_orun++;
else if (frameStat & LAN_PG0_RSR_MPA)
G_stat[dev_num].r_miss++;
else
G_stat[dev_num].r_too_long++;
/*----------------------------------------------------------*/
/* Free the header */
/*----------------------------------------------------------*/
RxPktDetach(rcvHdrPtr);
}
else
{
/*-----------------------------------------------------------*/
/* Copy buffer data to a header. */
/*-----------------------------------------------------------*/
RxCpyData(rcvHdrPtr);
/*-----------------------------------------------------------*/
/* Process the Packet */
/*-----------------------------------------------------------*/
RxPktProc(rcvHdrPtr);
}
}
else
{
/*--------------------------------------------------------------*/
/* Increment missed frame count */
/*--------------------------------------------------------------*/
G_stat[dev_num].r_nobufs++;
splx(iLevel);
break;
}
/*-----------------------------------------------------------------*/
/* Update boundary page register in ST-NIC */
/*-----------------------------------------------------------------*/
if (RxPktPagePtr[dev_num] >= LAN_RXSTOP)
RxPktPagePtr[dev_num] = LAN_RXSTART;
wrStNicReg(dev_num, LAN_PG0_BNRY, (UCHAR)(RxPktPagePtr[dev_num] - 1),
LAN_PAGE0);
/*-----------------------------------------------------------------*/
/* Enable Interrupts */
/*-----------------------------------------------------------------*/
splx(iLevel);
}
return;
}
/***********************************************************************/
/* RxPktProc: Process received packets. */
/* */
/* INPUTS: rcvHdrPtr: Process this receive packet pointer */
/* OUTPUTS: None */
/* */
/***********************************************************************/
STATIC void RxPktProc(LAN_RXPKT_LIST *rcvHdrPtr)
{
mblk_t *msgBlk;
frtn_t frtn;
ULONG type;
long dev_num;
long (*Announce)();
/*---------------------------------------------------------------------*/
/* Set up the device number from the packet structure */
/*---------------------------------------------------------------------*/
dev_num = rcvHdrPtr->dev_num;
/*---------------------------------------------------------------------*/
/* Set up the packet address parameters */
/*---------------------------------------------------------------------*/
type = (ULONG)(ntohs(rcvHdrPtr->type));
/*---------------------------------------------------------------------*/
/* Collect stats for MIB on broadcast and unicast packets. */
/*---------------------------------------------------------------------*/
if (rcvHdrPtr->daddr.ea_bytes[0] & 0x1)
MG_stat[dev_num].innucastpkts++;
else
MG_stat[dev_num].inucastpkts++;
/*---------------------------------------------------------------------*/
/* Check if type is IP, ARP, or RARP and update count of packets */
/* received with unknown protocol. */
/*---------------------------------------------------------------------*/
if ((type != LAN_IP) && (type != LAN_ARP) && (type != LAN_RARP))
MG_stat[dev_num].inunknownprotos++;
/*---------------------------------------------------------------------*/
/* If the packet is acceptable, pass it to pNA+. Otherwise, count the */
/* receive error and return envelope to the free queue. */
/*---------------------------------------------------------------------*/
G_stat[dev_num].l_rcv++;
MG_stat[dev_num].inoctets += rcvHdrPtr->dataLen;
rcvHdrPtr->dataLen -= 14;
frtn.free_arg = (void *) rcvHdrPtr;
frtn.free_func = (void (*)()) RxPktDetach;
Announce = lan_intfs[dev_num].if_announce;
if ((Announce != NULL) && ((msgBlk =
lan_intfs[dev_num].if_ni_funcs.esballoc((char *) rcvHdrPtr->pktbuf,
(int)rcvHdrPtr->dataLen, 0, &frtn)) != 0))
{
if (RxLstFreeCount[dev_num] <= RxLowWaterMark[dev_num]) {
type |= NI_RX_LOW_WATERMARK_REACHED;
}
msgBlk->b_wptr += rcvHdrPtr->dataLen;
(*Announce)(type, (char *) msgBlk, rcvHdrPtr->dataLen,
lan_intfs[dev_num].if_num,
(char *) &(rcvHdrPtr->saddr),
(char *) &(rcvHdrPtr->daddr));
}
else
RxPktDetach(rcvHdrPtr);
}
/***********************************************************************/
/* RxCpyData: Copy data from receive buffers to a receive header */
/* */
/* INPUTS: LAN_RXPKT_LIST *rcvHdrPtr = Address of Receive header */
/* OUTPUTS: None */
/* */
/***********************************************************************/
STATIC void RxCpyData(LAN_RXPKT_LIST *rcvHdrPtr)
{
register ULONG numBytes;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -