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

📄 sdla_fr.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (sendpacket[1] == 0x00 &&	    sendpacket[2] == 0x80 &&	    sendpacket[6] == 0x81 &&	    sendpacket[7] == 0x37) 	{		/* It's an IPX packet */		if (!enable_IPX) {			/* Return 1 so we don't pass it up the stack. */			return 1;		}	}	else	{		/* It's not IPX so return and pass it up the stack. */		return 0;	}	if (sendpacket[24] == 0x90 &&	    sendpacket[25] == 0x04) 	{		/* It's IPXWAN */		if (sendpacket[10] == 0x02 &&		    sendpacket[42] == 0x00) 		{			/* It's a timer request packet */			printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname);			/* Go through the routing options and answer no to every */			/* option except Unnumbered RIP/SAP */			for (i = 49; sendpacket[i] == 0x00; i += 5) 			{				/* 0x02 is the option for Unnumbered RIP/SAP */				if (sendpacket[i + 4] != 0x02) 				{					sendpacket[i + 1] = 0;				}			}			/* Skip over the extended Node ID option */			if (sendpacket[i] == 0x04) 				i += 8;			/* We also want to turn off all header compression opt. */			for (; sendpacket[i] == 0x80;) 			{				sendpacket[i + 1] = 0;				i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;			}			/* Set the packet type to timer response */			sendpacket[42] = 0x01;			printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname);		}		else if (sendpacket[42] == 0x02) 		{			/* This is an information request packet */			printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname);			/* Set the packet type to information response */			sendpacket[42] = 0x03;			/* Set the router name */			sendpacket[59] = 'F';			sendpacket[60] = 'P';			sendpacket[61] = 'I';			sendpacket[62] = 'P';			sendpacket[63] = 'E';			sendpacket[64] = '-';			sendpacket[65] = CVHexToAscii(network_number >> 28);			sendpacket[66] = CVHexToAscii((network_number & 0x0F000000) >> 24);			sendpacket[67] = CVHexToAscii((network_number & 0x00F00000) >> 20);			sendpacket[68] = CVHexToAscii((network_number & 0x000F0000) >> 16);			sendpacket[69] = CVHexToAscii((network_number & 0x0000F000) >> 12);			sendpacket[70] = CVHexToAscii((network_number & 0x00000F00) >> 8);			sendpacket[71] = CVHexToAscii((network_number & 0x000000F0) >> 4);			sendpacket[72] = CVHexToAscii(network_number & 0x0000000F);			for (i = 73; i < 107; i += 1) 				sendpacket[i] = 0;			printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname);		}		else		{			printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname);			return 0;		}		/* Set the WNodeID to our network address */		sendpacket[43] = (unsigned char) (network_number >> 24);		sendpacket[44] = (unsigned char) ((network_number & 0x00FF0000) >> 16);		sendpacket[45] = (unsigned char) ((network_number & 0x0000FF00) >> 8);		sendpacket[46] = (unsigned char) (network_number & 0x000000FF);		return 1;	}	/* If we get here, its an IPX-data packet so it'll get passed up the stack. */	/* switch the network numbers */	switch_net_numbers(sendpacket, network_number, 1);	return 0;}/****** Background Polling Routines  ****************************************//*============================================================================ * Main polling routine. * This routine is repeatedly called by the WANPIPE 'thead' to allow for * time-dependent housekeeping work. * * o fetch asynchronous network events. * * Notes: * 1. This routine may be called on interrupt context with all interrupts *    enabled. Beware! */static void wpf_poll(sdla_t * card){/*      struct device* dev = card->wandev.dev;  */	fr508_flags_t *flags = card->flags;	unsigned long host_cpu_flags;	++card->statistics.poll_entry;	if (((jiffies - card->state_tick) < HZ) ||	    (card->intr_mode == INTR_TEST_MODE))		return;	disable_irq(card->hw.irq);	++card->irq_dis_poll_count;	if (test_and_set_bit(0, (void *) &card->wandev.critical)) 	{		++card->statistics.poll_already_critical;		save_flags(host_cpu_flags);		cli();		if ((!card->irq_dis_if_send_count) &&		    (!(--card->irq_dis_poll_count)))			enable_irq(card->hw.irq);		restore_flags(host_cpu_flags);		return;	}	card->wandev.critical = 0x11;	++card->statistics.poll_processed;	/* This is to be changed later ??? */	/*	   if( dev && dev->tbusy && !(flags->imask & 0x02) ) {	   printk(KERN_INFO "%s: Wpf_Poll: tbusy = 0x01, imask = 0x%02X\n",             card->devname, flags->imask);	   }	 */	if (flags->event) 	{		fr_mbox_t *mbox = card->mbox;		int err;		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->cmd.command = FR_READ_STATUS;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;		if (err)			fr_event(card, err, mbox);	}	card->wandev.critical = 0;	save_flags(host_cpu_flags);	cli();	if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count)))		enable_irq(card->hw.irq);	restore_flags(host_cpu_flags);	card->state_tick = jiffies;}/****** Frame Relay Firmware-Specific Functions *****************************//*============================================================================ * Read firmware code version. * o fill string str with firmware version info.  */static int fr_read_version(sdla_t * card, char *str){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do 	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->cmd.command = FR_READ_CODE_VERSION;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	} while (err && retry-- && fr_event(card, err, mbox));		if (!err && str) 	{		int len = mbox->cmd.length;		memcpy(str, mbox->data, len);		str[len] = '\0';	}	return err;}/*============================================================================ * Set global configuration. */ static int fr_configure(sdla_t * card, fr_conf_t * conf){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int dlci_num = card->u.f.dlci_num;	int err, i;	do 	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		memcpy(mbox->data, conf, sizeof(fr_conf_t));		if (dlci_num)			for (i = 0; i < dlci_num; ++i)				((fr_conf_t *) mbox->data)->dlci[i] =				    card->u.f.node_dlci[i];		mbox->cmd.command = FR_SET_CONFIG;		mbox->cmd.length =		    sizeof(fr_conf_t) + dlci_num * sizeof(short);		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Set DLCI configuration. */static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t));		mbox->cmd.dlci = (unsigned short) dlci;		mbox->cmd.command = FR_SET_CONFIG;		mbox->cmd.length = 0x0E;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry--);	return err;}/*============================================================================ * Set interrupt mode. */static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		if (card->hw.fwid == SFID_FR502) 		{			fr502_intr_ctl_t *ictl = (void *) mbox->data;			memset(ictl, 0, sizeof(fr502_intr_ctl_t));			ictl->mode = mode;			ictl->tx_len = mtu;			mbox->cmd.length = sizeof(fr502_intr_ctl_t);		}		else		{			fr508_intr_ctl_t *ictl = (void *) mbox->data;			memset(ictl, 0, sizeof(fr508_intr_ctl_t));			ictl->mode = mode;			ictl->tx_len = mtu;			ictl->irq = card->hw.irq;			mbox->cmd.length = sizeof(fr508_intr_ctl_t);		}		mbox->cmd.command = FR_SET_INTR_MODE;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Enable communications. */static int fr_comm_enable(sdla_t * card){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do 	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->cmd.command = FR_COMM_ENABLE;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Disable communications.  */static int fr_comm_disable(sdla_t * card){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->cmd.command = FR_COMM_DISABLE;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Get communications error statistics.  */static int fr_get_err_stats(sdla_t * card){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;		do	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->cmd.command = FR_READ_ERROR_STATS;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		if (!err) 	{		fr_comm_stat_t *stats = (void *) mbox->data;		card->wandev.stats.rx_over_errors = stats->rx_overruns;		card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;		card->wandev.stats.rx_missed_errors = stats->rx_aborts;		card->wandev.stats.rx_length_errors = stats->rx_too_long;		card->wandev.stats.tx_aborted_errors = stats->tx_aborts;	}	return err;}/*============================================================================ * Get statistics.  */static int fr_get_stats(sdla_t * card){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do 	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->cmd.command = FR_READ_STATISTICS;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		if (!err) 	{		fr_link_stat_t *stats = (void *) mbox->data;		card->wandev.stats.rx_frame_errors = stats->rx_bad_format;		card->wandev.stats.rx_dropped = stats->rx_dropped + stats->rx_dropped2;	}	return err;}/*============================================================================ * Add DLCI(s) (Access Node only!). * This routine will perform the ADD_DLCIs command for the specified DLCI. */static int fr_add_dlci(sdla_t * card, int dlci, int num){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err, i;	do 	{		unsigned short *dlci_list = (void *) mbox->data;		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		for (i = 0; i < num; ++i)			dlci_list[i] = card->u.f.node_dlci[i];		mbox->cmd.length = num * sizeof(short);		mbox->cmd.command = FR_ADD_DLCI;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Activate DLCI(s) (Access Node only!).  * This routine will perform the ACTIVATE_DLCIs command with a list of DLCIs.  */static int fr_activate_dlci(sdla_t * card, int dlci, int num){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err, i;	do	{		unsigned short *dlci_list = (void *) mbox->data;		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		for (i = 0; i < num; ++i)			dlci_list[i] = card->u.f.node_dlci[i];		mbox->cmd.length = num * sizeof(short);		mbox->cmd.command = FR_ACTIVATE_DLCI;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Issue in-channel signalling frame.  */static int fr_issue_isf(sdla_t * card, int isf){	fr_mbox_t *mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err;	do	{		memset(&mbox->cmd, 0, sizeof(fr_cmd_t));		mbox->data[0] = isf;		mbox->cmd.length = 1;		mbox->cmd.command = FR_ISSUE_IS_FRAME;		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;	}	while (err && retry-- && fr_event(card, err, mbox));		return err;}/*============================================================================ * Send a frame (S502 version).  */static int fr50

⌨️ 快捷键说明

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