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

📄 lec.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
lec_vcc_attach(struct atm_vcc *vcc, void *arg){        int bytes_left;        struct atmlec_ioc ioc_data;        /* Lecd must be up in this case */        bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));        if (bytes_left != 0) {                printk("lec: lec_vcc_attach, copy from user failed for %d bytes\n",                       bytes_left);        }        if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||             !dev_lec[ioc_data.dev_num])                return -EINVAL;        lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,                       &ioc_data, vcc, vcc->push);        vcc->push = lec_push;        vcc->proto_data = dev_lec[ioc_data.dev_num];        return 0;}int lec_mcast_attach(struct atm_vcc *vcc, int arg){        if (arg <0 || arg >= MAX_LEC_ITF || !dev_lec[arg])                return -EINVAL;        vcc->proto_data = dev_lec[arg];        return (lec_mcast_make((struct lec_priv*)dev_lec[arg]->priv, vcc));}/* Initialize device. */int lecd_attach(struct atm_vcc *vcc, int arg){          int i;        struct lec_priv *priv;        if (arg<0)                i = 0;        else                i = arg;#ifdef CONFIG_TR        if (arg >= MAX_LEC_ITF)                return -EINVAL;#else /* Reserve the top NUM_TR_DEVS for TR */        if (arg >= (MAX_LEC_ITF-NUM_TR_DEVS))                return -EINVAL;#endif        if (!dev_lec[i]) {                int is_trdev, size;                is_trdev = 0;                if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))                        is_trdev = 1;                size = sizeof(struct lec_priv);#ifdef CONFIG_TR                if (is_trdev)                        dev_lec[i] = init_trdev(NULL, size);                else#endif                dev_lec[i] = init_etherdev(NULL, size);                if (!dev_lec[i])                        return -ENOMEM;                priv = dev_lec[i]->priv;                priv->is_trdev = is_trdev;                sprintf(dev_lec[i]->name, "lec%d", i);                lec_init(dev_lec[i]);        } else {                priv = dev_lec[i]->priv;                if (priv->lecd)                        return -EADDRINUSE;        }        lec_arp_init(priv);	priv->itfnum = i;  /* LANE2 addition */        priv->lecd = vcc;        bind_vcc(vcc, &lecatm_dev);                vcc->proto_data = dev_lec[i];	set_bit(ATM_VF_META,&vcc->flags);	set_bit(ATM_VF_READY,&vcc->flags);        /* Set default values to these variables */        priv->maximum_unknown_frame_count = 1;        priv->max_unknown_frame_time = (1*HZ);        priv->vcc_timeout_period = (1200*HZ);        priv->max_retry_count = 1;        priv->aging_time = (300*HZ);        priv->forward_delay_time = (15*HZ);        priv->topology_change = 0;        priv->arp_response_time = (1*HZ);        priv->flush_timeout = (4*HZ);        priv->path_switching_delay = (6*HZ);        if (dev_lec[i]->flags & IFF_UP) {                netif_start_queue(dev_lec[i]);        }        MOD_INC_USE_COUNT;        return i;}void atm_lane_init_ops(struct atm_lane_ops *ops){        ops->lecd_attach = lecd_attach;        ops->mcast_attach = lec_mcast_attach;        ops->vcc_attach = lec_vcc_attach;        ops->get_lecs = get_dev_lec;        printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");	return;}static int __init lane_module_init(void){        extern struct atm_lane_ops atm_lane_ops;        atm_lane_init_ops(&atm_lane_ops);        return 0;}static void __exit lane_module_cleanup(void){        int i;        extern struct atm_lane_ops atm_lane_ops;        struct lec_priv *priv;        atm_lane_ops.lecd_attach = NULL;        atm_lane_ops.mcast_attach = NULL;        atm_lane_ops.vcc_attach = NULL;        atm_lane_ops.get_lecs = NULL;        for (i = 0; i < MAX_LEC_ITF; i++) {                if (dev_lec[i] != NULL) {                        priv = (struct lec_priv *)dev_lec[i]->priv;#if defined(CONFIG_TR)                	if (priv->is_trdev)                        	unregister_trdev(dev_lec[i]);                	else#endif                        unregister_netdev(dev_lec[i]);                        kfree(dev_lec[i]);                        dev_lec[i] = NULL;                }        }        return;                                    }module_init(lane_module_init);module_exit(lane_module_cleanup);/* * LANE2: 3.1.3, LE_RESOLVE.request * Non force allocates memory and fills in *tlvs, fills in *sizeoftlvs. * If sizeoftlvs == NULL the default TLVs associated with with this * lec will be used. * If dst_mac == NULL, targetless LE_ARP will be sent */static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,    u8 **tlvs, u32 *sizeoftlvs){        struct lec_priv *priv = (struct lec_priv *)dev->priv;        struct lec_arp_table *table;        struct sk_buff *skb;        int retval;        if (force == 0) {                table = lec_arp_find(priv, dst_mac);                if(table == NULL)                        return -1;                                *tlvs = kmalloc(table->sizeoftlvs, GFP_KERNEL);                if (*tlvs == NULL)                        return -1;                                memcpy(*tlvs, table->tlvs, table->sizeoftlvs);                *sizeoftlvs = table->sizeoftlvs;                                return 0;        }	if (sizeoftlvs == NULL)		retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);			else {		skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);		if (skb == NULL)			return -1;		skb->len = *sizeoftlvs;		memcpy(skb->data, *tlvs, *sizeoftlvs);		retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);	}        return retval;}        /* * LANE2: 3.1.4, LE_ASSOCIATE.request * Associate the *tlvs with the *lan_dst address. * Will overwrite any previous association * Returns 1 for success, 0 for failure (out of memory) * */static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,                         u8 *tlvs, u32 sizeoftlvs){        int retval;        struct sk_buff *skb;        struct lec_priv *priv = (struct lec_priv*)dev->priv;        if ( memcmp(lan_dst, dev->dev_addr, ETH_ALEN) != 0 )                return (0);       /* not our mac address */        kfree(priv->tlvs); /* NULL if there was no previous association */        priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);        if (priv->tlvs == NULL)                return (0);        priv->sizeoftlvs = sizeoftlvs;        memcpy(priv->tlvs, tlvs, sizeoftlvs);        skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);        if (skb == NULL)                return 0;        skb->len = sizeoftlvs;        memcpy(skb->data, tlvs, sizeoftlvs);        retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);        if (retval != 0)                printk("lec.c: lane2_associate_req() failed\n");        /* If the previous association has changed we must         * somehow notify other LANE entities about the change         */        return (1);}/* * LANE2: 3.1.5, LE_ASSOCIATE.indication * */static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,    u8 *tlvs, u32 sizeoftlvs){#if 0        int i = 0;#endif	struct lec_priv *priv = (struct lec_priv *)dev->priv;#if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you         uncomment this code, make sure the TLVs get freed when entry is killed */        struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);        if (entry == NULL)                return;     /* should not happen */        kfree(entry->tlvs);        entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);        if (entry->tlvs == NULL)                return;        entry->sizeoftlvs = sizeoftlvs;        memcpy(entry->tlvs, tlvs, sizeoftlvs);#endif#if 0        printk("lec.c: lane2_associate_ind()\n");        printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);        while (i < sizeoftlvs)                printk("%02x ", tlvs[i++]);                printk("\n");#endif        /* tell MPOA about the TLVs we saw */        if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {                priv->lane2_ops->associate_indicator(dev, mac_addr,                                                     tlvs, sizeoftlvs);        }        return;}/* * Here starts what used to lec_arpc.c * * lec_arpc.c was added here when making * lane client modular. October 1997 * */#include <linux/types.h>#include <linux/sched.h>#include <linux/timer.h>#include <asm/param.h>#include <asm/atomic.h>#include <linux/inetdevice.h>#include <net/route.h>#if 0#define DPRINTK(format,args...)/*#define DPRINTK printk*/#endif#define DEBUG_ARP_TABLE 0#define LEC_ARP_REFRESH_INTERVAL (3*HZ)static void lec_arp_check_expire(unsigned long data);static __inline__ void lec_arp_expire_arp(unsigned long data);void dump_arp_table(struct lec_priv *priv);/*  * Arp table funcs */#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))static __inline__ void lec_arp_lock(struct lec_priv *priv){        atomic_inc(&priv->lec_arp_lock_var);}static __inline__ void lec_arp_unlock(struct lec_priv *priv){        atomic_dec(&priv->lec_arp_lock_var);}/* * Initialization of arp-cache */void lec_arp_init(struct lec_priv *priv){        unsigned short i;        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {                priv->lec_arp_tables[i] = NULL;        }                init_timer(&priv->lec_arp_timer);        priv->lec_arp_timer.expires = jiffies+LEC_ARP_REFRESH_INTERVAL;        priv->lec_arp_timer.data = (unsigned long)priv;        priv->lec_arp_timer.function = lec_arp_check_expire;        add_timer(&priv->lec_arp_timer);}voidlec_arp_clear_vccs(struct lec_arp_table *entry){        if (entry->vcc) {                entry->vcc->push = entry->old_push;#if 0 /* August 6, 1998 */                set_bit(ATM_VF_RELEASED,&entry->vcc->flags);		clear_bit(ATM_VF_READY,&entry->vcc->flags);                entry->vcc->push(entry->vcc, NULL);#endif		atm_async_release_vcc(entry->vcc, -EPIPE);                entry->vcc = NULL;        }        if (entry->recv_vcc) {

⌨️ 快捷键说明

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