📄 dm9000.c
字号:
}
DM9000_iow(DM9000_GPCR, 0x01); /* Let GPIO0 output */
DM9000_iow(DM9000_GPR, 0x00); /* Enable PHY */
}
#ifdef CONFIG_DM9000_SROM
static u16 dm9000_read_srom(int offset)
{
DM9000_iow(DM9000_EPAR, offset);
DM9000_iow(DM9000_EPCR, 0x4);
OALStall(200);
DM9000_iow(DM9000_EPCR, 0x0);
return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8));
}
#endif
static void dm9000_reset(void)
{
OALMSGS(DM9000_DEBUG, (L"dm9000_reset\r\n"));
DM9000_iow(DM9000_NCR, NCR_RST);
OALStall(1000); /* delay 1ms */
}
BOOL DM9000Init(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
int i, oft, lnk;
UINT8* pMAC = (UINT8*) mac;
DM9000_IO = (UINT32) pAddress;
DM9000_DATA = DM9000_IO + 4;
OALMSGS(DM9000_DEBUG, (L"+DM9000Init I/O: 0x%08x\r\n", DM9000_IO));
/* RESET device */
dm9000_reset();
dm9000_probe();
/* NIC Type: FASTETHER, HOMERUN, LONGRUN */
// identify_nic();
/* GPIO0 on pre-activate PHY */
DM9000_iow(DM9000_GPR, 0x00); /*REG_1F bit0 activate phyxcer */
/* Set PHY */
dm9000_set_mode(DM9000_PHY_MODE);
/* Program operating register */
DM9000_iow(DM9000_NCR, 0x0); /* only intern phy supported by now */
DM9000_iow(DM9000_TCR, 0); /* TX Polling clear */
// DM9000_iow(DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */
// DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* Flow Control : High/Low Water */
// DM9000_iow(DM9000_FCR, 0xff); /* enable Flow Control */
DM9000_iow(DM9000_SMCR, 0); /* Special Mode */
DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */
DM9000_iow(DM9000_ISR, 0x0f); /* Clear interrupt status */
/* Set Node address */
for (i = 0; i < 6; i++)
#ifdef CONFIG_DM9000_SROM
pMAC[i] = dm9000_read_srom(i);
#else
pMAC[i] = i;
#endif
OALMSGS(DM9000_INFO, (L"DM9000 MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
pMAC[0], pMAC[1], pMAC[2], pMAC[3], pMAC[4], pMAC[5]));
for (i = 0, oft = 0x10; i < 6; i++, oft++)
DM9000_iow(oft, pMAC[i]);
for (i = 0, oft = 0x16; i < 8; i++, oft++)
DM9000_iow(oft, 0xff);
/* read back mac, just to be sure */
// for (i = 0, oft = 0x10; i < 6; i++, oft++)
// DM9000_DBG("%02x:", DM9000_ior(oft));
// DM9000_DBG("\n");
/* Activate DM9000 */
DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* RX enable */
DM9000_iow(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); /* Enable TX/RX interrupt mask */
// DM9000_iow(DM9000_IMR, IMR_PAR);
for( i=0; !(dm9000_phy_read(1) & 0x20); i++) { /* autonegation complete bit */
OALStall(1000);
if (i == 10000) {
OALMSGS(DM9000_ERROR, (L"DM9000 could not establish link\r\n"));
return FALSE;
}
}
/* see what we've got */
lnk = dm9000_phy_read(17) >> 12;
OALMSGS(DM9000_INFO, (L"DM9000 operating at %d mode\r\n", lnk));
OALMSGS(DM9000_DEBUG, (L"-DM9000Init\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
UINT16 DM9000SendFrame(UINT8 *pBuffer, UINT32 length)
{
u8 *data_ptr;
u32 tmplen, i;
// UINT32 startTime;
/* wait for end of transmission */
// Wait until it is sent or an error is generated.
while( DM9000_ior(DM9000_TCR) & TCR_TXREQ);
OALMSGS(DM9000_DEBUG, (L"+DM9000SendFrame %d bytes\r\n", length));
#ifdef CONFIG_DM9000_DEBUG
for (i = 0; i < length; i++) {
if (i % 8 == 0)
DM9000_DBG("\nSend: %02x: ", (unsigned int)i);
DM9000_DBG("%02x ", ((unsigned char *) packet)[i]);
}
DM9000_DBG("\n");
#endif
/* Move data to DM9000 TX RAM */
data_ptr = (u8 *) pBuffer;
DM9000_outb(DM9000_MWCMD, DM9000_IO);
#ifdef CONFIG_DM9000_USE_8BIT
/* Byte mode */
for (i = 0; i < length; i++)
DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA);
#endif /* */
#ifdef CONFIG_DM9000_USE_16BIT
tmplen = (length + 1) / 2;
for (i = 0; i < tmplen; i++)
DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
#endif /* */
#ifdef CONFIG_DM9000_USE_32BIT
tmplen = (length + 3) / 4;
for (i = 0; i < tmplen; i++)
DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
#endif /* */
/* Set TX length to DM9000 */
DM9000_iow(DM9000_TXPLL, length & 0xff);
DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
/* Issue TX command */
DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
OALMSGS(DM9000_DEBUG, (L"-DM9000SendFrame\r\n"));
return 0;
}
//------------------------------------------------------------------------------
UINT16 DM9000GetFrame(UINT8 *pBuffer, UINT16 *pLength)
{
u8 rxbyte, *rdptr = (u8 *) pBuffer;
u16 IntStatus, RxStatus, RxLen = 0;
u32 tmplen, i;
OALMSGS(DM9000_DEBUG, (L"+DM9000GetFrame %d bytes\r\n", *pLength));
*pLength = 0;
IntStatus = DM9000_ior(DM9000_ISR); /* Got ISR */
DM9000_iow(DM9000_ISR, (u8)IntStatus); /* Clear ISR status */
/* Check packet ready or not */
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
if (rxbyte == 0)
return 0;
/* Status check: this byte must be 0 or 1 */
if (rxbyte > 1) {
DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
// DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
OALMSGS(DM9000_ERROR, (L"DM9000 RX status check FAILED (0x%02x)\r\n", rxbyte));
}
/* A packet ready now & Get status/length */
DM9000_outb(DM9000_MRCMD, DM9000_IO);
#ifdef CONFIG_DM9000_USE_8BIT
RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
#endif /* */
#ifdef CONFIG_DM9000_USE_16BIT
RxStatus = DM9000_inw(DM9000_DATA);
RxLen = DM9000_inw(DM9000_DATA);
#endif /* */
#ifdef CONFIG_DM9000_USE_32BIT
tmplen = DM9000_inl(DM9000_DATA);
RxStatus = tmplen;
RxLen = tmplen >> 16;
#endif /* */
OALMSGS(DM9000_DEBUG, (L"DM9000 RX status: 0x%04x, RX len: %d\r\n", RxStatus, RxLen));
/* Move data from DM9000 */
/* Read received packet from RX SRAM */
#ifdef CONFIG_DM9000_USE_8BIT
for (i = 0; i < RxLen; i++)
rdptr[i] = DM9000_inb(DM9000_DATA);
#endif /* */
#ifdef CONFIG_DM9000_USE_16BIT
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
#endif /* */
#ifdef CONFIG_DM9000_USE_32BIT
tmplen = (RxLen + 3) / 4;
for (i = 0; i < tmplen; i++)
((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA);
#endif /* */
if ((RxStatus & 0xbf00) || (RxLen < 0x40)
|| (RxLen > DM9000_PKT_MAX)) {
OALMSGS(DM9000_ERROR, (L"DM9000 RX error (0x%04x)\r\n", RxStatus));
// dm9000_reset();
} else {
#ifdef CONFIG_DM9000_DEBUG
for (i = 0; i < RxLen; i++) {
if (i % 8 == 0)
DM9000_DBG("\nRecv: %02x: ", (unsigned int)i);
DM9000_DBG("%02x ", rdptr[i]);
}
DM9000_DBG("\n");
#endif
*pLength = RxLen;
}
OALMSGS(DM9000_DEBUG, (L"-DM9000GetFrame\r\n"));
return *pLength;
}
//------------------------------------------------------------------------------
VOID DM9000EnableInts()
{
OALMSGS(DM9000_DEBUG, (L"+DM9000EnableInts\r\n"));
DM9000_iow(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); /* Enable TX/RX interrupt mask */
OALMSGS(DM9000_DEBUG, (L"-DM9000EnableInts\r\n"));
}
//------------------------------------------------------------------------------
VOID DM9000DisableInts()
{
OALMSGS(DM9000_DEBUG, (L"+DM9000DisableInts\r\n"));
DM9000_iow(DM9000_IMR, IMR_PAR); /* Disable TX/RX interrupt mask */
DM9000_iow(DM9000_ISR, 0xf);
OALMSGS(DM9000_DEBUG, (L"-DM9000DisableInts\r\n"));
}
//------------------------------------------------------------------------------
VOID DM9000CurrentPacketFilter(UINT32 filter)
{
OALMSGS(DM9000_MISS, (L"+DM9000CurrentPacketFilter(0x%08x)\r\n", filter));
OALMSGS(DM9000_MISS, (L"-DM9000CurrentPacketFilter\r\n"));
}
//------------------------------------------------------------------------------
BOOL DM9000MulticastList(UINT8 *pAddresses, UINT32 count)
{
OALMSGS(DM9000_MISS, (L"+DM9000MulticastList(0x%08x, %d)\r\n", pAddresses, count));
OALMSGS(DM9000_MISS, (L"-DM9000MulticastList\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -