📄 ns8390x.c
字号:
/* Update Ethernet Physical Address */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG1_PAR0, hwaPtr->ea_bytes[0], LAN_PAGE1); /* LSB of EthAdr */
wrStNicReg(dev_num, LAN_PG1_PAR1, hwaPtr->ea_bytes[1], LAN_PAGE1);
wrStNicReg(dev_num, LAN_PG1_PAR2, hwaPtr->ea_bytes[2], LAN_PAGE1);
wrStNicReg(dev_num, LAN_PG1_PAR3, hwaPtr->ea_bytes[3], LAN_PAGE1);
wrStNicReg(dev_num, LAN_PG1_PAR4, hwaPtr->ea_bytes[4], LAN_PAGE1);
wrStNicReg(dev_num, LAN_PG1_PAR5, hwaPtr->ea_bytes[5], LAN_PAGE1); /* MSB of EthAdr */
/*---------------------------------------------------------------------*/
/* Initialize multicast address registers */
/* Reset multicast bits again on reset. Receive old multicast packets */
/*---------------------------------------------------------------------*/
#if ((BOARD_FLAGS) & (IFF_MULTICAST))
for (i = 0, cnt = 0; i < 8; i++)
{
rval = 0;
for (j = 0; j < 8; j++)
{
if (lan_mcast_ref[dev_num][cnt])
{
rval |= (1 << j);
}
cnt++;
}
wrStNicReg(dev_num, LAN_PG1_MAR0 + i, rval, LAN_PAGE1);
}
#endif
/*---------------------------------------------------------------------*/
/* Update the current Page Register */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG1_CURR, LAN_RXSTART, LAN_PAGE1);
/*---------------------------------------------------------------------*/
/* Start ST-NIC 83902A */
/*---------------------------------------------------------------------*/
wrStNicCR(dev_num, LAN_PG0_CR_STA | LAN_PG0_CR_RD2);
/*---------------------------------------------------------------------*/
/* Take the transmitter out of loopback */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_TCR, LAN_PG0_TCR_LBM0, LAN_PAGE0);
}
/***********************************************************************/
/* InitBuffers: Initialize driver's pools of receive buffers & transmit*/
/* headers */
/* */
/* INPUTS: long dev_num = Device number */
/* OUTPUTS: None */
/* */
/***********************************************************************/
STATIC void InitBuffers(long dev_num)
{
register ULONG i;
/*---------------------------------------------------------------------*/
/* Zero out the transmit headers */
/*---------------------------------------------------------------------*/
zfill((UCHAR *) &TxHeaders[dev_num][0],
(ULONG) (LanNrTxHdrs * sizeof(LAN_TX_HDR)));
/*---------------------------------------------------------------------*/
/* Link transmit headers in a free list */
/*---------------------------------------------------------------------*/
TxHdrFreeHead[dev_num] = &TxHeaders[dev_num][0];
for (i = 0; i < (LanNrTxHdrs - 1); i++)
{
TxHeaders[dev_num][i].dev_num = dev_num;
TxHeaders[dev_num][i].next = &TxHeaders[dev_num][i + 1];
}
TxHeaders[dev_num][(LanNrTxHdrs - 1)].next = NULL;
/*---------------------------------------------------------------------*/
/* Initialize the list of queued transmit headers to empty. */
/*---------------------------------------------------------------------*/
TxHdrOutHead[dev_num] = (LAN_TX_HDR *) NULL;
TxHdrOutTail[dev_num] = (LAN_TX_HDR *) NULL;
/*---------------------------------------------------------------------*/
/* Initialize other transmission variables */
/*---------------------------------------------------------------------*/
TxCurrHdrPtr[dev_num][0] = (LAN_TX_HDR *) NULL;
TxCurrHdrPtr[dev_num][1] = (LAN_TX_HDR *) NULL;
TxAbortpageNum[dev_num] = 0;
TxAbortnumBytes[dev_num] = 0;
/*---------------------------------------------------------------------*/
/* Zero out the memory to be used for the receive buffers. */
/*---------------------------------------------------------------------*/
zfill((UCHAR *) &RxPktList[dev_num][0],
(ULONG) (LanNrRxPkts * sizeof(LAN_RXPKT_LIST)));
/*---------------------------------------------------------------------*/
/* Link the receive buffers together in the free list. */
/*---------------------------------------------------------------------*/
RxLstFreeHead[dev_num] = &RxPktList[dev_num][0];
for (i = 0; i < (LanNrRxPkts - 1); i++)
{
RxPktList[dev_num][i].dev_num = dev_num;
RxPktList[dev_num][i].next = &RxPktList[dev_num][i + 1];
}
RxPktList[dev_num][(LanNrRxPkts - 1)].next = NULL;
RxLstFreeCount[dev_num] = LanNrRxPkts;
}
/***********************************************************************/
/* ns8390probe: Initialize driver and get ethernet address from ROM */
/* */
/* */
/* INPUTS: long dev_num = Device number */
/* OUTPUTS: int (-1 on error, 0 on success) */
/* */
/***********************************************************************/
STATIC int ns8390probe(long dev_num)
{
ULONG reg0, i;
ULONG wordlength = 2, neX000;
UCHAR SA_prom[32], *name=NULL;
struct lan_intf *lan_intfp = &lan_intfs[dev_num];
int regd;
struct {unsigned char value, offset; } program_seq[] =
{
{LAN_PG0_CR_RD2+LAN_PAGE0+LAN_PG0_CR_STP, 0x00}, /* Select page 0*/
{0x48, 0x0e}, /* Set byte-wide (0x48) access. */
{0x00, 0x0a}, /* Clear the count regs. */
{0x00, 0x0b},
{0x00, 0xf}, /* Mask completion irq. */
{0xFF, 0x07},
{0x20, 0x0c}, /* 0x20 Set to monitor */
{0x02, 0x4}, /* 0x02 and loopback mode. */
{32, 0x0a},
{0x00, 0x0b},
{0x00, 0x08}, /* DMA starting at 0x0000. */
{0x00, 0x09},
{LAN_PG0_CR_RD0+LAN_PG0_CR_STA, 0x00},
};
reg0 = inb(LAN_NIC_BASE);
if (reg0 == 0xFF)
return -1;
/*----------------------------------------------------------------*/
/* Do a preliminary verification that we have a 8390. */
/*----------------------------------------------------------------*/
outb(LAN_NIC_BASE, LAN_PG0_CR_RD2+LAN_PAGE1+LAN_PG0_CR_STP);
regd = inb(LAN_NIC_BASE + 0x0d);
outb(LAN_NIC_BASE + 0x0d, 0xff);
outb(LAN_NIC_BASE, LAN_PG0_CR_RD2+LAN_PAGE0);
inb(LAN_PG0_CNTR0); /* Clear the counter by reading.*/
if (inb(LAN_PG0_CNTR0) != 0)
{
outb(LAN_NIC_BASE, (UCHAR)reg0);
outb(LAN_NIC_BASE + 0x0d, (UCHAR)regd);/* Restore the old values. */
return -1;
}
/*----------------------------------------------------------------*/
/* Reset card. */
/*----------------------------------------------------------------*/
outb(LAN_NIC_BASE + NE_RESET, inb(LAN_NIC_BASE + NE_RESET));
while ((inb(LAN_PG0_ISR) & LAN_PG0_ISR_RST) == 0);
outb(LAN_PG0_ISR, 0xff);
/*----------------------------------------------------------------*/
/* Read the 16 bytes of station address PROM. We must first */
/* initialize registers. */
/*----------------------------------------------------------------*/
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
outb(LAN_NIC_BASE + program_seq[i].offset, program_seq[i].value);
for (i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2)
{
SA_prom[i] = inb(portPtr[dev_num]);
SA_prom[i+1] = inb(portPtr[dev_num]);
if (SA_prom[i] != SA_prom[i+1])
wordlength = 1;
}
if (wordlength == 2)
{
for (i = 0; i < 16; i++)
SA_prom[i] = SA_prom[i+i];
}
/*----------------------------------------------------------------*/
/* Cross check SA_prom values */
/* Word access in NE2000 cards */
/*----------------------------------------------------------------*/
neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
if (neX000 && (wordlength == 2))
{
/* We've a NE2000 card */
}
else
{
return -1; /* No LAN Card found */
}
/* Copy the ethernet address */
for (i = 0; i < 6; i++)
{
lan_intfp->if_enet_addr.ea_bytes[i] = SA_prom[i];
}
return 0;
}
/***********************************************************************/
/* RxOflow: A receive overflow occurred. Process according to the */
/* algorithm specified in the manual (section 7.0 page 17). */
/* */
/* INPUTS: long dev_num = Device number */
/* OUTPUTS: None */
/* */
/***********************************************************************/
STATIC void RxOflow(long dev_num)
{
ULONG iLevel;
/*---------------------------------------------------------------------*/
/* Disable Interrupts */
/*---------------------------------------------------------------------*/
iLevel = splhigh();
ns8390Stop(dev_num);
/*---------------------------------------------------------------------*/
/* Remote Byte Count Registers */
/* - Clear Byte Count */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_RBCR0, 0, LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_RBCR1, 0, LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_TCR, LAN_PG0_TCR_LBM1, LAN_PAGE0);
wrStNicCR(dev_num, LAN_PG0_CR_STA | LAN_PG0_CR_RD2);
/*---------------------------------------------------------------------*/
/* Remove Packets from the ring */
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* Reinitialize the chip */
/*---------------------------------------------------------------------*/
StNicInit(dev_num);
/*---------------------------------------------------------------------*/
/* Enable interrupts at the chip */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_IMR, LAN_PG0_IMR_OVWE | LAN_PG0_IMR_TXEE |
LAN_PG0_IMR_RXEE | LAN_PG0_IMR_PTXE |
LAN_PG0_IMR_PRXE | LAN_PG0_IMR_CNTE, LAN_PAGE0);
/*---------------------------------------------------------------------*/
/* Enable Interrupts */
/*---------------------------------------------------------------------*/
splx(iLevel);
}
/***********************************************************************/
/* RxPktDetach: Return a receive header to the free list */
/* */
/* INPUTS: buf_ptr: Pointer to the header being returned */
/* OUTPUTS: None */
/* */
/* NOTES: This is the "Free Routine" called by pNA+ after it has */
/* unlinked the header from the message block structure to */
/* return it to the driver's header poll. */
/* */
/***********************************************************************/
STATIC ULONG RxPktDetach(LAN_RXPKT_LIST *hdrPtr)
{
ULONG iLevel;
long dev_num;
/*---------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -