📄 ed_device.c.bak
字号:
return -EOPNOTSUPP; } /* can change the irq */ if (map->irq != dev->irq) { dev->irq = map->irq; } return 0;}/* * ednet_rx,recieves a network packet and put the packet into TCP/IP up * layer,netif_rx() is the kernel API to do such thing. The recieving * procedure must alloc the sk_buff structure to store the data, * and the sk_buff will be freed in the up layer. */#ifdef LINUX_24void ednet_rx(struct net_device *dev, int len, unsigned char *buf)#elsevoid ednet_rx(struct device *dev ,int len, unsigned char *buf)#endif{ struct sk_buff *skb; struct ednet_priv *priv = (struct ednet_priv *) dev->priv; skb = dev_alloc_skb(len+2); if (!skb) { printk("ednet_rx can not allocate more memory to store the packet. drop the packet\n"); priv->stats.rx_dropped++; return; } skb_reserve(skb, 2); memcpy(skb_put(skb, len), buf, len); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); /* We need not check the checksum */ skb->ip_summed = CHECKSUM_UNNECESSARY; priv->stats.rx_packets++;#ifndef LINUX_20 priv->stats.rx_bytes += len;#endif netif_rx(skb); return;} /* * pseudo network hareware transmit,it just put the data into the * ed_tx device. */#ifdef LINUX_24void ednet_hw_tx(char *buf, int len, struct net_device *dev)#elsevoid ednet_hw_tx(char *buf, int len, struct device *dev)#endif{ struct ednet_priv *priv; /* check the ip packet length,it must more then 34 octets */ if (len < sizeof(struct ethhdr) + sizeof(struct iphdr)) { printk("Bad packet! It's size is less then 34!\n"); return; } /* now push the data into ed_tx device */ ed[ED_TX_DEVICE].kernel_write(buf,len,ed[ED_TX_DEVICE].buffer_size); /* record the transmitted packet status */ priv = (struct ednet_priv *) dev->priv; priv->stats.tx_packets++; priv->stats.rx_bytes += len; /* remember to free the sk_buffer allocated in upper layer. */ dev_kfree_skb(priv->skb); }/* * Transmit the packet,called by the kernel when there is an * application wants to transmit a packet. */#ifdef LINUX_24int ednet_tx(struct sk_buff *skb, struct net_device *dev)#elseint ednet_tx(struct sk_buff *skb, struct device *dev)#endif{ int len; char *data; struct ednet_priv *priv = (struct ednet_priv *) dev->priv; if( ed[ED_TX_DEVICE].busy ==1){ return -EBUSY; }#ifndef LINUX_24 if (dev->tbusy || skb == NULL) { ednet_tx_timeout (dev); if (skb == NULL) return 0; }#endif len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; data = skb->data; /* stamp the time stamp */ dev->trans_start = jiffies; /* remember the skb and free it in ednet_hw_tx */ priv->skb = skb; /* pseudo transmit the packet,hehe */ ednet_hw_tx(data, len, dev); return 0; }/* * Deal with a transmit timeout. */#ifdef LINUX_24void ednet_tx_timeout (struct net_device *dev)#elsevoid ednet_tx_timeout (struct device *dev)#endif{ struct ednet_priv *priv = (struct ednet_priv *) dev->priv; priv->stats.tx_errors++;#ifdef LINUX_24 netif_wake_queue(dev);#endif return;}/* * When we need some ioctls. */#ifdef LINUX_24int ednet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)#elseint ednet_ioctl(struct device *dev, struct ifreq *rq, int cmd)#endif{ return 0;}/* * ifconfig to get the packet transmitting status. */#ifdef LINUX_24struct net_device_stats *ednet_stats(struct net_device *dev)#elsestruct enet_statistics *ednet_stats(struct device *dev)#endif{ struct ednet_priv *priv = (struct ednet_priv *) dev->priv; return &priv->stats;}/* * TCP/IP handshake will call this function, if it need. */#ifdef LINUX_24int ednet_change_mtu(struct net_device *dev, int new_mtu)#elseint ednet_change_mtu(struct device *dev, int new_mtu)#endif{ int err; unsigned long flags; spinlock_t *lock = &((struct ednet_priv *) dev->priv)->lock; /* en, the mtu CANNOT LESS THEN 68 OR MORE THEN 1500. */ if (new_mtu < 68) return -EINVAL; spin_lock_irqsave(lock, flags); dev->mtu = new_mtu; /* realloc the new buffer */ err = ed_realloc(new_mtu); spin_unlock_irqrestore(lock, flags); return err; }#ifdef LINUX_24int ednet_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned int len)#elseint ednet_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned int len)#endif{ struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN); eth->h_proto = htons(type); memcpy(eth->h_source,saddr? saddr : dev->dev_addr,dev->addr_len); memcpy(eth->h_dest, daddr? daddr : dev->dev_addr, dev->addr_len); return (dev->hard_header_len);}int ednet_rebuild_header(struct sk_buff *skb){ struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN); #ifdef LINUX_24 struct net_device *dev = skb->dev;#else struct device *dev = skb->dev;#endif memcpy(eth->h_source, dev->dev_addr ,dev->addr_len); memcpy(eth->h_dest, dev->dev_addr , dev->addr_len); return 0;}#ifdef LINUX_24int ednet_init(struct net_device *dev)#elseint ednet_init(struct device *dev)#endif{ ether_setup(dev); dev->open = ednet_open; dev->stop = ednet_release; dev->set_config = ednet_config; dev->hard_start_xmit = ednet_tx; dev->do_ioctl = ednet_ioctl; dev->get_stats = ednet_stats; dev->change_mtu = ednet_change_mtu; #ifdef LINUX_24 dev->hard_header = ednet_header;#endif dev->rebuild_header = ednet_rebuild_header;#ifdef LINUX_24 dev->tx_timeout = ednet_tx_timeout; dev->watchdog_timeo = timeout;#endif /* We do not need the ARP protocol. */ dev->flags |= IFF_NOARP;#ifndef LINUX_20 dev->hard_header_cache = NULL; #endif #ifdef LINUX_24 SET_MODULE_OWNER(dev);#endif dev->priv = kmalloc(sizeof(struct ednet_priv), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; memset(dev->priv, 0, sizeof(struct ednet_priv)); spin_lock_init(& ((struct ednet_priv *) dev->priv)->lock); return 0;}struct file_operations ed_ops ={#ifdef LINUX_24 NULL,#endif NULL, device_read, device_write, NULL, NULL, device_ioctl, NULL, device_open, NULL, device_release, };/* initialize the character devices */int eddev_module_init(void){ int err; int i; if((err=device_init()) != 0) { printk("Init device error:"); return err; } err = register_chrdev(MAJOR_NUM_REC,ed[ED_REC_DEVICE].name,&ed_ops); if( err != 0) printk("Install the buffer rec device %s fail", ED_REC_DEVICE_NAME); for(i=0; i<2;i++) ed[i].kernel_write = kernel_write; err = register_chrdev(MAJOR_NUM_TX,ed[ED_TX_DEVICE].name,&ed_ops); if( err != 0) printk("Install the buffer tx device %s fail",ED_TX_DEVICE_NAME); return err; }/* clean up the character devices */void eddev_module_cleanup(void){ int err; int i; for (i = 0 ;i < 2; i++){ kfree(ed[i].buffer); } err = unregister_chrdev(MAJOR_NUM_REC,ed[ED_REC_DEVICE].name); if(err != 0) printk("UnInstall the buffer recieve device %s fail",ED_REC_DEVICE_NAME); err = unregister_chrdev(MAJOR_NUM_TX,ed[ED_TX_DEVICE].name); if(err != 0) printk("UnInstall the buffer recieve device %s fail",ED_TX_DEVICE_NAME); }int ednet_module_init(void){ int err; strcpy(ednet_dev.name, "ed0"); ednet_dev.init = ednet_init; if ( (err = register_netdev(&ednet_dev)) ) printk("ednet: error %i registering pseudo network device \"%s\"\n", err, ednet_dev.name); return err;}void ednet_module_cleanup(void){ kfree(ednet_dev.priv); unregister_netdev(&ednet_dev); return;}/* called by the kernel to setup the module*/int init_module(void){ int err; err = eddev_module_init(); if(err < 0) return err; err = ednet_module_init(); if(err < 0) return err; return err; }/* cleanup the module */void cleanup_module(){ eddev_module_cleanup(); ednet_module_cleanup(); }#ifdef LINUX_24MODULE_LICENSE("GPL");#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -