📄 rtl8019.c
字号:
outl(temp, IO0DIR); outl(1 << 8, IOCLR); device_init(dev); temp = inl(VPBDIV); temp = inl(VPBDIV); outl(0, VPBDIV); outl(inl(EXTMODE) & (~(1 << 3)), EXTMODE); outl(inl(EXTPOLAR) | (1 << 3), EXTPOLAR); outl(temp, VPBDIV); local_irq_restore(flag);
request_irq(dev->irq, net_irq_handle, SA_INTERRUPT | SA_SAMPLE_RANDOM, "eth0", dev);
} usage++; MOD_INC_USE_COUNT; netif_start_queue(dev); return 0; /* success */} /*********************************************************************************************************
** Function name: net_release
** Descriptions: release device
** 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 net_release(struct net_device *dev) { unsigned long flag; u32 temp; netif_stop_queue(dev); MOD_DEC_USE_COUNT;
MOD_DEC_USE_COUNT; usage--;
if (usage == 0)
{
local_irq_save(flag); temp = inl(PINSEL0); temp &= ~(3 << (9 * 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, unsigned int bnry){ struct sk_buff *skb; u8 *dec;
/* * 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 */ WriteToNet(0x09, bnry); //RSAR1写入读页地址的高字节//read page address high
WriteToNet(0x08, 4); //RSAR0写入读页地址的低字节//read page address low
WriteToNet(0x0b, ((length >> 8) & 0x00ff)); //RSCR1写入读取字节计数高字节//read count high
WriteToNet(0x0a, (length & 0x00ff)); //RSCR0写入读取字节计数低字节//read count low;
WriteToNet(0x00, 0x0a); //启动Remote DMA读操作
skb_put(skb, length); dec = skb->data;
insw(RTL8019_REG(0x10), dec, length >> 1);
if ((length & 0x01) != 0)
{
dec[length - 1] = ReadFromNet(0x10);
}
//================终止DMA操作
WriteToNet(0x0b, 0x00);
WriteToNet(0x0a, 0x00);
WriteToNet(0x00, 0x22); /* 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 bnry, curr; unsigned int temp; u32 len;
while (1) { page(0);
bnry = ReadFromNet(0X03) & 0xff; //bnry page have read 读页指针
page(1); curr = ReadFromNet(0X07) & 0xff; //curr writepoint 8019写页指针
page(0);
if (curr == 0)
{
return -1;
} bnry++;
if (bnry > 0x7f)
{
bnry = 0x4c;
} if(bnry == curr) /* none data*/ { break; }
WriteToNet(0x09, bnry); //RSAR1写入读页地址的高字节
WriteToNet(0x08, 0x00); //RSAR0写入读页地址的低字节
WriteToNet(0x0b, 0x00); //RSCR1写入读取字节计数高字节
WriteToNet(0x0a, 4); //RSCR0写入读取字节计数低字节
WriteToNet(0x00, 0x0a); //启动Remote DMA读操作
temp = ReadFromNet(0x10);
len = ReadFromNet(0x10); /* 关闭dma */ WriteToNet(0x0b, 0x00);
WriteToNet(0x0a, 0x00);
WriteToNet(0x00, 0x22);
if (((temp & 0xff00) > 0x7f00) ||
((temp & 0xff00) < 0x4c00)) { page(1);
curr = ReadFromNet(0X07); //page1读取CURR的值
curr = curr & 0xff;
page(0); //切换回page0
bnry = curr - 1; //把bnry恢复为下16K中的空余部分
if(bnry < 0x4c)
{
bnry = 0x7f;
}
WriteToNet(0x03, bnry); //把BNRY恢复到指向下一帧write to bnry
WriteToNet(0x07, 0xff); //清除中断标志 break;
} net_rx(dev, len, bnry);
bnry = (temp / 256) - 1;
if (bnry < 0x4c)
{
bnry = 0x7f;
}
WriteToNet(0x03, bnry); //写入有效的BNRY //write to bnry } 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 void net_irq_handle(int irq, void *dev_id, struct pt_regs *regs){ unsigned int page_save, flag; unsigned int bnry, curr;
struct net_device *dev; dev = (struct net_device *)dev_id; page_save = savepage();
while (1)
{ page(0);
flag = ReadFromNet(0x07) & 0xff;
WriteToNet(0x07, flag); /* 清除中断标志 */
if ((flag & ((1 << 1 )| (1 << 4) | (1 << 0))) == 0)
{
break;
}
if ((flag & (1 << 1)) != 0) /* 发送成功 */
{
netif_start_queue(dev);
}
if ((flag & (1 << 4)) != 0) /* 接收缓冲区溢出 */
{
page(1);
curr = ReadFromNet(0X07); //page1读取CURR的值
curr = curr & 0xff;
page(0); //切换回page0
bnry = curr - 1; //把bnry恢复为下16K中的空余部分
if(bnry < 0x4c)
{
bnry = 0x7f;
}
WriteToNet(0x03, bnry); //把BNRY恢复到指向下一帧write to bnry
WriteToNet(0x07, 0xff); //清除中断标志
}
if ((flag & (1 << 0)) != 0) /* 接收成功 */
{
if (device_rx(dev) == -1)
{
RTL8019Dev = dev;
tasklet_schedule (&ZLG_net_tasklet);
break;
}
}
}
page(page_save); outl(1 << (dev->irq - 14), EXTINT);
}
/*********************************************************************************************************
** 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; result = register_netdev(&net_net); if (result < 0) { printk(KERN_ERR "eth0: error %i registering device \"%s\"\n", result, net_net.name); return(result); } printk(KERN_ERR "eth0: init OK\n"); return(0); }/*********************************************************************************************************
** 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 + -