📄 cs8900.c
字号:
#include "cs8900.h"
#include "printk.h"
//#include "udelay.h"
#include "net.h"
/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
/* it to wrap 100 times (total 1562500) to get 1 sec. */
#define CFG_HZ 15625
//u8 EthernetAddress[6]={0x60,0x20,0x00,0x00,0x20,0x00};
static u16 get_reg_init_bus(s32 RegisterOffset)
{
/* force 16 bit busmode */
volatile unsigned char c;
c = CS8900_BUS16_0;
c = CS8900_BUS16_1;
c = CS8900_BUS16_0;
c = CS8900_BUS16_1;
c = CS8900_BUS16_0;
CS8900_PacketPageRegister = RegisterOffset;
return (u16) CS8900_PacketPageData;
}
static u16 get_reg(s32 RegisterOffset)
{
CS8900_PacketPageRegister = RegisterOffset;
return (u16) CS8900_PacketPageData;
}
static void put_reg(s32 RegisterOffset, u16 value)
{
CS8900_PacketPageRegister = RegisterOffset;
CS8900_PacketPageData = value;
}
static void eth_reset(void)
{
s32 tmo;
u16 us;
/* reset NIC */
put_reg(PacketPageRegister_SelfCTL, get_reg(PacketPageRegister_SelfCTL) | PacketPageRegister_SelfCTL_Reset );
/* wait for 200ms */
udelay(200000);
/* Wait until the chip is reset */
tmo = 1 * CFG_HZ;
while ((((us = get_reg_init_bus(PacketPageRegister_SelfSTAT)) & PacketPageRegister_SelfSTAT_InitD) == 0)
&& (tmo--) > 0)
/*NOP*/;
}
//void cs8900_get_enetaddr (uchar *addr)
//{
// s32 i;
// /* verify chip id */
// if (get_reg_init_bus(PacketPageRegister_ChipID) != 0x630e)
// return;
// eth_reset();
// if ((get_reg(PacketPageRegister_SelfST) & (PacketPageRegister_SelfSTAT_EEPROM | PacketPageRegister_SelfSTAT_EEPROM_OK)) ==
// (PacketPageRegister_SelfSTAT_EEPROM|PacketPageRegister_SelfSTAT_EEPROM_OK)) {
// /* Load the MAC from EEPROM */
// for (i=0; i<6/2; i++) {
// unsigned s32 Addr;
// Addr = get_reg(PacketPageRegister_IA+i*2);
// addr[i*2] = Addr & 0xFF;
// addr[i*2+1] = Addr >> 8;
// }
// }
//}
void eth_halt( void )
{
/* disable transmitter/receiver mode */
u16 i;
put_reg(PacketPageRegister_LineCTL, 0x31);
/* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
get_reg_init_bus(PacketPageRegister_ChipID);
/* verify chip id */
}
void eth_init( void )
{
/* verify chip id */
if (get_reg_init_bus(PacketPageRegister_ChipID) != 0x630e)
{
printk("we foune nothing here!\n");
return ;
}
//printk("we foune cs8900 chipID here!\n");
eth_reset();
/* set the ethernet address */
put_reg(PacketPageRegister_IA + 0,board_MAC_address[0] | (board_MAC_address[1] << 8));
put_reg(PacketPageRegister_IA + 2, board_MAC_address[2] | (board_MAC_address[3] << 8));
put_reg(PacketPageRegister_IA + 4, board_MAC_address[4] | (board_MAC_address[5] << 8));
/* receive only error free packets addressed to this card */
put_reg(PacketPageRegister_RxCTL, PacketPageRegister_RxCTL_IA | PacketPageRegister_RxCTL_Broadcast | PacketPageRegister_RxCTL_RxOK);
/* do not generate any s32errupts on receive operations */
put_reg(PacketPageRegister_RxCFG, 0);
/* do not generate any s32errupts on transmit operations */
put_reg(PacketPageRegister_TxCFG, 0);
/* do not generate any s32errupts on buffer operations */
put_reg(PacketPageRegister_BufCFG, 0);
/* enable transmitter/receiver mode */
put_reg(PacketPageRegister_LineCTL, PacketPageRegister_LineCTL_Rx | PacketPageRegister_LineCTL_Tx);
}
/* Get a data block via Ethernet */
int eth_rx( void )
{
s32 i;
u16 rxlen=0;
u16 *addr;
u16 status;
status = get_reg(PacketPageRegister_RER);
if ((status & PacketPageRegister_RER_RxOK) == 0)
return 0;
status = CS8900_Receive_TransmitData; /* stat */
rxlen = CS8900_Receive_TransmitData; /* len */
if(0==rxlen) return;
for(addr = (u16 *)receive_packet, i = rxlen >> 1; i > 0; i-- )
*addr++ = CS8900_Receive_TransmitData;
if(rxlen & 1)
*addr++ = CS8900_Receive_TransmitData;
/* Pass the packet up to the protocol layers. */
return rxlen;
}
/* Send a data block via Ethernet. */
int eth_send(volatile void *packet, s32 length)
{
volatile u16 *addr;
s32 tmo;
u16 s;
//retry:
/* initiate a transmit sequence */
CS8900_TxCMD = PacketPageRegister_TxCmd_TxStart_Full;
CS8900_TxLength = length;
/* Test to see if the chip has allocated memory for the packet */
if ((s=get_reg(PacketPageRegister_BusSTAT) & PacketPageRegister_BusSTAT_TxRDY) == 0);
//{
/* Oops... this should not haPacketPageRegisteren! */
// for (tmo = get_timer(0) + 5 * CFG_HZ; get_timer(0) < tmo; )
/*NOP*/;
//eth_reset();
//goto retry;
//}
/* Write the contents of the packet */
/* assume even number of bytes */
for(addr = packet; length > 0; length -= 2 )
CS8900_Receive_TransmitData = *addr++;
/* wait for transfer to succeed */
tmo = 5 * CFG_HZ;
while((s = get_reg(PacketPageRegister_TER) & ~0x1F) == 0)
{
if (0>= tmo--)
break;
}
/* nothing */ ;
if ((s & (PacketPageRegister_TER_CRS | PacketPageRegister_TER_TxOK)) != PacketPageRegister_TER_TxOK) {
return 0;
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -