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

📄 sdla_ppp.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ppp_priv_area->mc = conf->mc;	ppp_priv_area->pap = conf->pap;	ppp_priv_area->chap = conf->chap;	/* If no user ids are specified */	if(!strlen(conf->userid) && (ppp_priv_area->pap||ppp_priv_area->chap)){		kfree(ppp_priv_area);		return -EINVAL;	}	/* If no passwords are specified */	if(!strlen(conf->passwd) && (ppp_priv_area->pap||ppp_priv_area->chap)){		kfree(ppp_priv_area);		return -EINVAL;	}	if(strlen(conf->sysname) > 31){		kfree(ppp_priv_area);		return -EINVAL;	}	/* If no system name is specified */	if(!strlen(conf->sysname) && (card->u.p.authenticator)){		kfree(ppp_priv_area);		return -EINVAL;	}	/* copy the data into the ppp private structure */	memcpy(ppp_priv_area->userid, conf->userid, strlen(conf->userid));	memcpy(ppp_priv_area->passwd, conf->passwd, strlen(conf->passwd));	memcpy(ppp_priv_area->sysname, conf->sysname, strlen(conf->sysname));		ppp_priv_area->enable_IPX = conf->enable_IPX;	if (conf->network_number)		ppp_priv_area->network_number = conf->network_number;	else		ppp_priv_area->network_number = 0xDEADBEEF;	/* prepare network device data space for registration */	strcpy(dev->name, card->u.p.if_name);	dev->init = &if_init;	dev->priv = ppp_priv_area;	return 0;}/*============================================================================ * Delete logical channel. */static int del_if(wan_device_t *wandev, struct net_device *dev){	if (dev->priv) {                kfree(dev->priv);                dev->priv = NULL;        }	return 0;}/****** WANPIPE-specific entry points ***************************************//*============================================================================ * Execute adapter interface command. *///FIXME: Why do we need this ????static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data){	ppp_mbox_t *mbox = card->mbox;	int len;	if (copy_from_user((void*)&mbox->cmd, u_cmd, sizeof(ppp_cmd_t)))		return -EFAULT;	len = mbox->cmd.length;	if (len) {		if( copy_from_user((void*)&mbox->data, u_data, len))			return -EFAULT;	}	/* execute command */	if (!sdla_exec(mbox))		return -EIO;	/* return result */	if( copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(ppp_cmd_t)))		return -EFAULT;	len = mbox->cmd.length;	if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len))		return -EFAULT;	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){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	wan_device_t *wandev = &card->wandev;#ifndef LINUX_2_1	int i;#endif	/* Initialize device driver entry points */	dev->open		= &if_open;	dev->stop		= &if_close;	dev->hard_header	= &if_header;	dev->rebuild_header	= &if_rebuild_hdr;	dev->hard_start_xmit	= &if_send;	dev->get_stats		= &if_stats;	dev->tx_timeout		= &if_tx_timeout;	dev->watchdog_timeo	= TX_TIMEOUT;	/* Initialize media-specific parameters */	dev->type		= ARPHRD_PPP;	/* ARP h/w type */	dev->flags	       |= IFF_POINTOPOINT;	/* Enable Mulitcasting if specified by user*/	if (ppp_priv_area->mc == WANOPT_YES){		dev->flags     |= IFF_MULTICAST;	}#ifndef LINUX_2_1	dev->family		= AF_INET;#endif		dev->mtu		= wandev->mtu;	dev->hard_header_len	= PPP_HDR_LEN;	/* media header length */	/* Initialize hardware parameters (just for reference) */	dev->irq		= wandev->irq;	dev->dma		= wandev->dma;	dev->base_addr		= wandev->ioport;	dev->mem_start		= wandev->maddr;	dev->mem_end		= wandev->maddr + wandev->msize - 1;        /* Set transmit buffer queue length */        dev->tx_queue_len = 100;   	/* Initialize socket buffers */	dev_init_buffers(dev);	return 0;}/*============================================================================ * Open network interface. * o enable communications and interrupts. * o prevent module from unloading by incrementing use count * * Return 0 if O.k. or errno. */static int if_open(struct net_device *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	ppp_flags_t *flags = card->flags;	struct timeval tv;	int err = 0;	if (netif_running(dev))		return -EBUSY;		/* only one open is allowed */		if (test_and_set_bit(0, (void*)&card->wandev.critical))		return -EAGAIN;	if (!card->configured){		if (config508(ppp_priv_area, card)){			err = -EIO;			card->wandev.critical = 0;			return err;		}		Intr_test_counter = 0;		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( "%s: Please choose another interrupt\n",card->devname);			err = -EIO;			card->wandev.critical = 0;			return err;		}				printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", 			card->devname, Intr_test_counter);		card->configured = 1;	}	/* Initialize Rx/Tx buffer control fields */	init_ppp_tx_rx_buff( card );	if (ppp_set_intr_mode(card, PPP_INTR_RXRDY|			    		PPP_INTR_TXRDY|				    	PPP_INTR_MODEM|				    	PPP_INTR_CMD  |				    	PPP_INTR_DISC |				    	PPP_INTR_OPEN |				    	PPP_INTR_DROP_DTR |					PPP_INTR_TIMER)) {			err = -EIO;		card->wandev.critical = 0;		return err;	}        /* Turn off the transmit and timer interrupt */	flags->imask &= ~(PPP_INTR_TXRDY | PPP_INTR_TIMER) ;	/* If you are not the authenticator and any one of the protocol is 	 * enabled then we call the set_out_bound_authentication.	 */	if ( !card->u.p.authenticator  && (ppp_priv_area->pap || ppp_priv_area->chap)) {		if ( ppp_set_outbnd_auth(card, ppp_priv_area) ){			err = -EIO;			card->wandev.critical = 0;			return err;		}	} 		/* If you are the authenticator and any one of the protocol is enabled	 * then we call the set_in_bound_authentication.	 */	if ( card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)) {		if ( ppp_set_inbnd_auth(card, ppp_priv_area) ){			err = -EIO;			card->wandev.critical = 0;			return err;		}	}	if (ppp_comm_enable(card)) {		err = -EIO;		card->wandev.critical = 0;		return err;	}		wanpipe_set_state(card, WAN_CONNECTING);	wanpipe_open(card);	dev->mtu = min(dev->mtu, card->wandev.mtu);	netif_start_queue(dev);		do_gettimeofday( &tv );	ppp_priv_area->router_start_time = tv.tv_sec;	card->wandev.critical = 0;	return err;}/*============================================================================ * Close network interface. * o if this is the last open, then disable communications and interrupts. * o reset flags. */static int if_close(struct net_device *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	if (test_and_set_bit(0, (void*)&card->wandev.critical))		return -EAGAIN;		netif_stop_queue(dev);	wanpipe_close(card);	wanpipe_set_state(card, WAN_DISCONNECTED);	ppp_set_intr_mode(card, 0);	ppp_comm_disable(card);	card->wandev.critical = 0;	return 0;}/*============================================================================ * Build media header. * * The trick here is to put packet type (Ethertype) into 'protocol' field of * the socket buffer, so that we don't forget it.  If packet type is not * supported, set skb->protocol to 0 and discard packet later. * * Return:	media header length. */static int if_header(struct sk_buff *skb, struct net_device *dev,	unsigned short type, void *daddr, void *saddr, unsigned len){	switch (type)	{		case ETH_P_IP:			case ETH_P_IPX:			skb->protocol = htons(type);			break;		default:			skb->protocol = 0;	}	return PPP_HDR_LEN;}/*============================================================================ * Re-build media header. * * Return:	1	physical address resolved. *		0	physical address not resolved */static int if_rebuild_hdr (struct sk_buff *skb){	struct net_device *dev = skb->dev;	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n",		card->devname, dev->name);	return 1;}/*============================================================================ * Handle transmit timeout from netif watchdog */static void if_tx_timeout (struct net_device *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	/* If our device stays busy for at least 5 seconds then we will	 * kick start the device by making dev->tbusy = 0.  We expect 	 * that our device never stays busy more than 5 seconds. So this	 * is only used as a last resort. 	 */	++ppp_priv_area->if_send_stat.if_send_tbusy;	++card->wandev.stats.collisions;	printk (KERN_INFO "%s: Transmit times out\n", card->devname);	++ppp_priv_area->if_send_stat.if_send_tbusy_timeout;	++card->wandev.stats.collisions;	/* unbusy the card (because only one interface per card) */	netif_start_queue(dev);}/*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based *   transmit from overlapping. * o check link state. If link is not up, then drop the packet. * o execute adapter send command. * o free socket buffer * * Return:	0	complete (socket buffer must be freed) *		non-0	packet may be re-transmitted (tbusy must be set) * * Notes: * 1. This routine is called either by the protocol stack or by the "net *    bottom half" (with interrupts enabled). * 2. Setting tbusy flag will inhibit further transmit requests from the *    protocol stack and can be used for flow control with protocol layer. */static int if_send (struct sk_buff *skb, struct net_device *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	unsigned char *sendpacket;	unsigned long smp_flags;	ppp_flags_t *flags = card->flags;	int retry = 0;	int udp_type;			++ppp_priv_area->if_send_stat.if_send_entry;	if (skb == NULL) {		/* If we get here, some higher layer thinks we've missed an		 * tx-done interrupt.		 */		printk(KERN_INFO "%s: interface %s got kicked!\n",			card->devname, dev->name);				++ppp_priv_area->if_send_stat.if_send_skb_null;				netif_wake_queue(dev);		return 0;	}	sendpacket = skb->data;	udp_type = udp_pkt_type( skb, card );	if (udp_type == UDP_PTPIPE_TYPE){		if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,                	              ppp_priv_area)){	               	flags->imask |= PPP_INTR_TIMER;		}		++ppp_priv_area->if_send_stat.if_send_PIPE_request;		return 0;	}	/* Check for broadcast and multicast addresses 	 * If found, drop (deallocate) a packet and return.	 */	if(chk_bcast_mcast_addr(card, dev, skb)){                        return 0;	} 	if(card->hw.type != SDLA_S514){		s508_lock(card,&smp_flags);	}    	if (test_and_set_bit(0, (void*)&card->wandev.critical)) {		printk(KERN_INFO "%s: Critical in if_send: %x\n",				card->wandev.name,card->wandev.critical);    		dev_kfree_skb(skb);		++card->wandev.stats.tx_dropped;		++ppp_priv_area->if_send_stat.if_send_critical_non_ISR;			if(card->hw.type != SDLA_S514){				s508_unlock(card,&smp_flags);		}		return 0;	}	if (card->wandev.state != WAN_CONNECTED) {		++ppp_priv_area->if_send_stat.if_send_wan_disconnected;        	++card->wandev.stats.tx_dropped;     	} else if (!skb->protocol) {		++ppp_priv_area->if_send_stat.if_send_protocol_error;        	++card->wandev.stats.tx_errors;

⌨️ 快捷键说明

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