51/AVR单片机技术驿站!  <在线翻译>     便利工具    特色网址   无弹窗、无插件的绿色站点...  英才招聘   学历查询  喜欢>>收藏我站 

当前位置:首页 > ARM/CPLD/综合 > 详细内容
at91rm9200下的8019as网卡硬中断问题
发布时间:2009/7/23  阅读次数:718  字体大小: 【】 【】【
下是我参照网上修改的8019as中断式网络驱动(以ne2000的ISA驱动修改)
下面这个是Ne.c (drivers\net) 主要修改地方用红色的字表示
现在是文件系统都能进去了,用板子ping主机,显示出来的结果是时间超时,但我用抓包工具显示,主机的网卡也确实接受到数据,而且也显示是同一个MAC地址发出的。
目前自己认为是中断赋值出错,就是我用绿色字表示的。主要的就是我的中断号如何我的硬件中断联系起来,用什么函数在那定义。
而且在板子里ping自己是能ping通的(就是ping 127.0.0.1)
硬件情况:网卡中断接的针脚:PA23(既IRQ3)
                              网卡基地址:0x50000000(既片选NCS4)

现在不知如何是好,希望高人指点帮助


#include
#include
#include
#include
#include
#include              //add by wzj
#include //add by wzj

#include 8390.h
#define DRV_NAME ne

#define    RTL_8019_IRQ     (22) //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 Intnl */
      {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 0x48     //add by wzj    只能是8bit 模式(由于硬件的原因目前只能8bit模式)

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 ); //这个函数在2.4内核没有的,不知道用什么函数能代替他。
if(base_addr==0){
         dev->base_addr = base_addr = __ioremap(0x50000000,sizeof(unsigned int),0,1);    //这个函数2.6内涵是4个参数,2.4内核就只有3个参数就够了。
    dev->irq = RTL_8019_IRQ;
    once++;
    }
//*********************************** wzj ************************************

SET_MODULE_OWNER(dev);
/* First check any supplied i/o locations. User knows best. */
if (base_addr > 0x1ff) /* Check a single specified location. */
    return ne_probe1(dev, base_addr);
else if (base_addr != 0) /* Dont 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)
{

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];
for(i=0;i<6;i++) {
    SA_prom = ep;
}

SA_prom[14] = SA_prom[15]=0x57;
wordlength =1;
}
//****************************************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 (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 dont know that IRQ 2 is really IRQ 9,
         or dont know which one to set. */
    dev->irq = 9;
if (! dev->irq) {
    printk( failed to detect IRQ line.\n);
    ret = -EAGAIN;
    goto err_out;
}
/* Snarf the interrupt now.    Theres no point in waiting since we cannot
      share and the board will usually be enabled. */
ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);     //这里的中断号,如何和我硬件中断联系起来呢???
//ret = at91rm9200_gpio_request_irq(dev->irq,23,1,ei_interrupt,GPIO-PA23);

if (ret) {
    printk ( unable to get IRQ %d (errno=%d).\n, dev->irq, ret);
    goto err_out;
}
dev->base_addr = ioaddr;
#ifdef CONFIG_PLAT_MAPPI
outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
    ioaddr + E8390_CMD); /* 0x61 */
for (i = 0 ; i < ETHER_ADDR_LEN ; i++) {
    dev->dev_addr[i] = SA_prom[i]
     = inb_p(ioaddr + EN1_PHYS_SHIFT(i));
    printk( %2.2x, SA_prom[i]);
}
#else
for(i = 0; i < ETHER_ADDR_LEN; i++) {
    printk( %2.2x, SA_prom[i]);
    dev->dev_addr[i] = SA_prom[i];
}
#endif
printk(\n%s: %s found at %#x, using IRQ %d.\n,
    dev->name, name, ioaddr, dev->irq);
ei_status.name = name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
#ifdef CONFIG_PLAT_OAKS32R
ei_status.word16 = 0;
#else
ei_status.word16 = (wordlength == 2);
#endif
ei_status.rx_start_page = start_page + TX_PAGES;
#ifdef PACKETBUF_MEMSIZE
    /* Allow the packet buffer size to be overridden by know-it-alls. */
ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
#endif
我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

网站导航 管理登陆 ┊ 免责声明 问题反馈  友链说明
本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正!
不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作!

    我要报警 Alexa
 mcusy_cn#126.com (请把#改成@) 交流:522422171
本站学习交流群:138..158(高级群1-)、77930286(高级群2)、61804809(群3)
Copyright© MCUSY All Rights Reserved
本站网警备案号: WZ36040002485
  ICP备案证书号:粤ICP备09034963号