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

📄 ethernet_dm9000.c

📁 dm9000芯片的网络驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
**        addr:   config data** Output: 0:     OK**         other: errno** **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/        static int net_set_mac_address(struct net_device *dev, void *addr){    struct sockaddr *mac_addr;    int i;    mac_addr = addr;    if (netif_running(dev))    {        return -EBUSY;    }    /* Set the device copy of the Ethernet address */    memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);        for(i = 0; i < 6; i++)    {        MyMacID[i] = mac_addr->sa_data[i];    }    device_init(dev);    return 0;    }                           /*********************************************************************************************************** Function name: net_tx** Descriptions:  send data to other machine** Input: skb:    save data for send**        dev:    information of device** Output: 0:     OK**         other: not OK** **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/        static int net_tx(struct sk_buff *skb, struct net_device *dev){    unsigned long flag;    int len;    u16 *data;    board_info_t *db = dev->priv;    netif_stop_queue(dev);    len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;    data = (u16 *)skb->data;    len = (len + 1) & (~1);    local_irq_save(flag);    iow(db, 0xff, 0x80);    outb(0xf8, db->ioaddr);    outsw(db->io_data, data, len >> 1);    iow(db, 0xfc, len & 0xff);    iow(db, 0xfd, (len >> 8) & 0xff);     iow(db, 0x2, 0x1);      /* Cleared after TX complete */        /* Re-enable interrupt*/     iow(db, 0xff, 0x83);                dev->trans_start = jiffies;    local_irq_restore(flag);            dev_kfree_skb(skb);        return 0; /* Our simple device can not fail */}/*********************************************************************************************************** Function name: net_open** Descriptions:  open device** Input: dev:    information of device**       ** Output: 0:     OK**         other: not OK** **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/        static int  net_open(struct net_device *dev){    unsigned long flag;    unsigned int 	i1,i2;     if (usage == 0)    {        BANKCON3= BANKCON_Tacs0 | BANKCON_Tcos4 | BANKCON_Tacc14 |        BANKCON_Toch1 | BANKCON_Tcah4 | BANKCON_Tacp6 | BANKCON_PMC16;	printk(KERN_ERR "request_region!\n");    	request_region(IOaddress0, 0x08, "dm9000");    	printk(KERN_ERR "request_region ok!\n");    	//    	printk(KERN_ERR "Short length %d!\n", sizeof(short));    	        local_irq_save(flag);                mac_hard_open();                device_init(dev);        	printk(KERN_ERR "Network init OK!\n");//	printk(KERN_ERR " !\n");        local_irq_restore(flag);        	set_external_irq(IRQ_EINT0, EXT_HIGHLEVEL, GPIO_PULLUP_DIS);			        if(request_irq(dev->irq, net_irq_handle, SA_INTERRUPT | SA_SAMPLE_RANDOM, "eth0", dev))        {        	printk(KERN_ERR "request irq fault!\n");        }        printk(KERN_ERR "Init INT OK!\n");        netif_start_queue(dev);    }    usage++;    MOD_INC_USE_COUNT;    return 0;          /* success */} /*********************************************************************************************************** Function name: net_release** Descriptions:  release device** Input: dev:    information of device**       ** Output: 0:     OK**         other: not OK** **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/        static int  net_release(struct net_device *dev) {    unsigned long flag;    MOD_DEC_USE_COUNT;    usage--;    if (usage == 0)    {        netif_stop_queue(dev);        local_irq_save(flag);        mac_hard_close();        local_irq_restore(flag);        release_region(IOaddress0, 8);        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** **-------------------------------------------------------------------------------------------------------** 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**  **-------------------------------------------------------------------------------------------------------** 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)    {        rxbyte = ior(db, 0xf0);	  /* Dummy read *///set the address to 0xf0        rxbyte = ior(db, 0xf0);   /* Got most updated data */		//printk(KERN_ERR "rxbyte = %d!!\n",rxbyte);        /* 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);	//printk(KERN_ERR "RxStatus = %d!! RxLen = %d!!\n",RxStatus,RxLen);        /* 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** **-------------------------------------------------------------------------------------------------------** 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** **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/        static void 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 */     	SRCPND |= (1 << 0);/* Clear CPU ISR status */ 	INTPND |= (1 << 0);	//EINTPEND |= (1 << 9); //清除外部中断 EINT9	//printk(KERN_ERR "int_status = %d!!\n",int_status);    if (int_status & DM9000_TX_INTR)     //表示发送成功,判断发送状态寄存器TSR,决定是否出错    {        //printk(KERN_ERR "TX OK\n");        netif_wake_queue(dev);    }    if (int_status & DM9000_RX_INTR)     /* 接收成功       */    {        if (device_rx(dev) == -1)        {            DM9000Dev = dev;            tasklet_schedule(&ZLG_net_tasklet);        }    }}/*********************************************************************************************************** Function name: net_init_module** Descriptions:  init driver** Input: none**       ** Output: 0:     OK**         other: not OK** **-------------------------------------------------------------------------------------------------------** 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** **-------------------------------------------------------------------------------------------------------** 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 + -