📄 ns8390x.c
字号:
/*---------------------------------------------------------------------*/
/* Define Receive Packet list and free list pointer */
/*---------------------------------------------------------------------*/
STATIC ULONG LanNrRxPkts; /* Number of Rx Packets */
STATIC LAN_RXPKT_LIST *RxPktList[NUM_NS8390];
STATIC LAN_RXPKT_LIST *RxLstFreeHead[NUM_NS8390]; /* Head of free list */
STATIC ULONG RxPktPagePtr[NUM_NS8390];
STATIC ULONG RxLstFreeCount[NUM_NS8390];
STATIC ULONG RxLowWaterMark[NUM_NS8390];
/*---------------------------------------------------------------------*/
/* Miscellaneous variables */
/*---------------------------------------------------------------------*/
STATIC long ni_init_cnt; /* NI count */
STATIC struct lan_intf lan_intfs[NUM_NS8390];
STATIC volatile ULONG crPtr[NUM_NS8390]; /* Control register Ptr */
STATIC volatile ULONG portPtr[NUM_NS8390]; /* DMA port address of St Nic */
STATIC mib_stat MG_stat[NUM_NS8390];
STATIC struct lance_stat G_stat[NUM_NS8390];
#if ((BOARD_FLAGS) & (IFF_MULTICAST))
STATIC unsigned char lan_mcast_ref[NUM_NS8390][64];
#endif
STATIC ULONG Channel_idx;
/***********************************************************************/
/* NI Function Prototypes */
/* */
/* Chip & Buffer initialization routines */
/***********************************************************************/
STATIC long nic_get_dev_num(long);
STATIC UCHAR rdStNicCR(long);
STATIC void wrStNicCR(long, UCHAR);
STATIC UCHAR rdStNicReg(long, ULONG, ULONG);
STATIC void wrStNicReg(long, ULONG, UCHAR, ULONG);
STATIC void StNicInit(long);
STATIC void InitBuffers(long);
STATIC int ns8390probe(long);
/*---------------------------------------------------------------------*/
/* Local Packet reception procesing routines */
/*---------------------------------------------------------------------*/
STATIC void RxOflow(long);
STATIC ULONG RxPktDetach(LAN_RXPKT_LIST *);
STATIC void RxPktRcv(long);
STATIC void RxPktProc(LAN_RXPKT_LIST *);
STATIC void RxCpyData(LAN_RXPKT_LIST *);
/*---------------------------------------------------------------------*/
/* Remote DMA management routines */
/*---------------------------------------------------------------------*/
STATIC void remDmaSetup(long, ULONG, ULONG, ULONG);
STATIC void remDmaDo(long, UCHAR *, ULONG, ULONG);
/*---------------------------------------------------------------------*/
/* Local packet transmission procesing routines */
/*---------------------------------------------------------------------*/
STATIC void TxCpyData(LAN_TX_HDR *, ULONG);
STATIC void TxFillBuffs_isr(long);
STATIC void TxFillBuffs(long);
STATIC int ns8390_trigger_send(long, ULONG, ULONG);
/*---------------------------------------------------------------------*/
/* MIB related functions */
/*---------------------------------------------------------------------*/
STATIC void update_mib_stat(long dev_num);
STATIC void copyphysaddress(ULONG if_num, void *dest);
STATIC void ns8390_pna_init(ULONG);
#if ((BOARD_FLAGS) & (IFF_MULTICAST))
STATIC ULONG lan_mcast_hash_idx(UCHAR *);
STATIC long lan_map_mcast(struct ni_map_mcast *mmap);
STATIC long lan_add_mcast(ULONG, UCHAR *);
STATIC long lan_del_mcast(ULONG, UCHAR *);
#endif
/*---------------------------------------------------------------------*/
/* Ni interface routines */
/*---------------------------------------------------------------------*/
STATIC void ns8390_setup(union nientry *p);
STATIC long ns8390_init(long (*)(), long, struct ni_funcs *);
STATIC long ns8390_send(long, char *, char *, USHORT, USHORT);
STATIC long ns8390_isr(long);
STATIC void ns8390Stop(long);
STATIC unsigned long ns8390_ioctl(unsigned long, unsigned long, long*);
/***********************************************************************/
/* Ni Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* nic_get_dev_num: Get device number from interface number */
/* */
/* INPUTS: interface number */
/* */
/* OUTPUTS: device number */
/* */
/***********************************************************************/
STATIC long nic_get_dev_num(long if_num)
{
#if NUM_NS8390 == 1
return 0;
#else
long i;
for (i=0; i<NUM_NS8390; i++)
{
if (lan_intfs[i].if_num == if_num)
break;
}
if (i < NUM_NS8390)
return i;
else
return 0; /* it should return -1 if the caller cheks */
#endif /* NUM_NS8390 */
}
/***********************************************************************/
/* rdStNicCR: Read the Command Register */
/* */
/* INPUTS: device number */
/* */
/* OUTPUTS: UCHAR regVal */
/* */
/***********************************************************************/
STATIC UCHAR rdStNicCR(long dev_num)
{
UCHAR cr;
cr = inb(crPtr[dev_num]);
return (cr);
}
/***********************************************************************/
/* wrStNicCR: Write the Command Register */
/* */
/* INPUTS: long dev_num = Device number */
/* UCHAR regVal */
/* */
/* OUTPUTS: none */
/* */
/***********************************************************************/
STATIC void wrStNicCR(long dev_num, UCHAR regVal)
{
outb(crPtr[dev_num], regVal);
}
/***********************************************************************/
/* rdStNicReg: Read a StNic register */
/* */
/* INPUTS: long dev_num = Device number */
/* UCHAR *regAddr = Address of the register */
/* ULONG pg = Page number */
/* */
/* OUTPUTS: UCHAR regVal */
/* */
/***********************************************************************/
STATIC UCHAR rdStNicReg(long dev_num, ULONG regAddr, ULONG pg)
{
UCHAR regVal;
/*---------------------------------------------------------------------*/
/* Write the command register with the correct page number */
/*---------------------------------------------------------------------*/
if (((regVal = rdStNicCR(dev_num)) & LAN_PBMASK) != pg)
{
regVal &= 0x3F;
wrStNicCR(dev_num, (UCHAR)(regVal | pg));
}
/*---------------------------------------------------------------------*/
/* Read the specified register from the page */
/*---------------------------------------------------------------------*/
regVal = inb(regAddr);
return (regVal);
}
/***********************************************************************/
/* wrStNicReg: Write to a StNic register */
/* */
/* INPUTS: long dev_num = Device number */
/* UCHAR *regAddr = Address of the register */
/* UCHAR regVal = Value to write */
/* ULONG pg = Page number */
/* OUTPUTS: None */
/* */
/***********************************************************************/
STATIC void wrStNicReg(long dev_num, ULONG regAddr, UCHAR regVal, ULONG pg)
{
UCHAR val;
/*---------------------------------------------------------------------*/
/* Write the command register with the correct page number */
/*---------------------------------------------------------------------*/
if (((val = rdStNicCR(dev_num)) & LAN_PBMASK) != pg)
{
val &= 0x3F;
wrStNicCR(dev_num, (UCHAR)(val | pg));
}
/*---------------------------------------------------------------------*/
/* Write to the specified register from the page */
/*---------------------------------------------------------------------*/
outb(regAddr, regVal);
}
/***********************************************************************/
/* StNicInit: Initialize the StNic Control & Status Registers */
/* */
/* INPUTS: long dev_num = Device number */
/* OUTPUTS: None */
/* */
/* NOTES: This code follows the instructions for the initialization */
/* procedure on page 37: section 11.0 of the manual. */
/* */
/***********************************************************************/
STATIC void StNicInit(long dev_num)
{
ULONG i, j, cnt;
UCHAR rval;
e_addr *hwaPtr = &lan_intfs[dev_num].if_enet_addr;
/*---------------------------------------------------------------------*/
/* Set Command Register */
/* - Page 0 Regs, Abort Remote DMA, stop the chip */
/*---------------------------------------------------------------------*/
ns8390Stop(dev_num);
/*---------------------------------------------------------------------*/
/* Data Configuration register */
/* - 4 word FIFO */
/* We must set the 8390 for word mode. */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_DCR, (LAN_PG0_DCR_LS | LAN_PG0_DCR_FT8B | LAN_PG0_DCR_WTS), LAN_PAGE0);
/*---------------------------------------------------------------------*/
/* 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);
/*---------------------------------------------------------------------*/
/* Receive Configuration Register */
/* - Accept Broadcast & Multicast Packets */
/*---------------------------------------------------------------------*/
#if ((BOARD_FLAGS) & (IFF_MULTICAST))
wrStNicReg(dev_num, LAN_PG0_RCR,
(LAN_PG0_RCR_SEP | LAN_PG0_RCR_AB | LAN_PG0_RCR_AM), LAN_PAGE0);
#else
wrStNicReg(dev_num, LAN_PG0_RCR, LAN_PG0_RCR_SEP | LAN_PG0_RCR_AB, LAN_PAGE0);
#endif
/*---------------------------------------------------------------------*/
/* Transmit Configuration Register */
/* - Internal Loopback Enable */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_TCR, LAN_PG0_TCR_LBM1, LAN_PAGE0);
/*---------------------------------------------------------------------*/
/* Buffer Ring Registers - Boundary, PStart & PStop */
/* - Accept Broadcast Packets */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_BNRY, LAN_RXSTART - 1, LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_PSTRT, LAN_RXSTART, LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_PSTOP, LAN_RXSTOP, LAN_PAGE0);
RxPktPagePtr[dev_num] = LAN_RXSTART;
/*---------------------------------------------------------------------*/
/* Interrupt Status Register */
/* - Clear */
/*---------------------------------------------------------------------*/
wrStNicReg(dev_num, LAN_PG0_ISR, 0xFF, LAN_PAGE0);
wrStNicReg(dev_num, LAN_PG0_IMR, 0x00, LAN_PAGE0);
/*---------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -