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

📄 lec.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
                atomic_add(skb->truesize, &send_vcc->tx_inuse);                priv->stats.tx_packets++;                priv->stats.tx_bytes += skb->len;                send_vcc->send(send_vcc, skb);        } else {                priv->stats.tx_dropped++;                dev_kfree_skb(skb);	}#if 0        /* Should we wait for card's device driver to notify us? */        dev->tbusy=0;#endif                return 0;}/* The inverse routine to net_open(). */static int lec_close(struct net_device *dev) {        netif_stop_queue(dev);        return 0;}/* * Get the current statistics. * This may be called with the card open or closed. */static struct net_device_stats *lec_get_stats(struct net_device *dev){        return &((struct lec_priv *)dev->priv)->stats;}static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb){        struct net_device *dev = (struct net_device*)vcc->proto_data;        struct lec_priv *priv = (struct lec_priv*)dev->priv;        struct atmlec_msg *mesg;        struct lec_arp_table *entry;        int i;        char *tmp; /* FIXME */	atomic_sub(skb->truesize+ATM_PDU_OVHD, &vcc->tx_inuse);        mesg = (struct atmlec_msg *)skb->data;        tmp = skb->data;        tmp += sizeof(struct atmlec_msg);        DPRINTK("%s: msg from zeppelin:%d\n", dev->name, mesg->type);        switch(mesg->type) {        case l_set_mac_addr:                for (i=0;i<6;i++) {                        dev->dev_addr[i] = mesg->content.normal.mac_addr[i];                }                    break;        case l_del_mac_addr:                for(i=0;i<6;i++) {                        dev->dev_addr[i] = 0;                }                break;        case l_addr_delete:                lec_addr_delete(priv, mesg->content.normal.atm_addr,                                 mesg->content.normal.flag);                break;        case l_topology_change:                priv->topology_change = mesg->content.normal.flag;                  break;        case l_flush_complete:                lec_flush_complete(priv, mesg->content.normal.flag);                break;        case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */                entry = lec_arp_find(priv, mesg->content.normal.mac_addr);                lec_arp_remove(priv->lec_arp_tables, entry);                if (mesg->content.normal.no_source_le_narp)                        break;                /* FALL THROUGH */        case l_arp_update:                lec_arp_update(priv, mesg->content.normal.mac_addr,                               mesg->content.normal.atm_addr,                               mesg->content.normal.flag,                               mesg->content.normal.targetless_le_arp);                DPRINTK("lec: in l_arp_update\n");                if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */                        DPRINTK("lec: LANE2 3.1.5, got tlvs, size %d\n", mesg->sizeoftlvs);                        lane2_associate_ind(dev,                                            mesg->content.normal.mac_addr,                                            tmp, mesg->sizeoftlvs);                }                break;        case l_config:                priv->maximum_unknown_frame_count =                         mesg->content.config.maximum_unknown_frame_count;                priv->max_unknown_frame_time =                         (mesg->content.config.max_unknown_frame_time*HZ);                priv->max_retry_count =                         mesg->content.config.max_retry_count;                priv->aging_time = (mesg->content.config.aging_time*HZ);                priv->forward_delay_time =                         (mesg->content.config.forward_delay_time*HZ);                priv->arp_response_time =                         (mesg->content.config.arp_response_time*HZ);                priv->flush_timeout = (mesg->content.config.flush_timeout*HZ);                priv->path_switching_delay =                         (mesg->content.config.path_switching_delay*HZ);                priv->lane_version = mesg->content.config.lane_version; /* LANE2 */		priv->lane2_ops = NULL;		if (priv->lane_version > 1)			priv->lane2_ops = &lane2_ops;		if (dev->change_mtu(dev, mesg->content.config.mtu))			printk("%s: change_mtu to %d failed\n", dev->name,			    mesg->content.config.mtu);		priv->is_proxy = mesg->content.config.is_proxy;                break;        case l_flush_tran_id:                lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,                                      mesg->content.normal.flag);                break;        case l_set_lecid:                priv->lecid=(unsigned short)(0xffff&mesg->content.normal.flag);                break;        case l_should_bridge: {#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)                struct net_bridge_fdb_entry *f;                DPRINTK("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n",                        dev->name,                        mesg->content.proxy.mac_addr[0], mesg->content.proxy.mac_addr[1],                        mesg->content.proxy.mac_addr[2], mesg->content.proxy.mac_addr[3],                        mesg->content.proxy.mac_addr[4], mesg->content.proxy.mac_addr[5]);                if (br_fdb_get_hook == NULL || dev->br_port == NULL)                        break;                f = br_fdb_get_hook(dev->br_port->br, mesg->content.proxy.mac_addr);                if (f != NULL &&                    f->dst->dev != dev &&                    f->dst->state == BR_STATE_FORWARDING) {                                /* hit from bridge table, send LE_ARP_RESPONSE */                        struct sk_buff *skb2;                        DPRINTK("%s: entry found, responding to zeppelin\n", dev->name);                        skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);                        if (skb2 == NULL) {                                br_fdb_put_hook(f);                                break;                        }                        skb2->len = sizeof(struct atmlec_msg);                        memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));                        atm_force_charge(priv->lecd, skb2->truesize);                        skb_queue_tail(&priv->lecd->recvq, skb2);                        wake_up(&priv->lecd->sleep);                }                if (f != NULL) br_fdb_put_hook(f);#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */                }                break;        default:                printk("%s: Unknown message type %d\n", dev->name, mesg->type);                dev_kfree_skb(skb);                return -EINVAL;        }        dev_kfree_skb(skb);        return 0;}static void lec_atm_close(struct atm_vcc *vcc){        struct sk_buff *skb;        struct net_device *dev = (struct net_device *)vcc->proto_data;        struct lec_priv *priv = (struct lec_priv *)dev->priv;        priv->lecd = NULL;        /* Do something needful? */        netif_stop_queue(dev);        lec_arp_destroy(priv);        if (skb_peek(&vcc->recvq))		printk("%s lec_atm_close: closing with messages pending\n",                       dev->name);        while ((skb = skb_dequeue(&vcc->recvq))) {                atm_return(vcc, skb->truesize);		dev_kfree_skb(skb);        }  	printk("%s: Shut down!\n", dev->name);        MOD_DEC_USE_COUNT;}static struct atmdev_ops lecdev_ops = {        close:	lec_atm_close,        send:	lec_atm_send};static struct atm_dev lecatm_dev = {        &lecdev_ops,        NULL,	    /*PHY*/        "lec",	    /*type*/        999,	    /*dummy device number*/        NULL,NULL,  /*no VCCs*/        NULL,NULL,  /*no data*/        { 0 },	    /*no flags*/        NULL,	    /* no local address*/        { 0 }	    /*no ESI or rest of the atm_dev struct things*/};/* * LANE2: new argument struct sk_buff *data contains * the LE_ARP based TLVs introduced in the LANE2 spec */int send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,              unsigned char *mac_addr, unsigned char *atm_addr,             struct sk_buff *data){	struct sk_buff *skb;	struct atmlec_msg *mesg;	if (!priv || !priv->lecd) {		return -1;	}	skb = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);	if (!skb)		return -1;	skb->len = sizeof(struct atmlec_msg);	mesg = (struct atmlec_msg *)skb->data;        memset(mesg, 0, sizeof(struct atmlec_msg));	mesg->type = type;        if (data != NULL)                mesg->sizeoftlvs = data->len;	if (mac_addr)		memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN);        else                mesg->content.normal.targetless_le_arp = 1;	if (atm_addr)		memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);        atm_force_charge(priv->lecd, skb->truesize);	skb_queue_tail(&priv->lecd->recvq, skb);        wake_up(&priv->lecd->sleep);        if (data != NULL) {                DPRINTK("lec: about to send %d bytes of data\n", data->len);                atm_force_charge(priv->lecd, data->truesize);                skb_queue_tail(&priv->lecd->recvq, data);                wake_up(&priv->lecd->sleep);        }        return 0;}/* shamelessly stolen from drivers/net/net_init.c */static int lec_change_mtu(struct net_device *dev, int new_mtu){        if ((new_mtu < 68) || (new_mtu > 18190))                return -EINVAL;        dev->mtu = new_mtu;        return 0;}static void lec_init(struct net_device *dev){        dev->change_mtu = lec_change_mtu;        dev->open = lec_open;        dev->stop = lec_close;        dev->hard_start_xmit = lec_send_packet;        dev->get_stats = lec_get_stats;        dev->set_multicast_list = NULL;        dev->do_ioctl  = NULL;        printk("%s: Initialized!\n",dev->name);        return;}static unsigned char lec_ctrl_magic[] = {        0xff,        0x00,        0x01,        0x01 };void lec_push(struct atm_vcc *vcc, struct sk_buff *skb){        struct net_device *dev = (struct net_device *)vcc->proto_data;        struct lec_priv *priv = (struct lec_priv *)dev->priv; #if DUMP_PACKETS >0        int i=0;        char buf[300];        printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,               vcc->vpi, vcc->vci);#endif        if (!skb) {                DPRINTK("%s: null skb\n",dev->name);                lec_vcc_close(priv, vcc);                return;        }#if DUMP_PACKETS > 0        printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,               skb->len, priv->lecid);#if DUMP_PACKETS >= 2        for(i=0;i<skb->len && i <99;i++) {                sprintf(buf+i*3,"%2.2x ",0xff&skb->data[i]);        }#elif DUMP_PACKETS >= 1        for(i=0;i<skb->len && i < 30;i++) {                sprintf(buf+i*3,"%2.2x ", 0xff&skb->data[i]);        }#endif /* DUMP_PACKETS >= 1 */        if (i==skb->len)                printk("%s\n",buf);        else                printk("%s...\n",buf);#endif /* DUMP_PACKETS > 0 */        if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/                DPRINTK("%s: To daemon\n",dev->name);                skb_queue_tail(&vcc->recvq, skb);                wake_up(&vcc->sleep);        } else { /* Data frame, queue to protocol handlers */                unsigned char *dst;                atm_return(vcc,skb->truesize);                if (*(uint16_t *)skb->data == htons(priv->lecid) ||                    !priv->lecd) {                         /* Probably looping back, or if lecd is missing,                           lecd has gone down */                        DPRINTK("Ignoring loopback frame...\n");                        dev_kfree_skb(skb);                        return;                }#ifdef CONFIG_TR                if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;                else#endif                dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;                if (!(dst[0]&0x01) &&   /* Never filter Multi/Broadcast */                    !priv->is_proxy &&  /* Proxy wants all the packets */		    memcmp(dst, dev->dev_addr, dev->addr_len)) {                        dev_kfree_skb(skb);                        return;                }                if (priv->lec_arp_empty_ones) {                        lec_arp_check_empties(priv, vcc, skb);                }                skb->dev = dev;                skb->data += 2; /* skip lec_id */#ifdef CONFIG_TR                if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev);                else#endif                skb->protocol = eth_type_trans(skb, dev);                priv->stats.rx_packets++;                priv->stats.rx_bytes += skb->len;                netif_rx(skb);        }}int 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -