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

📄 sdla_fr.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
	u.cfg.kbps	= conf->bps / 1000;    	u.cfg.cir_fwd = u.cfg.cir_bwd = 16;        u.cfg.bc_fwd  = u.cfg.bc_bwd = 16;		u.cfg.options	= 0x0000;	printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname);		switch (conf->u.fr.signalling) {		case WANOPT_FR_ANSI:			u.cfg.options = 0x0000; 			break;					case WANOPT_FR_Q933:				u.cfg.options |= 0x0200; 			break;			case WANOPT_FR_LMI:				u.cfg.options |= 0x0400; 			break;		case WANOPT_NO:			u.cfg.options |= 0x0800; 			break;		default:			printk(KERN_INFO "%s: Illegal Signalling option\n",					card->wandev.name);			return -EINVAL;	}	card->wandev.signalling = conf->u.fr.signalling;	if (conf->station == WANOPT_CPE) {		if (conf->u.fr.signalling == WANOPT_NO){			printk(KERN_INFO 				"%s: ERROR - For NO signalling, station must be set to Node!",				 	 card->devname);			return -EINVAL;		}		u.cfg.station = 0;		u.cfg.options |= 0x8000;	/* auto config DLCI */		card->u.f.dlci_num  = 0;		} else {		u.cfg.station = 1;	/* switch emulation mode */		/* For switch emulation we have to create a list of dlci(s)		 * that will be sent to be global SET_DLCI_CONFIGURATION 		 * command in fr_configure() routine. 		 */		card->u.f.dlci_num  = min(max(conf->u.fr.dlci_num, 1), 100);			for ( i = 0; i < card->u.f.dlci_num; i++) {			card->u.f.node_dlci[i] = (unsigned short) 				conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16;			}	}	if (conf->clocking == WANOPT_INTERNAL)		u.cfg.port |= 0x0001;	if (conf->interface == WANOPT_RS232)		u.cfg.port |= 0x0002;	if (conf->u.fr.t391)		u.cfg.t391 = min(conf->u.fr.t391, 30);	else		u.cfg.t391 = 5;	if (conf->u.fr.t392)		u.cfg.t392 = min(conf->u.fr.t392, 30);	else		u.cfg.t392 = 15;	if (conf->u.fr.n391)		u.cfg.n391 = min(conf->u.fr.n391, 255);	else		u.cfg.n391 = 2;	if (conf->u.fr.n392)		u.cfg.n392 = min(conf->u.fr.n392, 10);	else		u.cfg.n392 = 3;		if (conf->u.fr.n393)		u.cfg.n393 = min(conf->u.fr.n393, 10);	else		u.cfg.n393 = 4;	if (fr_configure(card, &u.cfg))		return -EIO;	if (card->hw.type == SDLA_S514) {	                buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR +			FR508_RXBC_OFFS);                card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase);                card->u.f.rxmb_base =                        (void*)(buf_info->rse_base + card->hw.dpmbase);                 card->u.f.rxmb_last =                        (void*)(buf_info->rse_base +                        (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) +                        card->hw.dpmbase);	}	else {			buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS);		card->rxmb = (void*)(buf_info->rse_next -			FR_MB_VECTOR + card->hw.dpmbase);				card->u.f.rxmb_base =			(void*)(buf_info->rse_base -			FR_MB_VECTOR + card->hw.dpmbase);				card->u.f.rxmb_last =			(void*)(buf_info->rse_base +			(buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) -			FR_MB_VECTOR + card->hw.dpmbase);	}	card->u.f.rx_base = buf_info->buf_base;	card->u.f.rx_top  = buf_info->buf_top;	card->u.f.tx_interrupts_pending = 0;	card->wandev.mtu	= conf->mtu;	card->wandev.bps	= conf->bps;	card->wandev.interface	= conf->interface;	card->wandev.clocking	= conf->clocking;	card->wandev.station	= conf->station;	card->poll		= NULL; 	card->exec		= &wpf_exec;	card->wandev.update	= &update;	card->wandev.new_if	= &new_if;	card->wandev.del_if	= &del_if;	card->wandev.state	= WAN_DISCONNECTED;	card->wandev.ttl	= conf->ttl;        card->wandev.udp_port 	= conf->udp_port;       	/* Intialize global statistics for a card */	init_global_statistics( card );        card->TracingEnabled          = 0;	/* Interrupt Test */	Intr_test_counter = 0;	card->intr_mode = INTR_TEST_MODE;	err = intr_test( card );	if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {		printk( 			"%s: Interrupt Test Failed, Counter: %i\n", 			card->devname, Intr_test_counter);		printk( "Please choose another interrupt\n");		err = -EIO;		return err;	}	printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n",			card->devname, Intr_test_counter);        return 0;}/******* WAN Device Driver Entry Points *************************************//*============================================================================ * Update device status & statistics. */static int update (wan_device_t* wandev){	volatile sdla_t* card;	unsigned long timeout;	fr508_flags_t* flags;	/* sanity checks */	if ((wandev == NULL) || (wandev->private == NULL))		return -EFAULT;	if (wandev->state == WAN_UNCONFIGURED)		return -ENODEV;	if (test_bit(1, (void*)&wandev->critical))		return -EAGAIN;	card = wandev->private;	flags = card->flags;	card->u.f.update_comms_stats = 1;	card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE;	flags->imask |= FR_INTR_TIMER;       	timeout = jiffies;       	for(;;) {		if(card->u.f.update_comms_stats == 0)			break;                if ((jiffies - timeout) > (1 * HZ)){    			card->u.f.update_comms_stats = 0; 			return -EAGAIN;		}        }	return 0;}/*============================================================================ * Create new logical channel. * This routine is called by the router when ROUTER_IFNEW IOCTL is being * handled. * o parse media- and hardware-specific configuration * o make sure that a new channel can be created * o allocate resources, if necessary * o prepare network device structure for registaration. * * Return:	0	o.k. *		< 0	failure (channel will not be created) */static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf){	sdla_t* card = wandev->private;	fr_channel_t* chan;	int dlci = 0;	int err = 0;		if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {				printk(KERN_INFO "%s: invalid interface name!\n",			card->devname);		return -EINVAL;	}	/* allocate and initialize private data */	chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL);	if (chan == NULL)		return -ENOMEM;	memset(chan, 0, sizeof(fr_channel_t));	strcpy(chan->name, conf->name);	chan->card = card; 	/* verify media address */	if (is_digit(conf->addr[0])) {		dlci = dec_to_uint(conf->addr, 0);		if (dlci && (dlci <= HIGHEST_VALID_DLCI)) {					chan->dlci = dlci;				} else {					printk(KERN_ERR				"%s: invalid DLCI %u on interface %s!\n",				wandev->name, dlci, chan->name);			err = -EINVAL;		}	} else {		printk(KERN_ERR			"%s: invalid media address on interface %s!\n",			wandev->name, chan->name);		err = -EINVAL;	}        /* Setup wanpipe as a router (WANPIPE) or as an API */        if(strcmp(conf->usedby, "WANPIPE") == 0){                printk(KERN_INFO "%s: Running in WANPIPE mode %s\n",			wandev->name, chan->name);                chan->usedby = WANPIPE;        } else if(strcmp(conf->usedby, "API") == 0){#ifdef FRAME_RELAY_API                chan->usedby = API;                printk(KERN_INFO "%s: Running in API mode %s\n",			wandev->name, chan->name);#else                printk(KERN_INFO "%s: API Mode is not supported !\n",			wandev->name);                printk(KERN_INFO			"%s: API patch can be obtained from Sangoma Tech.\n",                        	wandev->name);                err = -EINVAL;#endif        }	if (err) {				kfree(chan);		return err;	}	card->u.f.dlci_to_dev_map[dlci] = dev; 	/* place cir,be,bc and other channel specific information into the	 * chan structure          */	if (conf->cir) {		chan->cir = max( 1, min( conf->cir, 512 ) );		chan->cir_status = CIR_ENABLED; 				/* If CIR is enabled, force BC to equal CIR                 * this solves number of potential problems if CIR is                  * set and BC is not 		 */		chan->bc = chan->cir;		if (conf->be){			chan->be = max( 0, min( conf->be, 511) ); 		}else{				conf->be = 0;		}		printk (KERN_INFO "%s: CIR enabled for DLCI %i \n",				wandev->name,chan->dlci);		printk (KERN_INFO "%s:     CIR = %i ; BC = %i ; BE = %i\n",				wandev->name,chan->cir,chan->bc,chan->be);	}else{		chan->cir_status = CIR_DISABLED;		printk (KERN_INFO "%s: CIR disabled for DLCI %i\n",				wandev->name,chan->dlci);	}	chan->mc = conf->mc;	/* FIXME: ARP is not supported by this frame relay verson */	if (conf->inarp == WANOPT_YES){		printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support ARPs\n",				card->devname);			//chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE;		//chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10;		kfree(chan);		return -EINVAL;	}else{		chan->inarp = INARP_NONE;		chan->inarp_interval = 10;	}	chan->dlci_configured = DLCI_NOT_CONFIGURED;		/*FIXME: IPX disabled in this WANPIPE version */	if (conf->enable_IPX == WANOPT_YES){		printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n",				card->devname);		kfree(chan);		return -EINVAL;	}else{		chan->enable_IPX = WANOPT_NO;	}		if (conf->network_number){		chan->network_number = conf->network_number;	}else{		chan->network_number = 0xDEADBEEF;	}	chan->route_flag = NO_ROUTE;		init_chan_statistics(chan);	chan->transmit_length = 0;	/* prepare network device data space for registration */	strcpy(dev->name, chan->name);	dev->init = &if_init;	dev->priv = chan;	/* Enable Interrupts and Communications */	if (!wandev->new_if_cnt){		fr508_flags_t* flags = card->flags;		wandev->new_if_cnt++;		/* 		If you enable comms and then set ints, you get a Tx int as you		perform the SET_INT_TRIGGERS command. So, we only set int		triggers and then adjust the interrupt mask (to disable Tx ints)		before enabling comms. 		*/	                if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY |			FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) ,			card->wandev.mtu, 0)) {			kfree(chan);			return -EIO;		}		flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER); 		if (fr_comm_enable(card)) {			kfree(chan);			return -EIO;		}			wanpipe_set_state(card, WAN_CONNECTED);	}	return 0;}/*============================================================================ * Delete logical channel. */static int del_if (wan_device_t* wandev, struct net_device* dev){	sdla_t *card = wandev->private;	/* Execute shutdown very first time we enter del_if */	if (!wandev->del_if_cnt) {		wandev->del_if_cnt++;		wanpipe_set_state(card, WAN_DISCONNECTED);		fr_set_intr_mode(card, 0, 0, 0);		fr_comm_disable(card);

⌨️ 快捷键说明

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