📄 dm9000.c
字号:
// temp &= ~(3 << (7 * 2));
// temp |= PinSel0Save;
// outl(temp, PINSEL0);
// local_irq_restore(flag);
// free_irq(dev->irq, dev);
//}
return(0);
}
/*********************************************************************************************************
** Function name: net_rx
** Descriptions: transact receving data
** Input: dev: information of device
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void net_rx(struct net_device *dev, unsigned int length)
{
struct sk_buff *skb;
u8 *dec;
board_info_t *db = dev->priv;
/*
* The packet has been retrieved from the transmission
* medium. Build an skb around it, so upper layers can handle it
*/
skb = dev_alloc_skb(length + 2);
if (!skb)
{
return;
}
skb_reserve(skb, 2); /* align IP on 16B boundary */
skb_put(skb, length);
dec = skb->data;
insw(db->io_data, dec, length >> 1);
if ((length & 0x01) != 0)
{
dec[length - 1] = inb(db->io_data);
}
/* Write metadata, and then pass to the receive level */
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb);
dev->last_rx = jiffies;
return;
}
/*********************************************************************************************************
** Function name: device_rx
** Descriptions: device receving data
** Input: dev: information of device
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int device_rx(struct net_device *dev)
{
unsigned int i, RxStatus, RxLen, GoodPacket, tmplen;
unsigned int rxbyte;
board_info_t *db = dev->priv;
while (1)
{
ior(db, 0xf0); /* Dummy read *///set the address to 0xf0
//ior(db,0xfe); /* only for delay IO must act */
rxbyte = inb(db->io_data);
//rxbyte = ior(db,0xf0);/* Got most updated data */
/* Status check: this byte must be 0 or 1 */
if (rxbyte > DM9000_PKT_RDY)
{
return -1;
}
if (rxbyte != DM9000_PKT_RDY)
{
break;
}
/* A packet ready now & Get status/length */
GoodPacket = TRUE;
outb(0xf2, db->ioaddr);//set the address to 0xf2
RxStatus = inw(db->io_data);
RxLen = inw(db->io_data);
/* Packet Status check */
if (RxLen < 60)
{ //Runt Packet
GoodPacket = FALSE;
}
if (RxLen > DM9000_PKT_MAX)
{ //long packet
return -1;
}
if (RxStatus & 0xbf00)
{//status err
GoodPacket = FALSE;
}
/* Move data from DM9000 */
if ( GoodPacket )
{
net_rx(dev, RxLen);
}
else
{
/* Without buffer or error packet */
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
{
inw(db->io_data);
}
}
}
return 0;
}
/*********************************************************************************************************
** Function name: net_tasklet
** Descriptions: The tasklet for interrupt handler
** Input:
** Output none
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void net_tasklet(unsigned long data)
{
struct net_device *dev;
dev = (struct net_device *)data;
device_init(dev);
}
/*********************************************************************************************************
** Function name: net_irq_handle
** Descriptions: The top-half interrupt handler
** Input:
** Output none
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int net_irq_handle(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned int int_status;
struct net_device *dev;
board_info_t *db;
dev = (struct net_device *)dev_id;
db = dev->priv;
int_status = ior(db, 0xfe); /* Got ISR */
iow(db, 0xfe, int_status); /* Clear ISR status */
//outl(1 << (dev->irq - 14), EXTINT);
EXTINT |= 0x4;
if (int_status & DM9000_TX_INTR) //表示发送成功,判断发送状态寄存器TSR,决定是否出错
{
netif_start_queue(dev);
}
if (int_status & DM9000_RX_INTR) /* 接收成功 */
{
if (device_rx(dev) == -1)
{
DM9000Dev = dev;
tasklet_schedule (&ZLG_net_tasklet);
}
}
return(IRQ_HANDLED);
}
/*********************************************************************************************************
** Function name: net_init_module
** Descriptions: init driver
** Input: none
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int net_init_module(void)
{
int result;
int lResult;
result = register_netdev(&net_net);
if (result < 0)
{
printk(KERN_ERR "eth0: error %i registering device \"%s\"\n",
result, net_net.name);
return(result);
}
return(0);
}
/* auto probe net driver and regnetdev */
struct net_device * __init dm9000_probe(int unit)
{
int lResult;
unsigned int ulData;
*(volatile unsigned int *)(0xffe0000c) = 0x10001460;/* set system device work clock */
// *(volatile unsigned int *)(0xffe0000c) = 0x1000ffef;
udelay(10);
if(initflag == 0)
{
lResult = search9000();
if(lResult == 1)
{
printk(KERN_ERR "find net card dm9000\n");
}
else
{
printk(KERN_ERR "not find net card dm9000\n");
}
initflag = 1;
net_init_module();
}
}
/* find dm9000 netchip */
int search9000()
{
int cardfound = 0;
uint32 ulData = 0;
NetDriverInfo[0].ioaddr = 0x83000000;
NetDriverInfo[0].io_data = 0x83400000;
iow(NetDriverInfo,0x00,0x01);
udelay(10);
ulData = ior(NetDriverInfo,DM9KS_VID_L);
ulData |= ior(NetDriverInfo,DM9KS_VID_H)<<8;
ulData |= ior(NetDriverInfo,DM9KS_PID_L)<<16;
ulData |= ior(NetDriverInfo,DM9KS_PID_H)<<24;
if(ulData == DM9KS_ID || ulData == DM9010_ID)
{
cardfound = 1;
}
return cardfound;
}
/*********************************************************************************************************
** Function name: net_cleanup
** Descriptions: exit driver
** Input: none
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void net_cleanup(void)
{
unregister_netdev(&net_net);
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -