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

📄 sdla_chdlc.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
               		max_permitted_baud =				(card->hw.type == SDLA_S514) ?				PRI_MAX_BAUD_RATE_S514 : 				PRI_MAX_BAUD_RATE_S508;		}else if(port_num == WANOPT_SEC) {			/* For Secondary Port 1 */                        max_permitted_baud =                               (card->hw.type == SDLA_S514) ?                                SEC_MAX_BAUD_RATE_S514 :                                SEC_MAX_BAUD_RATE_S508;                        }  			if(conf->bps > max_permitted_baud) {				conf->bps = max_permitted_baud;				printk(KERN_INFO "%s: Baud too high!\n",					card->wandev.name); 				printk(KERN_INFO "%s: Baud rate set to %lu bps\n", 					card->wandev.name, max_permitted_baud);			}			card->wandev.bps = conf->bps;	}else{        	card->wandev.bps = 0;  	}	/* Setup the Port MTU */	if((port_num == WANOPT_PRI) || card->u.c.receive_only) {		/* For Primary Port 0 */		card->wandev.mtu =			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?			min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :			CHDLC_DFLT_DATA_LEN;	} else if(port_num == WANOPT_SEC) { 		/* For Secondary Port 1 */		card->wandev.mtu =			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?			min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :			CHDLC_DFLT_DATA_LEN;	}	/* Set up the interrupt status area */	/* Read the CHDLC Configuration and obtain: 	 *	Ptr to shared memory infor struct         * Use this pointer to calculate the value of card->u.c.flags ! 	 */	mb1->buffer_length = 0;	mb1->command = READ_CHDLC_CONFIGURATION;	err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;	if(err != COMMAND_OK) {                if(card->hw.type != SDLA_S514)                	enable_irq(card->hw.irq);		chdlc_error(card, err, mb1);		return -EIO;	}	if(card->hw.type == SDLA_S514){               	card->u.c.flags = (void *)(card->hw.dpmbase +               		(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->			ptr_shared_mem_info_struct));        }else{                card->u.c.flags = (void *)(card->hw.dpmbase +                        (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->			ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));	}	flags = card->u.c.flags;		/* This is for the ports link state */	card->wandev.state = WAN_DUALPORT;	card->u.c.state = WAN_DISCONNECTED;	if (!card->wandev.piggyback){			int err;		/* Perform interrupt testing */		err = intr_test(card);		if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { 			printk(KERN_INFO "%s: Interrupt test failed (%i)\n",					card->devname, Intr_test_counter);			printk(KERN_INFO "%s: Please choose another interrupt\n",					card->devname);			return -EIO;		}				printk(KERN_INFO "%s: Interrupt test passed (%i)\n", 				card->devname, Intr_test_counter);		card->configured = 1;	}	if ((card->tty_opt=conf->tty) == WANOPT_YES){		int err;		card->tty_minor = conf->tty_minor;		/* On ASYNC connections internal clocking 		 * is mandatory */		if ((card->u.c.async_mode = conf->tty_mode)){			card->wandev.clocking = 1;		}		err=wanpipe_tty_init(card);		if (err){			return err;		}	}else{			if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){			printk (KERN_INFO "%s: "				"Failed to set interrupt triggers!\n",				card->devname);			return -EIO;	        	}			/* Mask the Timer interrupt */		flags->interrupt_info_struct.interrupt_permission &= 			~APP_INT_ON_TIMER;	}	/* If we are using CHDLC in backup mode, this flag will	 * indicate not to look for IP addresses in config_chdlc()*/	card->u.c.backup = conf->backup;		printk(KERN_INFO "\n");	return 0;}/******* WAN Device Driver Entry Points *************************************//*============================================================================ * Update device status & statistics * This procedure is called when updating the PROC file system and returns * various communications statistics. These statistics are accumulated from 3  * different locations: * 	1) The 'if_stats' recorded for the device. * 	2) Communication error statistics on the adapter. *      3) CHDLC operational statistics on the adapter. * The board level statistics are read during a timer interrupt. Note that we  * read the error and operational statistics during consecitive timer ticks so * as to minimize the time that we are inside the interrupt handler. * */static int update(struct wan_device* wandev){	sdla_t* card = wandev->private; 	struct net_device* dev;        volatile chdlc_private_area_t* chdlc_priv_area;        SHARED_MEMORY_INFO_STRUCT *flags;	unsigned long timeout;	/* sanity checks */	if((wandev == NULL) || (wandev->private == NULL))		return -EFAULT;		if(wandev->state == WAN_UNCONFIGURED)		return -ENODEV;	/* more sanity checks */        if(!card->u.c.flags)                return -ENODEV;	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical))                return -EAGAIN;	if((dev=card->wandev.dev) == NULL)		return -ENODEV;	if((chdlc_priv_area=dev->priv) == NULL)		return -ENODEV;      	flags = card->u.c.flags;       	if(chdlc_priv_area->update_comms_stats){		return -EAGAIN;	}				/* we will need 2 timer interrupts to complete the */	/* reading of the statistics */	chdlc_priv_area->update_comms_stats = 2;       	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;	chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;  	/* wait a maximum of 1 second for the statistics to be updated */         timeout = jiffies;        for(;;) {		if(chdlc_priv_area->update_comms_stats == 0)			break;                if ((jiffies - timeout) > (1 * HZ)){    			chdlc_priv_area->update_comms_stats = 0; 			chdlc_priv_area->timer_int_enabled &=				~TMR_INT_ENABLED_UPDATE;  			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(struct wan_device* wandev, struct net_device* dev,		  wanif_conf_t* conf){	sdla_t* card = wandev->private;	chdlc_private_area_t* chdlc_priv_area;	printk(KERN_INFO "%s: Configuring Interface: %s\n",			card->devname, conf->name); 	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 */	chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);		if(chdlc_priv_area == NULL) 		return -ENOMEM;	memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));	chdlc_priv_area->card = card; 	chdlc_priv_area->common.sk = NULL;	chdlc_priv_area->common.func = NULL;		/* initialize data */	strcpy(card->u.c.if_name, conf->name);	if(card->wandev.new_if_cnt > 0) {                kfree(chdlc_priv_area);		return -EEXIST;	}	card->wandev.new_if_cnt++;	chdlc_priv_area->TracingEnabled = 0;	chdlc_priv_area->route_status = NO_ROUTE;	chdlc_priv_area->route_removed = 0;	card->u.c.async_mode = conf->async_mode;		/* setup for asynchronous mode */	if(conf->async_mode) {		printk(KERN_INFO "%s: Configuring for asynchronous mode\n",			wandev->name);		if(card->u.c.comm_port == WANOPT_PRI) {			printk(KERN_INFO				"%s:Asynchronous mode on secondary port only\n",					wandev->name);			kfree(chdlc_priv_area);			return -EINVAL;		}	       	if(strcmp(conf->usedby, "WANPIPE") == 0) {			printk(KERN_INFO                                "%s: Running in WANIPE Async Mode\n",                                        			wandev->name);			card->u.c.usedby = WANPIPE;		}else{			card->u.c.usedby = API;		}		if(!card->wandev.clocking) {			printk(KERN_INFO				"%s: Asynch. clocking must be 'Internal'\n",				wandev->name);			kfree(chdlc_priv_area);			return -EINVAL;		}		if((card->wandev.bps < MIN_ASY_BAUD_RATE) ||			(card->wandev.bps > MAX_ASY_BAUD_RATE)) {			printk(KERN_INFO "%s: Selected baud rate is invalid.\n",				wandev->name);			printk(KERN_INFO "Must be between %u and %u bps.\n",				MIN_ASY_BAUD_RATE, MAX_ASY_BAUD_RATE);			kfree(chdlc_priv_area);			return -EINVAL;		}		card->u.c.api_options = 0;                if (conf->asy_data_trans == WANOPT_YES) {                        card->u.c.api_options |= ASY_RX_DATA_TRANSPARENT;                }				card->u.c.protocol_options = 0;		if (conf->rts_hs_for_receive == WANOPT_YES) {			card->u.c.protocol_options |= ASY_RTS_HS_FOR_RX;	        }                if (conf->xon_xoff_hs_for_receive == WANOPT_YES) {                        card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_RX;                }                if (conf->xon_xoff_hs_for_transmit == WANOPT_YES) {                        card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_TX;                }                if (conf->dcd_hs_for_transmit == WANOPT_YES) {                        card->u.c.protocol_options |= ASY_DCD_HS_FOR_TX;                }                if (conf->cts_hs_for_transmit == WANOPT_YES) {                        card->u.c.protocol_options |= ASY_CTS_HS_FOR_TX;                }		card->u.c.tx_bits_per_char = conf->tx_bits_per_char;                card->u.c.rx_bits_per_char = conf->rx_bits_per_char;                card->u.c.stop_bits = conf->stop_bits;		card->u.c.parity = conf->parity;		card->u.c.break_timer = conf->break_timer;		card->u.c.inter_char_timer = conf->inter_char_timer;		card->u.c.rx_complete_length = conf->rx_complete_length;		card->u.c.xon_char = conf->xon_char;	} else {	/* setup for synchronous mode */		card->u.c.protocol_options = 0;		if (conf->ignore_dcd == WANOPT_YES){			card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT;		}		if (conf->ignore_cts == WANOPT_YES){			card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT;		}		if (conf->ignore_keepalive == WANOPT_YES) {			card->u.c.protocol_options |=				IGNORE_KPALV_FOR_LINK_STAT;			card->u.c.kpalv_tx  = MIN_Tx_KPALV_TIMER; 			card->u.c.kpalv_rx  = MIN_Rx_KPALV_TIMER; 			card->u.c.kpalv_err = MIN_KPALV_ERR_TOL; 		} else {   /* Do not ignore keepalives */			card->u.c.kpalv_tx =				((conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER)				>= 0) ?	   			min_t(unsigned int, conf->keepalive_tx_tmr,MAX_Tx_KPALV_TIMER) :				DEFAULT_Tx_KPALV_TIMER;			card->u.c.kpalv_rx =		   		((conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER)				>= 0) ?	   			min_t(unsigned int, conf->keepalive_rx_tmr,MAX_Rx_KPALV_TIMER) :				DEFAULT_Rx_KPALV_TIMER;			card->u.c.kpalv_err =		   		((conf->keepalive_err_margin-MIN_KPALV_ERR_TOL)				>= 0) ?	   			min_t(unsigned int, conf->keepalive_err_margin,				MAX_KPALV_ERR_TOL) : 	   			DEFAULT_KPALV_ERR_TOL;		}		/* Setup slarp timer to control delay between slarps */		card->u.c.slarp_timer = 			((conf->slarp_timer - MIN_SLARP_REQ_TIMER) >= 0) ?			min_t(unsigned int, conf->slarp_timer, MAX_SLARP_REQ_TIMER) :			DEFAULT_SLARP_REQ_TIMER;		if (conf->hdlc_streaming == WANOPT_YES) {			printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n",				wandev->name);			card->u.c.protocol_options = HDLC_STREAMING_MODE;		}		if ((chdlc_priv_area->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){			printk(KERN_INFO 				"%s: Enabling, true interface type encoding.\n",				card->devname);		}		        	/* Setup wanpipe as a router (WANPIPE) or as an API */		if( strcmp(conf->usedby, "WANPIPE") == 0) {			printk(KERN_INFO "%s: Running in WANPIPE mode!\n",				wandev->name);			card->u.c.usedby = WANPIPE;			/* Option to bring down the interface when         		 * the link goes down */			if (conf->if_down){				set_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down);				printk(KERN_INFO 				 "%s: Dynamic interface configuration enabled\n",				   card->devname);			} 		} else if( strcmp(conf->usedby, "API") == 0) {			card->u.c.usedby = API;			printk(KERN_INFO "%s: Running in API mode !\n",				wandev->name);		}	}	/* Tells us that if this interface is a         * gateway or not */	if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){		printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",			card->devname,card->u.c.if_name);	}	/* Get Multicast Information */	chdlc_priv_area->mc = conf->mc;	/* prepare network device data space for registration */	strcpy(dev->name,card->u.c.if_name);	dev->init = &if_init;	dev->priv = chdlc_priv_area;	/* Initialize the polling work routine */	INIT_WORK(&chdlc_priv_area->poll_work, (void*)(void*)chdlc_poll, dev);	/* Initialize the polling delay timer */	init_timer(&chdlc_priv_area->poll_delay_timer);	chdlc_priv_area->poll_delay_timer.data = (unsigned long)dev;	chdlc_priv_area->poll_delay_timer.function = chdlc_poll_delay;		printk(KERN_INFO "\n");	return 0;}/****** Network Device Interface ********************************************//*============================================================================ * Initialize Linux network interface. * * This routine is called only once for each interface, during Linux network * interface registration.  Returning anything but zero will fail interface * registration. */static int if_init(struct net_device* dev){	chdlc_private_area_t* chdlc_priv_area = dev->priv;	sdla_t* card = chdlc_priv_area->card;	struct wan_device* wandev = &card->wandev;

⌨️ 快捷键说明

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