📄 ethernet_dm9000.c
字号:
** 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 + -