diff options
Diffstat (limited to 'drivers/net/wan/sdla_fr.c')
-rw-r--r-- | drivers/net/wan/sdla_fr.c | 5061 |
1 files changed, 0 insertions, 5061 deletions
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c deleted file mode 100644 index 7f1ce9d4333..00000000000 --- a/drivers/net/wan/sdla_fr.c +++ /dev/null @@ -1,5061 +0,0 @@ -/***************************************************************************** -* sdla_fr.c WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module. -* -* Author(s): Nenad Corbic <ncorbic@sangoma.com> -* Gideon Hack -* -* Copyright: (c) 1995-2001 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 23, 2000 Nenad Corbic o Added support for 2.4.X kernels -* Nov 15, 2000 David Rokavarg -* Nenad Corbic o Added frame relay bridging support. -* Original code from Mark Wells and Kristian Hoffmann has -* been integrated into the frame relay driver. -* Nov 13, 2000 Nenad Corbic o Added true interface type encoding option. -* Tcpdump doesn't support Frame Relay inteface -* types, to fix this true type option will set -* the interface type to RAW IP mode. -* Nov 07, 2000 Nenad Corbic o Added security features for UDP debugging: -* Deny all and specify allowed requests. -* Nov 06, 2000 Nenad Corbic o Wanpipe interfaces conform to raw packet interfaces. -* Moved the if_header into the if_send() routine. -* The if_header() was breaking the libpcap -* support. i.e. support for tcpdump, ethereal ... -* Oct 12. 2000 Nenad Corbic o Added error message in fr_configure -* Jul 31, 2000 Nenad Corbic o Fixed the Router UP Time. -* Apr 28, 2000 Nenad Corbic o Added the option to shutdown an interface -* when the channel gets disconnected. -* Apr 28, 2000 Nenad Corbic o Added M.Grants patch: disallow duplicate -* interface setups. -* Apr 25, 2000 Nenad Corbic o Added M.Grants patch: dynamically add/remove -* new dlcis/interfaces. -* Mar 23, 2000 Nenad Corbic o Improved task queue, bh handling. -* Mar 16, 2000 Nenad Corbic o Added Inverse ARP support -* Mar 13, 2000 Nenad Corbic o Added new socket API support. -* Mar 06, 2000 Nenad Corbic o Bug Fix: corrupted mbox recovery. -* Feb 24, 2000 Nenad Corbic o Fixed up FT1 UDP debugging problem. -* Dev 15, 1999 Nenad Corbic o Fixed up header files for 2.0.X kernels -* -* Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function -* o Removed the ARP support. This has to be done -* in the next version. -* o Only a Node can implement NO signalling. -* Initialize DLCI during if_open() if NO -* signalling. -* o Took out IPX support, implement in next -* version -* Sep 29, 1999 Nenad Corbic o Added SMP support and changed the update -* function to use timer interrupt. -* o Fixed the CIR bug: Set the value of BC -* to CIR when the CIR is enabled. -* o Updated comments, statistics and tracing. -* Jun 02, 1999 Gideon Hack o Updated for S514 support. -* Sep 18, 1998 Jaspreet Singh o Updated for 2.2.X kernels. -* Jul 31, 1998 Jaspreet Singh o Removed wpf_poll routine. The channel/DLCI -* status is received through an event interrupt. -* Jul 08, 1998 David Fong o Added inverse ARP support. -* Mar 26, 1997 Jaspreet Singh o Returning return codes for failed UDP cmds. -* Jan 28, 1997 Jaspreet Singh o Improved handling of inactive DLCIs. -* Dec 30, 1997 Jaspreet Singh o Replaced dev_tint() with mark_bh(NET_BH) -* Dec 16, 1997 Jaspreet Singh o Implemented Multiple IPX support. -* 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/module.h> -#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/slab.h> /* kmalloc(), kfree() */ -#include <linux/wanrouter.h> /* WAN router definitions */ -#include <linux/wanpipe.h> /* WANPIPE common user API definitions */ -#include <linux/workqueue.h> -#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 */ -#include <linux/in.h> /* sockaddr_in */ -#include <linux/jiffies.h> /* time_after() macro */ -#include <asm/errno.h> - -#include <linux/ip.h> -#include <linux/if.h> - -#include <linux/if_wanpipe_common.h> /* Wanpipe Socket */ -#include <linux/if_wanpipe.h> - -#include <linux/sdla_fr.h> /* frame relay firmware API definitions */ - -#include <asm/uaccess.h> -#include <linux/inetdevice.h> -#include <linux/netdevice.h> - -#include <net/route.h> /* Dynamic Route Creation */ -#include <linux/etherdevice.h> /* eth_type_trans() used for bridging */ -#include <linux/random.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 - -#define FRAME_RELAY_API 1 -#define MAX_BH_BUFF 10 - -/* 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 -{ - wanpipe_common_t common; - 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() */ - 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 */ - unsigned char enable_IPX; /* Enable/Disable the use of IPX */ - unsigned long network_number; /* Internal Network Number for IPX*/ - sdla_t *card; /* -> owner */ - unsigned route_flag; /* Add/Rem dest addr in route tables */ - unsigned inarp; /* Inverse Arp Request status */ - long inarp_ready; /* Ready to send requests */ - int inarp_interval; /* Time between InArp Requests */ - unsigned long inarp_tick; /* InArp jiffies tick counter */ - long interface_down; /* Bring interface down on disconnect */ - struct net_device_stats ifstats; /* interface statistics */ - if_send_stat_t drvstats_if_send; - rx_intr_stat_t drvstats_rx_intr; - pipe_mgmt_stat_t drvstats_gen; - unsigned long router_up_time; - - unsigned short transmit_length; - struct sk_buff *delay_skb; - - bh_data_t *bh_head; /* Circular buffer for chdlc_bh */ - unsigned long tq_working; - volatile int bh_write; - volatile int bh_read; - atomic_t bh_buff_used; - - /* Polling task queue. Each interface - * has its own task queue, which is used - * to defer events from the interrupt */ - struct work_struct fr_poll_work; - struct timer_list fr_arp_timer; - - u32 ip_local; - u32 ip_remote; - long config_dlci; - long unconfig_dlci; - - /* Whether this interface should be setup as a gateway. - * Used by dynamic route setup code */ - u8 gateway; - - /* True interface type */ - u8 true_if_encoding; - u8 fr_header[FR_HEADER_LEN]; - char fr_header_len; - -} fr_channel_t; - -/* Route Flag options */ -#define NO_ROUTE 0x00 -#define ADD_ROUTE 0x01 -#define ROUTE_ADDED 0x02 -#define REMOVE_ROUTE 0x03 -#define ARP_REQ 0x04 - -/* inarp options */ -#define INARP_NONE 0x00 -#define INARP_REQUEST 0x01 -#define INARP_CONFIGURED 0x02 - -/* reasons for enabling the timer interrupt on the adapter */ -#define TMR_INT_ENABLED_UDP 0x01 -#define TMR_INT_ENABLED_UPDATE 0x02 -#define TMR_INT_ENABLED_ARP 0x04 -#define TMR_INT_ENABLED_UPDATE_STATE 0x08 -#define TMR_INT_ENABLED_CONFIG 0x10 -#define TMR_INT_ENABLED_UNCONFIG 0x20 - - -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; - -/* 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(struct wan_device *wandev); -static int new_if(struct wan_device *wandev, struct net_device *dev, - wanif_conf_t *conf); -static int del_if(struct wan_device *wandev, struct net_device *dev); -static void disable_comm (sdla_t *card); - -/* 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 net_device *dev); -static int if_open(struct net_device *dev); -static int if_close(struct net_device *dev); - -static void if_tx_timeout(struct net_device *dev); - -static int if_rebuild_hdr (struct sk_buff *skb); - -static int if_send(struct sk_buff *skb, struct net_device *dev); -static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, - struct sk_buff *skb); -static struct net_device_stats *if_stats(struct net_device *dev); - -/* Interrupt handlers */ -static void fr_isr(sdla_t *card); -static void rx_intr(sdla_t *card); -static void tx_intr(sdla_t *card); -static void timer_intr(sdla_t *card); -static void spur_intr(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_init_dlci (sdla_t *card, fr_channel_t *chan); -static int fr_set_intr_mode (sdla_t *card, unsigned mode, unsigned mtu, unsigned short timeout); -static int fr_comm_enable(sdla_t *card); -static void 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); -static int fr_activate_dlci(sdla_t *card, int dlci); -static int fr_delete_dlci (sdla_t* card, int dlci); -static int fr_issue_isf(sdla_t *card, int isf); -static int fr_send(sdla_t *card, int dlci, unsigned char attr, int len, - void *buf); -static int fr_send_data_header(sdla_t *card, int dlci, unsigned char attr, int len, - void *buf,unsigned char hdr_len); -static unsigned int fr_send_hdr(sdla_t *card, int dlci, unsigned int offset); - -static int check_dlci_config (sdla_t *card, fr_channel_t *chan); -static void initialize_rx_tx_buffers (sdla_t *card); - - -/* 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 net_device *dev); -static void set_chan_state(struct net_device *dev, int state); -static struct net_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 ); -static int setup_for_delayed_transmit(struct net_device* dev, - struct sk_buff *skb); - -struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev); -static int check_tx_status(sdla_t *card, struct net_device *dev); - -/* Frame Relay Socket API */ -static void trigger_fr_bh (fr_channel_t *); -static void fr_bh(struct net_device *dev); -static int fr_bh_cleanup(struct net_device *dev); -static int bh_enqueue(struct net_device *dev, struct sk_buff *skb); - -static void trigger_fr_poll(struct net_device *dev); -static void fr_poll(struct net_device *dev); -//static void add_gateway(struct net_device *dev); - -static void trigger_unconfig_fr(struct net_device *dev); -static void unconfig_fr (sdla_t *); - -static void trigger_config_fr (sdla_t *); -static void config_fr (sdla_t *); - - -/* Inverse ARP and Dynamic routing functions */ -int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device *dev); -int is_arp(void *buf); -int send_inarp_request(sdla_t *card, struct net_device *dev); - -static void trigger_fr_arp(struct net_device *dev); -static void fr_arp (unsigned long data); - - -/* Udp management functions */ -static int process_udp_mgmt_pkt(sdla_t *card); -static int udp_pkt_type( struct sk_buff *skb, sdla_t *card ); -static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card, - struct sk_buff *skb, int dlci); - -/* 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); - -/* Lock Functions: SMP supported */ -void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags); -void s508_s514_lock(sdla_t *card, unsigned long *smp_flags); - -unsigned short calc_checksum (char *, int); -static int setup_fr_header(struct sk_buff *skb, - struct net_device* dev, char op_mode); - - -/****** 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) -{ - - int err; - fr508_flags_t* flags; - - union - { - char str[80]; - fr_conf_t cfg; - } u; - - fr_buf_info_t* buf_info; - int i; - - - printk(KERN_INFO "\n"); - - /* 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_FR508: - card->mbox = (void*)(card->hw.dpmbase + - FR508_MBOX_OFFS); - card->flags = (void*)(card->hw.dpmbase + - FR508_FLAG_OFFS); - if(card->hw.type == SDLA_S514) { - card->mbox += FR_MB_VECTOR; - card->flags += FR_MB_VECTOR; - } - card->isr = &fr_isr; - break; - - default: - return -EINVAL; - } - - flags = card->flags; - - /* 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 += FR_HEADER_LEN; - conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ? - min_t(unsigned int, conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) : - FR_CHANNEL_MTU + FR_HEADER_LEN; - - conf->bps = min_t(unsigned int, conf->bps, 2048000); - - /* Initialze the configuration structure sent to the board to zero */ - memset(&u.cfg, 0, sizeof(u.cfg)); - - memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map)); - - /* Configure adapter firmware */ - - 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; - - u.cfg.options = 0x0000; - printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname); - - switch (conf->u.fr.signalling) { - - case WANOPT_FR_ANSI: - u.cfg.options = 0x0000; - break; - - case WANOPT_FR_Q933: - u.cfg.options |= 0x0200; - break; - - case WANOPT_FR_LMI: - u.cfg.options |= 0x0400; - break; - - case WANOPT_NO: - u.cfg.options |= 0x0800; - break; - default: - printk(KERN_INFO "%s: Illegal Signalling option\n", - card->wandev.name); - return -EINVAL; - } - - - card->wandev.signalling = conf->u.fr.signalling; - - if (conf->station == WANOPT_CPE) { - - - if (conf->u.fr.signalling == WANOPT_NO){ - printk(KERN_INFO - "%s: ERROR - For NO signalling, station must be set to Node!", - card->devname); - return -EINVAL; - } - - u.cfg.station = 0; - 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_t(unsigned int, max_t(unsigned int, 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_t(unsigned int, conf->u.fr.t391, 30); - else - u.cfg.t391 = 5; - - if (conf->u.fr.t392) - u.cfg.t392 = min_t(unsigned int, conf->u.fr.t392, 30); - else - u.cfg.t392 = 15; - - if (conf->u.fr.n391) - u.cfg.n391 = min_t(unsigned int, conf->u.fr.n391, 255); - else - u.cfg.n391 = 2; - - if (conf->u.fr.n392) - u.cfg.n392 = min_t(unsigned int, conf->u.fr.n392, 10); - else - u.cfg.n392 = 3; - - if (conf->u.fr.n393) - u.cfg.n393 = min_t(unsigned int, conf->u.fr.n393, 10); - else - u.cfg.n393 = 4; - - if (fr_configure(card, &u.cfg)) - return -EIO; - - if (card->hw.type == SDLA_S514) { - - buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR + - FR508_RXBC_OFFS); - - card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase); - - card->u.f.rxmb_base = - (void*)(buf_info->rse_base + card->hw.dpmbase); - - card->u.f.rxmb_last = - (void*)(buf_info->rse_base + - (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) + - card->hw.dpmbase); - }else{ - buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS); - - card->rxmb = (void*)(buf_info->rse_next - - FR_MB_VECTOR + card->hw.dpmbase); - - card->u.f.rxmb_base = - (void*)(buf_info->rse_base - - FR_MB_VECTOR + card->hw.dpmbase); - - card->u.f.rxmb_last = - (void*)(buf_info->rse_base + - (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) - - FR_MB_VECTOR + card->hw.dpmbase); - } - - card->u.f.rx_base = buf_info->buf_base; - card->u.f.rx_top = buf_info->buf_top; - - card->u.f.tx_interrupts_pending = 0; - - card->wandev.mtu = conf->mtu; - card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; - card->wandev.clocking = conf->clocking; - card->wandev.station = conf->station; - card->poll = NULL; - card->exec = &wpf_exec; - card->wandev.update = &update; - card->wandev.new_if = &new_if; - card->wandev.del_if = &del_if; - card->wandev.state = WAN_DISCONNECTED; - card->wandev.ttl = conf->ttl; - card->wandev.udp_port = conf->udp_port; - card->disable_comm = &disable_comm; - card->u.f.arp_dev = NULL; - - /* Intialize global statistics for a card */ - init_global_statistics( card ); - - card->TracingEnabled = 0; - - /* Interrupt Test */ - Intr_test_counter = 0; - card->intr_mode = INTR_TEST_MODE; - err = intr_test( card ); - - printk(KERN_INFO "%s: End of Interrupt Test rc=0x%x count=%i\n", - card->devname,err,Intr_test_counter); - - if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { - printk(KERN_ERR "%s: Interrupt Test Failed, Counter: %i\n", - card->devname, Intr_test_counter); - printk(KERN_ERR "Please choose another interrupt\n"); - err = -EIO; - return err; - } - - printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", - card->devname, Intr_test_counter); - - - /* Apr 28 2000. Nenad Corbic - * Enable commnunications here, not in if_open or new_if, since - * interfaces come down when the link is disconnected. - */ - - /* If you enable comms and then set ints, you get a Tx int as you - * perform the SET_INT_TRIGGERS command. So, we only set int - * triggers and then adjust the interrupt mask (to disable Tx ints) - * before enabling comms. - */ - if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY | - FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) , - card->wandev.mtu, 0)) { - return -EIO; - } - - flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER); - - if (fr_comm_enable(card)) { - return -EIO; - } - wanpipe_set_state(card, WAN_CONNECTED); - spin_lock_init(&card->u.f.if_send_lock); - - printk(KERN_INFO "\n"); - - return 0; -} - -/******* WAN Device Driver Entry Points *************************************/ - -/*============================================================================ - * Update device status & statistics. - */ -static int update(struct wan_device* wandev) -{ - volatile sdla_t* card; - unsigned long timeout; - fr508_flags_t* flags; - - /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)) - return -EFAULT; - - if (wandev->state == WAN_UNCONFIGURED) - return -ENODEV; - - card = wandev->private; - flags = card->flags; - - - card->u.f.update_comms_stats = 1; - card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE; - flags->imask |= FR_INTR_TIMER; - timeout = jiffies; - for(;;) { - if(card->u.f.update_comms_stats == 0) - break; - if (time_after(jiffies, timeout + 1 * HZ)){ - card->u.f.update_comms_stats = 0; - 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; - fr_channel_t* chan; - int dlci = 0; - int err = 0; - - - 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 */ - chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL); - - if (chan == NULL) - return -ENOMEM; - - memset(chan, 0, sizeof(fr_channel_t)); - strcpy(chan->name, conf->name); - chan->card = card; - - /* verify media address */ - if (isdigit(conf->addr[0])) { - - dlci = dec_to_uint(conf->addr, 0); - - if (dlci && (dlci <= HIGHEST_VALID_DLCI)) { - - chan->dlci = dlci; - - } else { - - printk(KERN_ERR - "%s: Invalid DLCI %u on interface %s!\n", - wandev->name, dlci, chan->name); - err = -EINVAL; - } - - } else { - printk(KERN_ERR - "%s: Invalid media address on interface %s!\n", - wandev->name, chan->name); - err = -EINVAL; - } - - if ((chan->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) even if it is - * a bridged DLCI, or as an API - */ - if (strcmp(conf->usedby, "WANPIPE") == 0 || - strcmp(conf->usedby, "BRIDGE") == 0 || - strcmp(conf->usedby, "BRIDGE_N") == 0){ - - if(strcmp(conf->usedby, "WANPIPE") == 0){ - chan->common.usedby = WANPIPE; - - printk(KERN_INFO "%s: Running in WANPIPE mode.\n", - card->devname); - - }else if(strcmp(conf->usedby, "BRIDGE") == 0){ - - chan->common.usedby = BRIDGE; - - printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE) mode.\n", - card->devname); - }else if( strcmp(conf->usedby, "BRIDGE_N") == 0 ){ - - chan->common.usedby = BRIDGE_NODE; - - printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", - card->devname); - } - - if (!err){ - /* Dynamic interface configuration option. - * On disconnect, if the options is selected, - * the interface will be brought down */ - if (conf->if_down == WANOPT_YES){ - set_bit(DYN_OPT_ON,&chan->interface_down); - printk(KERN_INFO - "%s: Dynamic interface configuration enabled.\n", - card->devname); - } - } - - } else if(strcmp(conf->usedby, "API") == 0){ - - chan->common.usedby = API; - printk(KERN_INFO "%s: Running in API mode.\n", - wandev->name); - } - - if (err) { - - kfree(chan); - return err; - } - - /* place cir,be,bc and other channel specific information into the - * chan structure - */ - if (conf->cir) { - - chan->cir = max_t(unsigned int, 1, - min_t(unsigned int, conf->cir, 512)); - chan->cir_status = CIR_ENABLED; - - - /* If CIR is enabled, force BC to equal CIR - * this solves number of potential problems if CIR is - * set and BC is not - */ - chan->bc = chan->cir; - - if (conf->be){ - chan->be = max_t(unsigned int, - 0, min_t(unsigned int, conf->be, 511)); - }else{ - conf->be = 0; - } - - printk (KERN_INFO "%s: CIR enabled for DLCI %i \n", - wandev->name,chan->dlci); - printk (KERN_INFO "%s: CIR = %i ; BC = %i ; BE = %i\n", - wandev->name,chan->cir,chan->bc,chan->be); - - - }else{ - chan->cir_status = CIR_DISABLED; - printk (KERN_INFO "%s: CIR disabled for DLCI %i\n", - wandev->name,chan->dlci); - } - - chan->mc = conf->mc; - - if (conf->inarp == WANOPT_YES){ - printk(KERN_INFO "%s: Inverse ARP Support Enabled\n",card->devname); - chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE; - chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10; - }else{ - printk(KERN_INFO "%s: Inverse ARP Support Disabled\n",card->devname); - chan->inarp = INARP_NONE; - chan->inarp_interval = 10; - } - - - chan->dlci_configured = DLCI_NOT_CONFIGURED; - - - /*FIXME: IPX disabled in this WANPIPE version */ - if (conf->enable_IPX == WANOPT_YES){ - printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n", - card->devname); - kfree(chan); - return -EINVAL; - }else{ - chan->enable_IPX = WANOPT_NO; - } - - if (conf->network_number){ - chan->network_number = conf->network_number; - }else{ - chan->network_number = 0xDEADBEEF; - } - - chan->route_flag = NO_ROUTE; - - init_chan_statistics(chan); - - chan->transmit_length = 0; - - /* prepare network device data space for registration */ - strcpy(dev->name,chan->name); - - dev->init = &if_init; - dev->priv = chan; - - /* Initialize FR Polling Task Queue - * We need a poll routine for each network - * interface. - */ - INIT_WORK(&chan->fr_poll_work, (void *)fr_poll, dev); - - init_timer(&chan->fr_arp_timer); - chan->fr_arp_timer.data=(unsigned long)dev; - chan->fr_arp_timer.function = fr_arp; - - wandev->new_if_cnt++; - - /* Tells us that if this interface is a - * gateway or not */ - if ((chan->gateway = conf->gateway) == WANOPT_YES){ - printk(KERN_INFO "%s: Interface %s is set as a gateway.\n", - card->devname,dev->name); - } - - /* M. Grant Patch Apr 28 2000 - * Disallow duplicate dlci configurations. */ - if (card->u.f.dlci_to_dev_map[chan->dlci] != NULL) { - kfree(chan); - return -EBUSY; - } - - /* Configure this dlci at a later date, when - * the interface comes up. i.e. when if_open() - * executes */ - set_bit(0,&chan->config_dlci); - - printk(KERN_INFO "\n"); - - return 0; -} - -/*============================================================================ - * Delete logical channel. - */ -static int del_if(struct wan_device* wandev, struct net_device* dev) -{ - fr_channel_t* chan = dev->priv; - unsigned long smp_flags=0; - - /* This interface is dead, make sure the - * ARP timer is stopped */ - del_timer(&chan->fr_arp_timer); - - /* If we are a NODE, we must unconfigure this DLCI - * Trigger an unconfigure command that will - * be executed in timer interrupt. We must wait - * for the command to complete. */ - trigger_unconfig_fr(dev); - - lock_adapter_irq(&wandev->lock, &smp_flags); - wandev->new_if_cnt--; - unlock_adapter_irq(&wandev->lock, &smp_flags); - - return 0; -} - - -/*===================================================================== - * disable_comm - * - * Description: - * Disable communications. - * This code runs in shutdown (sdlamain.c) - * under critical flag. Therefore it is not - * necessary to set a critical flag here - * - * Usage: |