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

📄 ed_device.c

📁 linux下利用串口进行网络通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
        printk(KERN_WARNING "ednet: Can't change I/O address\n");        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 + -