📄 sdla_fr.c
字号:
/****************************************************************************** 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 0x20typedef 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -