at91rm9200下的8019as下网卡中断问题(兼容ne2000)
以下是我参照网上修改的8019as中断式网络驱动(以ne2000的ISA驱动修改)
下面这个是Ne.c (drivers\net) 主要修改地方用红色的字表示
输出结果用蓝色字表示
目前自己认为是中断赋值出错,就是我用绿色字表示的
硬件情况:网卡中断接的针脚:PA23(既IRQ3)
网卡基地址:0x50000000(既片选NCS4)
现在不知如何是好,希望高人指点帮助
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h> //add by wzj
#include <asm/arch/hardware.h> //add by wzj
#include "8390.h"
#define DRV_NAME "ne"
//unsigned int RTL_8019_BASE= (AT91_IO_P2V(0x50000000)); //add by wzj
#define RTL_8019_BASE (AT91C_VA_ISA_NET) //add by wzj
#define RTL_8019_IRQ AT91C_ID_IRQ3 //add by wzj
#define EBI_CSA 0x00 //add by wzj
#define EBI_CFGR 0x04 //add by wzj
#define SMC2_CSR4 0x10 //add by wzj
#define SUPPORT_NE_BAD_CLONES
#ifndef MODULE
static unsigned int netcard_portlist[] __initdata = {
0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0
};
#endif
static struct isapnp_device_id isapnp_clone_list[] __initdata = {
{ ISAPNP_CARD_ID('A','X','E',0x2011),
ISAPNP_VENDOR('A','X','E'), ISAPNP_FUNCTION(0x2011),
(long) "NetGear EA201" },
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216),
(long) "NN NE2000" },
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('P','N','P'), ISAPNP_FUNCTION(0x80d6),
(long) "Generic PNP" },
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(isapnp, isapnp_clone_list);
#ifdef SUPPORT_NE_BAD_CLONES
/* A list of bad clones that we none-the-less recognize. */
static struct { const char *name8, *name16; unsigned char SAprefix[4];}
bad_clone_list[] __initdata = {
{"DE100", "DE200", {0x00, 0xDE, 0x01,}},
{"DE120", "DE220", {0x00, 0x80, 0xc8,}},
{"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */
{"EtherNext UTP8", "EtherNext UTP16", {0x00, 0x00, 0x79}},
{"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */
{"NN1000", "NN2000", {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */
{"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}}, /* Outlaw 4-Dimension cards. */
{"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */
{"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */
{"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */
{"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{"RTL8019AS", "NE2000-compatible", {0x08, 0x08, 0x08}}, //add by wzj
{NULL,}
};
#endif
/* ---- No user-serviceable parts below ---- */
#define NE_BASE RTL_8019_BASE //(dev->base_addr)
#define NE_CMD 0x00
#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */
#define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */
#define NE_IO_EXTENT 0x20
#define NE1SM_START_PG 0x20 /* First page of TX buffer */
#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
#define NESM_START_PG 0x40 /* First page of TX buffer */
#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
#if 0 //add by wzj
#if defined(CONFIG_PLAT_MAPPI)
# define DCR_VAL 0x4b
#elif defined(CONFIG_PLAT_OAKS32R)
# define DCR_VAL 0x48
#else
# define DCR_VAL 0x49
#endif
#endif //add by wzj
#define DCR_VAL 0x49 //add by wzj 只能是16bit 模式
static int ne_probe1(struct net_device *dev, int ioaddr);
static int ne_probe_isapnp(struct net_device *dev);
static int ne_open(struct net_device *dev);
static int ne_close(struct net_device *dev);
static void ne_reset_8390(struct net_device *dev);
static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
static void ne_block_input(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
static void ne_block_output(struct net_device *dev, const int count,
const unsigned char *buf, const int start_page);
static int __init do_ne_probe(struct net_device *dev)
{
unsigned int base_addr =dev->base_addr;
#ifndef MODULE
int orig_irq = dev->irq;
#endif
//****************************** wzj ********************************
//在do_ne_probe函数中增加配置总线参数、基地址和中断的语句
static int once=0;
if (once) {
return -ENXIO;
}
unsigned int value;
value = __raw_readl(AT91C_VA_BASE_EBI);
value&=~AT91C_EBI_CS4A;
__raw_writel(value,AT91C_VA_BASE_EBI+EBI_CSA);
value=0;
value=((AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00));
__raw_writel(value,AT91C_VA_BASE_EBI+EBI_CFGR);
value=0;
value= ((AT91C_SMC2_NWS & 0x9) | AT91C_SMC2_WSEN | (AT91C_SMC2_TDF & 0x200) | AT91C_SMC2_DBW_8);
__raw_writel(value,AT91C_VA_BASE_SMC2+SMC2_CSR4);
printk("\n value=0x%x\n AT91C_EBI_CS4A=0x%X\n",value,AT91C_EBI_CS4A);
set_irq_type(RTL_8019_IRQ,IRQT_LOW );
if(base_addr==0){
dev->base_addr = base_addr = RTL_8019_BASE ;
dev->irq = RTL_8019_IRQ;
once++;
}
//*********************************** wzj ************************************
SET_MODULE_OWNER(dev);
/* First check any supplied i/o locations. User knows best. <cough> */
if (base_addr > 0x1ff) /* Check a single specified location. */
return ne_probe1(dev, base_addr);
else if (base_addr != 0) /* Don't probe at all. */
return -ENXIO;
/* Then look for any installed ISAPnP clones */
if (isapnp_present() && (ne_probe_isapnp(dev) == 0))
return 0;
#ifndef MODULE
/* Last resort. The semi-risky ISA auto-probe. */
for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
int ioaddr = netcard_portlist[base_addr];
dev->irq = orig_irq;
if (ne_probe1(dev, ioaddr) == 0)
return 0;
}
#endif
return -ENODEV;
}
static void cleanup_card(struct net_device *dev)
{
struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
if (idev)
pnp_device_detach(idev);
free_irq(dev->irq, dev);
release_region(dev->base_addr, NE_IO_EXTENT);
}
————————————————————————————
..................
————————————————————————————
static int __init ne_probe1(struct net_device *dev, int ioaddr)
{
printk("\n=================ioaddr=0x%x\n",ioaddr);
int i;
unsigned char SA_prom[32];
int wordlength = 2;
const char *name = NULL;
unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0}; //8019as 的MAC 地址
int start_page, stop_page;
int neX000, ctron, copam, bad_card;
int reg0, ret;
static unsigned version_printed;
if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
reg0 = inb_p(ioaddr);
if (reg0 == 0xFF) {
ret = -ENODEV;
goto err_out;
}
————————————————————————————
.........................
————————————————————————————
{
struct {unsigned char value, offset; } program_seq[] =
{
{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
{0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
{0x00, EN0_RCNTLO}, /* Clear the count regs. */
{0x00, EN0_RCNTHI},
{0x00, EN0_IMR}, /* Mask completion irq. */
{0xFF, EN0_ISR},
{E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
{32, EN0_RCNTLO},
{0x00, EN0_RCNTHI},
{0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
{0x00, EN0_RSARHI},
{E8390_RREAD+E8390_START, E8390_CMD},
};
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
outb_p(program_seq.value, ioaddr + program_seq.offset);
}
//****************************************wzj start*********************************
//下面是添加MAC 地址
{
unsigned char *ep;
ep = (unsigned char * ) &ne_defethaddr[0];
ne_defethaddr[5]++;
for(i=0;i<6;i++) {
SA_prom = ep;
}
SA_prom[14] = SA_prom[15]=0x57;
wordlength =2;
}
//****************************************wzj end*********************************
#if 0 //add by wzj
for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
SA_prom = inb(ioaddr + NE_DATAPORT);
SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
if (SA_prom != SA_prom[i+1])
wordlength = 1;
}
#endif //add by wzj
if (wordlength == 2)
{
#if 0 //add by wzj
for (i = 0; i < 16; i++)
SA_prom = SA_prom[i+i];
/* We must set the 8390 for word mode. */
outb_p(DCR_VAL, ioaddr + EN0_DCFG);
start_page = NESM_START_PG;
stop_page = NESM_STOP_PG;
#endif //add by wzj
//下面3 句是定义数据宽度16bit 模式
outb_p(0x49, ioaddr + EN0_DCFG); // add by wzj
start_page = NESM_START_PG; // add by wzj
stop_page = NESM_STOP_PG; // add by wzj
} else {
start_page = NE1SM_START_PG;
stop_page = NE1SM_STOP_PG;
}
————————————————
.......................
——————————————————
#else
printk(" not found.\n");
ret = -ENXIO;
goto err_out;
#endif
}
#if 0 //屏蔽自定检测中断号的语句
if (dev->irq < 2)
{
unsigned long cookie = probe_irq_on();
outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */
outb_p(0x00, ioaddr + EN0_RCNTLO);
outb_p(0x00, ioaddr + EN0_RCNTHI);
outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
mdelay(10); /* wait 10ms for interrupt to propagate */
outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */
dev->irq = probe_irq_off(cookie);
if (ei_debug > 2)
printk(" autoirq is %d\n", dev->irq);
} else if (dev->irq == 2)
/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
or don't know which one to set. */
dev->irq = 9;
#endif //add by wzj
if (! dev->irq) {
printk(" failed to detect IRQ line.\n");
ret = -EAGAIN;
goto err_out;
}
..................
得到以下结果:
Uncompressing Linux......................................................... done, booting the kernel.
Linux version 2.6.14.1 (uboot@localhost.localdomain) (gcc version 3.4.4) #79 Mon Feb 2 16:22:32 CST 2009
CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: Atmel AT91RM9200-DK
Memory policy: ECC disabled, Data cache writeback
Clocks: CPU 179 MHz, master 59 MHz, main 18.432 MHz
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists
Kernel command line: mem=32M console=ttyS0,115200 initrd=0x20500000,0x800000 root=/dev/ram rw
AT91: 128 gpio irqs in 4 banks
PID hash table entries: 256 (order: 8, 4096 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 32MB = 32MB total
Memory: 22332KB available (1412K code, 322K data, 88K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
softlockup thread 0 started up.
Freeing initrd memory: 8192K
NET: Registered protocol family 16
NetWinder Floating Point Emulator V0.97 (double precision)
devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
AT91 Real Time Clock driver.
AT91 SPI driver loaded
AT91 Watchdog Timer enabled (5 seconds)
ttyS0 at MMIO 0xfefff200 (irq = 1) is a AT91_SERIAL
ttyS1 at MMIO 0xfefc4000 (irq = 7) is a AT91_SERIAL
io scheduler noop registered
io scheduler anticipatory registered
RAMDISK driver initialized: 16 RAM disks of 16384K size 1024 blocksize
____________________________wzj______________
+++++++++++++ wzj 66++++++++++++++======
mak=0
value=0x4289
AT91C_EBI_CS4A=0x10
=================ioaddr=0xff000400
ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)
Last modified Nov 1, 2000 by Paul Gortmaker
NE*000 ethercard probe at 0xff000400:<4>eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
eth0: interrupt from stopped card
[ 本帖最后由 wzj071227 于 2009-2-3 14:42 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不错,非常不错
怎么没有人回答啊,
那就请教一个简单点的问题吧!
就是我的硬件中断,是如何和系统申请的中断号联系起来的,
请高人指点;