⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9000.c

📁 uClinux下
💻 C
📖 第 1 页 / 共 3 页
字号:
    //    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 + -