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

📄 sdla_ppp.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	} else {		/* If the source network is 0, make it ours */		if (pnetwork_number == 0) {			sendpacket[18] = (unsigned char) (network_number >> 24);			sendpacket[19] = (unsigned char) ((network_number &						      0x00FF0000) >> 16);			sendpacket[20] = (unsigned char) ((network_number &						       0x0000FF00) >> 8);			sendpacket[21] = (unsigned char) (network_number &							  0x000000FF);		}	}}				/* switch_net_numbers *//*============================================================================ * Get Ethernet-style interface statistics. * Return a pointer to struct enet_statistics. */static struct enet_statistics *if_stats(struct device *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card;		/*	 *	Device is down:No statistics	 */	 	if(ppp_priv_area==NULL)		return NULL;		card = ppp_priv_area->card;	return &card->wandev.stats;}/****** PPP Firmware Interface Functions ************************************//*============================================================================ * Read firmware code version. *	Put code version as ASCII string in str.  */static int ppp_read_version(sdla_t * card, char *str){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_READ_CODE_VERSION;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	else if (str) {		int len = mb->cmd.length;		memcpy(str, mb->data, len);		str[len] = '\0';	}	return err;}/*============================================================================ * Configure PPP firmware. */static int ppp_configure(sdla_t * card, void *data){	ppp_mbox_t *mb = card->mbox;	int data_len = (card->hw.fwid == SFID_PPP502) ?	sizeof(ppp502_conf_t) : sizeof(ppp508_conf_t);	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	memcpy(mb->data, data, data_len);	mb->cmd.length = data_len;	mb->cmd.command = PPP_SET_CONFIG;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	return err;}/*============================================================================ * Set interrupt mode. */static int ppp_set_intr_mode(sdla_t * card, unsigned mode){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->data[0] = mode;	switch (card->hw.fwid) {	case SFID_PPP502:		mb->cmd.length = 1;		break;	case SFID_PPP508:	default:		mb->data[1] = card->hw.irq;		mb->cmd.length = 2;	}	mb->cmd.command = PPP_SET_INTR_FLAGS;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	return err;}/*============================================================================ * Enable communications. */static int ppp_comm_enable(sdla_t * card){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_COMM_ENABLE;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	return err;}/*============================================================================ * Disable communications. */static int ppp_comm_disable(sdla_t * card){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_COMM_DISABLE;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	return err;}/*============================================================================ * Get communications error statistics. */static int ppp_get_err_stats(sdla_t * card){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_READ_ERROR_STATS;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err == CMD_OK) {		ppp_err_stats_t *stats = (void *) mb->data;		card->wandev.stats.rx_over_errors = stats->rx_overrun;		card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;		card->wandev.stats.rx_missed_errors = stats->rx_abort;		card->wandev.stats.rx_length_errors = stats->rx_lost;		card->wandev.stats.tx_aborted_errors = stats->tx_abort;	} else		ppp_error(card, err, mb);	return err;}/*============================================================================ * Send packet. *	Return:	0 - o.k. *		1 - no transmit buffers available */static int ppp_send(sdla_t * card, void *data, unsigned len, unsigned proto){	ppp_buf_ctl_t *txbuf = card->u.p.txbuf;	unsigned long addr;	if (txbuf->flag)		return 1		    ;	if (card->hw.fwid == SFID_PPP502)		addr = (txbuf->buf.o_p[1] << 8) + txbuf->buf.o_p[0];	else		addr = txbuf->buf.ptr;	sdla_poke(&card->hw, addr, data, len);	txbuf->length = len;	/* frame length */	if (proto == ETH_P_IPX)		txbuf->proto = 0x01;	/* protocol ID */	txbuf->flag = 1;	/* start transmission */	/* Update transmit buffer control fields */	card->u.p.txbuf = ++txbuf;	if ((void *) txbuf > card->u.p.txbuf_last)		card->u.p.txbuf = card->u.p.txbuf_base;	return 0;}/****** Firmware Error Handler **********************************************//*============================================================================ * Firmware error handler. *	This routine is called whenever firmware command returns non-zero *	return code. * * Return zero if previous command has to be cancelled. */static int ppp_error(sdla_t * card, int err, ppp_mbox_t * mb){	unsigned cmd = mb->cmd.command;	switch (err) {	case CMD_TIMEOUT:		printk(KERN_ERR "%s: command 0x%02X timed out!\n",		       card->devname, cmd);		break;	default:		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"		       ,card->devname, cmd, err);	}	return 0;}/****** Interrupt Handlers **************************************************//*============================================================================ * PPP interrupt service routine. */STATIC void wpp_isr(sdla_t * card){	ppp_flags_t *flags = card->flags;	char *ptr = &flags->iflag;	unsigned long host_cpu_flags;	struct device *dev = card->wandev.dev;	int i;	card->in_isr = 1;	++card->statistics.isr_entry;	if (test_and_set_bit(0, (void *) &card->wandev.critical)) {		++card->statistics.isr_already_critical;		printk(KERN_INFO "%s: Critical while in ISR!\n", card->devname);		card->in_isr = 0;		return;	}	/* For all interrupts set the critical flag to CRITICAL_IN_ISR. 	 * If the if_send routine is called with this flag set it will set 	 * the enable transmit flag to 1. (for a delayed interrupt) 	 */	card->wandev.critical = CRITICAL_IN_ISR;	card->buff_int_mode_unbusy = 0;	switch (flags->iflag) {	case 0x01:		/* receive interrupt */		++card->statistics.isr_rx;		rx_intr(card);		break;	case 0x02:		/* transmit interrupt */		++card->statistics.isr_tx;		flags->imask &= ~0x02;		dev->tbusy = 0;		card->buff_int_mode_unbusy = 1;		break;	case 0x08:		++Intr_test_counter;		++card->statistics.isr_intr_test;		break;	default:		/* unexpected interrupt */		++card->statistics.isr_spurious;		printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",		       card->devname, flags->iflag);		printk(KERN_INFO "%s: ID Bytes = ", card->devname);		for (i = 0; i < 8; i++)			printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));		printk(KERN_INFO "\n");	}	/* The critical flag is set to CRITICAL_INTR_HANDLED to let the	 * if_send call know that the interrupt is handled so that 	 * transmit interrupts are not enabled again.	 */	card->wandev.critical = CRITICAL_INTR_HANDLED;	/* If the enable transmit interrupt flag is set then enable transmit 	 * interrupt on the board. This only goes through if if_send is called 	 * and the critical flag is set due to an Interrupt. 	 */	if (card->wandev.enable_tx_int) {		flags->imask |= 0x02;		card->wandev.enable_tx_int = 0;		++card->statistics.isr_enable_tx_int;	}	save_flags(host_cpu_flags);	cli();	card->in_isr = 0;	flags->iflag = 0;	card->wandev.critical = 0;	restore_flags(host_cpu_flags);	if (card->buff_int_mode_unbusy)		mark_bh(NET_BH);}/*============================================================================ * Receive interrupt handler. */static void rx_intr(sdla_t * card){	ppp_buf_ctl_t *rxbuf = card->rxmb;	struct device *dev = card->wandev.dev;	ppp_private_area_t *ppp_priv_area;	struct sk_buff *skb;	unsigned len;	void *buf;	int i, err;	ppp_flags_t *flags = card->flags;	char *ptr = &flags->iflag;	int udp_type;	if (rxbuf->flag != 0x01) {		printk(KERN_INFO		       "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",		       card->devname, (unsigned) rxbuf, rxbuf->flag);		printk(KERN_INFO "%s: ID Bytes = ", card->devname);		for (i = 0; i < 8; i++)			printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));		printk(KERN_INFO "\n");		++card->statistics.rx_intr_corrupt_rx_bfr;		return;	}	if (dev && dev->start) {		len = rxbuf->length;		ppp_priv_area = dev->priv;		/* Allocate socket buffer */		skb = dev_alloc_skb(len);		if (skb != NULL) {			/* Copy data to the socket buffer */			if (card->hw.fwid == SFID_PPP502) {				unsigned addr = (rxbuf->buf.o_p[1] << 8) +				rxbuf->buf.o_p[0];				buf = skb_put(skb, len);				sdla_peek(&card->hw, addr, buf, len);			} else {				unsigned addr = rxbuf->buf.ptr;				if ((addr + len) > card->u.p.rx_top + 1) {					unsigned tmp = card->u.p.rx_top - addr					+ 1;					buf = skb_put(skb, tmp);					sdla_peek(&card->hw, addr, buf, tmp);					addr = card->u.p.rx_base;					len -= tmp;				}				buf = skb_put(skb, len);				sdla_peek(&card->hw, addr, buf, len);			}			/* Decapsulate packet */			switch (rxbuf->proto) {			case 0x00:				skb->protocol = htons(ETH_P_IP);				break;			case 0x01:				skb->protocol = htons(ETH_P_IPX);				break;			}			udp_type = udp_pkt_type(skb, card);			if (udp_type == UDP_DRVSTATS_TYPE) {				++ppp_priv_area->rx_intr_DRVSTATS_request;				process_udp_driver_call(					  UDP_PKT_FRM_NETWORK, card, skb,						     dev, ppp_priv_area);				dev_kfree_skb(skb);			} else if (udp_type == UDP_PTPIPE_TYPE) {				++ppp_priv_area->rx_intr_PTPIPE_request;				err = process_udp_mgmt_pkt(					       UDP_PKT_FRM_NETWORK, card,						skb, dev, ppp_priv_area);				dev_kfree_skb(skb);			} else if (handle_IPXWAN(skb->data, card->devname, card->wandev.enable_IPX, card->wandev.network_number, skb->protocol)) {				if (card->wandev.enable_IPX) {					ppp_send(card, skb->data, skb->len, ETH_P_IPX);					dev_kfree_skb(skb);				} else {					++card->wandev.stats.rx_dropped;				}			} else {				/* Pass it up the protocol stack */				skb->dev = dev;				skb->mac.raw = skb->data;				netif_rx(skb);				++card->wandev.stats.rx_packets; 				card->wandev.stats.rx_bytes += skb->len;				++ppp_priv_area->rx_intr_bfr_passed_to_stack;			}		} else {			printk(KERN_INFO "%s: no socket buffers available!\n",			       card->devname);			++card->wandev.stats.rx_dropped;			++ppp_priv_area->rx_intr_no_socket;		}	} else		++card->statistics.rx_intr_dev_not_started;	/* Release buffer element and calculate a pointer to the next one */	rxbuf->flag = (card->hw.fwid == SFID_PPP502) ? 0xFF : 0x00;	card->rxmb = ++rxbuf;	if ((void *) rxbuf > card->u.p.rxbuf_last)		card->rxmb = card->u.p.rxbuf_base;}/*============================================================================ * Transmit interrupt handler. */static void tx_intr(sdla_t * card){	struct device *dev = card->wandev.dev;	if (!dev || !dev->start) {		++card->statistics.tx_intr_dev_not_started;		return;	}	dev->tbusy = 0;	mark_bh(NET_BH);}static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto){	int i;	if (proto == htons(ETH_P_IPX)) {

⌨️ 快捷键说明

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