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

📄 sdla_fr.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************** sdla_fr.c	WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module.** Author(s):	Gene Kozin	*		Jaspreet Singh		<jaspreet@sangoma.com>** Copyright:	(c) 1995-1997 Sangoma Technologies Inc.**		This program is free software; you can redistribute it and/or*		modify it under the terms of the GNU General Public License*		as published by the Free Software Foundation; either version*		2 of the License, or (at your option) any later version.* ============================================================================* Nov 26, 1997	Jaspreet Singh	o Improved load sharing with multiple boards*				o Added Cli() to protect enabling of interrupts*				  while polling is called.* Nov 24, 1997	Jaspreet Singh	o Added counters to avoid enabling of interrupts*				  when they have been disabled by another*				  interface or routine (eg. wpf_poll).* Nov 06, 1997	Jaspreet Singh	o Added INTR_TEST_MODE to avoid polling	*				  routine disable interrupts during interrupt*				  testing.* Oct 20, 1997  Jaspreet Singh  o Added hooks in for Router UP time.* Oct 16, 1997  Jaspreet Singh  o The critical flag is used to maintain flow*                                 control by avoiding RACE conditions.  The*                                 cli() and restore_flags() are taken out.*                                 The fr_channel structure is appended for *                                 Driver Statistics.* Oct 15, 1997  Farhan Thawar    o updated if_send() and receive for IPX* Aug 29, 1997  Farhan Thawar    o Removed most of the cli() and sti()*                                o Abstracted the UDP management stuff*                                o Now use tbusy and critical more intelligently* Jul 21, 1997  Jaspreet Singh	 o Can configure T391, T392, N391, N392 & N393*				   through router.conf.*				 o Protected calls to sdla_peek() by adDing *				   save_flags(), cli() and restore_flags().*				 o Added error message for Inactive DLCIs in*				   fr_event() and update_chan_state().*				 o Fixed freeing up of buffers using kfree() *			           when packets are received.* Jul 07, 1997	Jaspreet Singh	 o Added configurable TTL for UDP packets *				 o Added ability to discard multicast and *				   broadcast source addressed packets* Jun 27, 1997	Jaspreet Singh	 o Added FT1 monitor capabilities *				   New case (0x44) statement in if_send routine *				   Added a global variable rCount to keep track*			 	   of FT1 status enabled on the board.* May 29, 1997	Jaspreet Singh	 o Fixed major Flow Control Problem*				   With multiple boards a problem was seen where*				   the second board always stopped transmitting*				   packet after running for a while. The code*				   got into a stage where the interrupts were*				   disabled and dev->tbusy was set to 1.*                  		   This caused the If_send() routine to get into*                                  the if clause for it(0,dev->tbusy) *				   forever.*				   The code got into this stage due to an *				   interrupt occurring within the if clause for *				   set_bit(0,dev->tbusy).  Since an interrupt *				   disables furhter transmit interrupt and * 				   makes dev->tbusy = 0, this effect was undone *                                  by making dev->tbusy = 1 in the if clause.*				   The Fix checks to see if Transmit interrupts*				   are disabled then do not make dev->tbusy = 1* 	   			   Introduced a global variable: int_occur and*				   added tx_int_enabled in the wan_device *				   structure.	* May 21, 1997  Jaspreet Singh   o Fixed UDP Management for multiple*                                  boards.** Apr 25, 1997  Farhan Thawar    o added UDP Management stuff*                                o fixed bug in if_send() and tx_intr() to*                                  sleep and wakeup all devices* Mar 11, 1997  Farhan Thawar   Version 3.1.1*                                o fixed (+1) bug in fr508_rx_intr()*                                o changed if_send() to return 0 if*                                  wandev.critical() is true*                                o free socket buffer in if_send() if*                                  returning 0 *                                o added tx_intr() routine* Jan 30, 1997	Gene Kozin	Version 3.1.0*				 o implemented exec() entry point*				 o fixed a bug causing driver configured as*				   a FR switch to be stuck in WAN_*				   mode* Jan 02, 1997	Gene Kozin	Initial version.*****************************************************************************/#include <linux/kernel.h>	/* printk(), and other useful stuff */#include <linux/stddef.h>	/* offsetof(), etc. */#include <linux/errno.h>	/* return codes */#include <linux/string.h>	/* inline memset(), etc. */#include <linux/malloc.h>	/* kmalloc(), kfree() */#include <linux/wanrouter.h>	/* WAN router definitions */#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */#include <linux/if_arp.h>	/* ARPHRD_* defines */#include <asm/byteorder.h>	/* htons(), etc. */#include <asm/io.h>		/* for inb(), outb(), etc. */#include <linux/time.h>		/* for do_gettimeofday */#define	_GNUC_#include <linux/sdla_fr.h>	/* frame relay firmware API definitions */#include <asm/uaccess.h>/****** Defines & Macros ****************************************************/#define	MAX_CMD_RETRY	10	/* max number of firmware retries */#define	FR_HEADER_LEN	8	/* max encapsulation header size */#define	FR_CHANNEL_MTU	1500	/* unfragmented logical channel MTU *//* Q.922 frame types */#define	Q922_UI		0x03	/* Unnumbered Info frame */#define	Q922_XID	0xAF	/* ??? *//* DLCI configured or not */#define DLCI_NOT_CONFIGURED	0x00#define DLCI_CONFIG_PENDING	0x01#define DLCI_CONFIGURED		0x02/* CIR enabled or not */#define CIR_ENABLED	0x00#define CIR_DISABLED	0x01/* Interrupt mode for DLCI = 0 */#define BUFFER_INTR_MODE	0x00#define DLCI_LIST_INTR_MODE	0x01/* Transmit Interrupt Status */#define DISABLED 		0x00#define WAITING_TO_BE_ENABLED	0x01/* For handle_IPXWAN() */#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b)))/****** Data Structures *****************************************************//* This is an extention of the 'struct device' we create for each network * interface to keep the rest of channel-specific data. */typedef struct fr_channel {	char name[WAN_IFNAME_SZ + 1];	/* interface name, ASCIIZ */	unsigned dlci_configured;	/* check whether configured or not */	unsigned cir_status;	/* check whether CIR enabled or not */	unsigned dlci;		/* logical channel number */	unsigned cir;		/* committed information rate */	unsigned bc;		/* committed burst size */	unsigned be;		/* excess burst size */	unsigned mc;		/* multicast support on or off */	unsigned tx_int_status;	/* Transmit Interrupt Status */	unsigned short pkt_length;	/* Packet Length */	unsigned long router_start_time;	/* Router start time in seconds */	unsigned long tick_counter;	/* counter for transmit time out */	char dev_pending_devtint;	/* interface pending dev_tint() */	char state;		/* channel state */	void *dlci_int_interface;	/* pointer to the DLCI Interface */	unsigned long IB_addr;	/* physical address of Interface Byte */	unsigned long state_tick;	/* time of the last state change */	sdla_t *card;		/* -> owner */	struct net_device_stats ifstats;		/* interface statistics */	unsigned long if_send_entry;	unsigned long if_send_skb_null;	unsigned long if_send_broadcast;	unsigned long if_send_multicast;	unsigned long if_send_critical_ISR;	unsigned long if_send_critical_non_ISR;	unsigned long if_send_busy;	unsigned long if_send_busy_timeout;	unsigned long if_send_FPIPE_request;	unsigned long if_send_DRVSTATS_request;	unsigned long if_send_wan_disconnected;	unsigned long if_send_dlci_disconnected;	unsigned long if_send_no_bfrs;	unsigned long if_send_adptr_bfrs_full;	unsigned long if_send_bfrs_passed_to_adptr;	unsigned long rx_intr_no_socket;	unsigned long rx_intr_dev_not_started;	unsigned long rx_intr_FPIPE_request;	unsigned long rx_intr_DRVSTATS_request;	unsigned long rx_intr_bfr_not_passed_to_stack;	unsigned long rx_intr_bfr_passed_to_stack;	unsigned long UDP_FPIPE_mgmt_kmalloc_err;	unsigned long UDP_FPIPE_mgmt_direction_err;	unsigned long UDP_FPIPE_mgmt_adptr_type_err;	unsigned long UDP_FPIPE_mgmt_adptr_cmnd_OK;	unsigned long UDP_FPIPE_mgmt_adptr_cmnd_timeout;	unsigned long UDP_FPIPE_mgmt_adptr_send_passed;	unsigned long UDP_FPIPE_mgmt_adptr_send_failed;	unsigned long UDP_FPIPE_mgmt_not_passed_to_stack;	unsigned long UDP_FPIPE_mgmt_passed_to_stack;	unsigned long UDP_FPIPE_mgmt_no_socket;	unsigned long UDP_DRVSTATS_mgmt_kmalloc_err;	unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK;	unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;	unsigned long UDP_DRVSTATS_mgmt_adptr_send_passed;	unsigned long UDP_DRVSTATS_mgmt_adptr_send_failed;	unsigned long UDP_DRVSTATS_mgmt_not_passed_to_stack;	unsigned long UDP_DRVSTATS_mgmt_passed_to_stack;	unsigned long UDP_DRVSTATS_mgmt_no_socket;	unsigned long router_up_time;} fr_channel_t;typedef struct dlci_status {	unsigned short dlci PACKED;	unsigned char state PACKED;} dlci_status_t;typedef struct dlci_IB_mapping {	unsigned short dlci PACKED;	unsigned long addr_value PACKED;} dlci_IB_mapping_t;/* This structure is used for DLCI list Tx interrupt mode.  It is used to   enable interrupt bit and set the packet length for transmission */typedef struct fr_dlci_interface {	unsigned char gen_interrupt PACKED;	unsigned short packet_length PACKED;	unsigned char reserved PACKED;} fr_dlci_interface_t;static unsigned short num_frames;static unsigned long curr_trace_addr;static unsigned long start_trace_addr;static unsigned short available_buffer_space;static char TracingEnabled; /* variable for keeping track of enabling/disabling FT1 monitor status */static int rCount = 0;extern void disable_irq(unsigned int);extern void enable_irq(unsigned int);/* variable for keeping track of number of interrupts generated during  * interrupt test routine  */static int Intr_test_counter;/****** Function Prototypes *************************************************//* WAN link driver entry points. These are called by the WAN router module. */static int update(wan_device_t * wandev);static int new_if(wan_device_t * wandev, struct device *dev,		  wanif_conf_t * conf);static int del_if(wan_device_t * wandev, struct device *dev);/* WANPIPE-specific entry points */static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data);/* Network device interface */static int if_init(struct device *dev);static int if_open(struct device *dev);static int if_close(struct device *dev);static int if_header(struct sk_buff *skb, struct device *dev,	    unsigned short type, void *daddr, void *saddr, unsigned len);static int if_rebuild_hdr(struct sk_buff *skb);static int if_send(struct sk_buff *skb, struct device *dev);static struct net_device_stats *if_stats(struct device *dev);/* Interrupt handlers */static void fr502_isr(sdla_t * card);static void fr508_isr(sdla_t * card);static void fr502_rx_intr(sdla_t * card);static void fr508_rx_intr(sdla_t * card);static void tx_intr(sdla_t * card);static void spur_intr(sdla_t * card);/* Background polling routines */static void wpf_poll(sdla_t * card);/* Frame relay firmware interface functions */static int fr_read_version(sdla_t * card, char *str);static int fr_configure(sdla_t * card, fr_conf_t * conf);static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci);static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu);static int fr_comm_enable(sdla_t * card);static int fr_comm_disable(sdla_t * card);static int fr_get_err_stats(sdla_t * card);static int fr_get_stats(sdla_t * card);static int fr_add_dlci(sdla_t * card, int dlci, int num);static int fr_activate_dlci(sdla_t * card, int dlci, int num);static int fr_issue_isf(sdla_t * card, int isf);static int fr502_send(sdla_t * card, int dlci, int attr, int len, void *buf);static int fr508_send(sdla_t * card, int dlci, int attr, int len, void *buf);/* Firmware asynchronous event handlers */static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox);static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox);static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox);/* Miscellaneous functions */static int update_chan_state(struct device *dev);static void set_chan_state(struct device *dev, int state);static struct device *find_channel(sdla_t * card, unsigned dlci);static int is_tx_ready(sdla_t * card, fr_channel_t * chan);static unsigned int dec_to_uint(unsigned char *str, int len);static int reply_udp(unsigned char *data, unsigned int mbox_len);static int intr_test(sdla_t * card);static void init_chan_statistics(fr_channel_t * chan);static void init_global_statistics(sdla_t * card);static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan);/* Udp management functions */static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan);static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan);static int udp_pkt_type(struct sk_buff *skb, sdla_t * card);/* IPX functions */static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming);static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number);/****** Public Functions ****************************************************//*============================================================================ * Frame relay protocol initialization routine. * * This routine is called by the main WANPIPE module during setup.  At this * point adapter is completely initialized and firmware is running. *  o read firmware version (to make sure it's alive) *  o configure adapter *  o initialize protocol-specific fields of the adapter data space. * * Return:	0	o.k. *		< 0	failure. */int wpf_init(sdla_t * card, wandev_conf_t * conf){	union {		char str[80];		fr_conf_t cfg;	} u;	int i;	/* Verify configuration ID */	if (conf->config_id != WANCONFIG_FR) 	{		printk(KERN_INFO "%s: invalid configuration ID %u!\n",		       card->devname, conf->config_id);		return -EINVAL;	}	/* Initialize protocol-specific fields of adapter data space */	switch (card->hw.fwid) 	{		case SFID_FR502:			card->mbox = (void *) (card->hw.dpmbase + FR502_MBOX_OFFS);			card->rxmb = (void *) (card->hw.dpmbase + FR502_RXMB_OFFS);			card->flags = (void *) (card->hw.dpmbase + FR502_FLAG_OFFS);			card->isr = &fr502_isr;			break;		case SFID_FR508:			card->mbox = (void *) (card->hw.dpmbase + FR508_MBOX_OFFS);			card->flags = (void *) (card->hw.dpmbase + FR508_FLAG_OFFS);			card->isr = &fr508_isr;			break;		default:			return -EINVAL;	}	/* Read firmware version.  Note that when adapter initializes, it	 * clears the mailbox, so it may appear that the first command was	 * executed successfully when in fact it was merely erased. To work	 * around this, we execute the first command twice.	 */	if (fr_read_version(card, NULL) || fr_read_version(card, u.str))		return -EIO;	printk(KERN_INFO "%s: running frame relay firmware v%s\n",	       card->devname, u.str);	/* Adjust configuration */	conf->mtu = max(min(conf->mtu, 4080), FR_CHANNEL_MTU + FR_HEADER_LEN);	conf->bps = min(conf->bps, 2048000);	/* Configure adapter firmware */	memset(&u.cfg, 0, sizeof(u.cfg));	u.cfg.mtu = conf->mtu;	u.cfg.kbps = conf->bps / 1000;	u.cfg.cir_fwd = u.cfg.cir_bwd = 16;	u.cfg.bc_fwd = u.cfg.bc_bwd = 16;	if (conf->station == WANOPT_CPE) 	{		u.cfg.options = 0x0080;		printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname);	}	else	{		u.cfg.options = 0x0081;	}	switch (conf->u.fr.signalling) 	{		case WANOPT_FR_Q933:			u.cfg.options |= 0x0200;			break;		case WANOPT_FR_LMI:			u.cfg.options |= 0x0400;			break;	}	if (conf->station == WANOPT_CPE) 	{		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

⌨️ 快捷键说明

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