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

📄 farsync.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *      FarSync WAN driver for Linux (2.6.x kernel version) * *      Actually sync driver for X.21, V.35 and V.24 on FarSync T-series cards * *      Copyright (C) 2001-2004 FarSite Communications Ltd. *      www.farsite.co.uk * *      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. * *      Author:      R.J.Dunlop    <bob.dunlop@farsite.co.uk> *      Maintainer:  Kevin Curtis  <kevin.curtis@farsite.co.uk> */#include <linux/module.h>#include <linux/kernel.h>#include <linux/version.h>#include <linux/pci.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/if.h>#include <linux/hdlc.h>#include <asm/io.h>#include <asm/uaccess.h>#include "farsync.h"/* *      Module info */MODULE_AUTHOR("R.J.Dunlop <bob.dunlop@farsite.co.uk>");MODULE_DESCRIPTION("FarSync T-Series WAN driver. FarSite Communications Ltd.");MODULE_PARM(fst_txq_low, "i");MODULE_PARM(fst_txq_high, "i");MODULE_PARM(fst_max_reads, "i");MODULE_PARM(fst_excluded_cards, "i");MODULE_PARM(fst_excluded_list, "0-32i");MODULE_LICENSE("GPL");/*      Driver configuration and global parameters *      ========================================== *//*      Number of ports (per card) and cards supported */#define FST_MAX_PORTS           4#define FST_MAX_CARDS           32/*      Default parameters for the link */#define FST_TX_QUEUE_LEN        100	/* At 8Mbps a longer queue length is					 * useful, the syncppp module forces					 * this down assuming a slower line I					 * guess.					 */#define FST_TXQ_DEPTH           16	/* This one is for the buffering					 * of frames on the way down to the card					 * so that we can keep the card busy					 * and maximise throughput					 */#define FST_HIGH_WATER_MARK     12	/* Point at which we flow control					 * network layer */#define FST_LOW_WATER_MARK      8	/* Point at which we remove flow					 * control from network layer */#define FST_MAX_MTU             8000	/* Huge but possible */#define FST_DEF_MTU             1500	/* Common sane value */#define FST_TX_TIMEOUT          (2*HZ)#ifdef ARPHRD_RAWHDLC#define ARPHRD_MYTYPE   ARPHRD_RAWHDLC	/* Raw frames */#else#define ARPHRD_MYTYPE   ARPHRD_HDLC	/* Cisco-HDLC (keepalives etc) */#endif/* * Modules parameters and associated varaibles */int fst_txq_low = FST_LOW_WATER_MARK;int fst_txq_high = FST_HIGH_WATER_MARK;int fst_max_reads = 7;int fst_excluded_cards = 0;int fst_excluded_list[FST_MAX_CARDS];/*      Card shared memory layout *      ========================= */#pragma pack(1)/*      This information is derived in part from the FarSite FarSync Smc.h *      file. Unfortunately various name clashes and the non-portability of the *      bit field declarations in that file have meant that I have chosen to *      recreate the information here. * *      The SMC (Shared Memory Configuration) has a version number that is *      incremented every time there is a significant change. This number can *      be used to check that we have not got out of step with the firmware *      contained in the .CDE files. */#define SMC_VERSION 24#define FST_MEMSIZE 0x100000	/* Size of card memory (1Mb) */#define SMC_BASE 0x00002000L	/* Base offset of the shared memory window main				 * configuration structure */#define BFM_BASE 0x00010000L	/* Base offset of the shared memory window DMA				 * buffers */#define LEN_TX_BUFFER 8192	/* Size of packet buffers */#define LEN_RX_BUFFER 8192#define LEN_SMALL_TX_BUFFER 256	/* Size of obsolete buffs used for DOS diags */#define LEN_SMALL_RX_BUFFER 256#define NUM_TX_BUFFER 2		/* Must be power of 2. Fixed by firmware */#define NUM_RX_BUFFER 8/* Interrupt retry time in milliseconds */#define INT_RETRY_TIME 2/*      The Am186CH/CC processors support a SmartDMA mode using circular pools *      of buffer descriptors. The structure is almost identical to that used *      in the LANCE Ethernet controllers. Details available as PDF from the *      AMD web site: http://www.amd.com/products/epd/processors/\ *                    2.16bitcont/3.am186cxfa/a21914/21914.pdf */struct txdesc {			/* Transmit descriptor */	volatile u16 ladr;	/* Low order address of packet. This is a				 * linear address in the Am186 memory space				 */	volatile u8 hadr;	/* High order address. Low 4 bits only, high 4				 * bits must be zero				 */	volatile u8 bits;	/* Status and config */	volatile u16 bcnt;	/* 2s complement of packet size in low 15 bits.				 * Transmit terminal count interrupt enable in				 * top bit.				 */	u16 unused;		/* Not used in Tx */};struct rxdesc {			/* Receive descriptor */	volatile u16 ladr;	/* Low order address of packet */	volatile u8 hadr;	/* High order address */	volatile u8 bits;	/* Status and config */	volatile u16 bcnt;	/* 2s complement of buffer size in low 15 bits.				 * Receive terminal count interrupt enable in				 * top bit.				 */	volatile u16 mcnt;	/* Message byte count (15 bits) */};/* Convert a length into the 15 bit 2's complement *//* #define cnv_bcnt(len)   (( ~(len) + 1 ) & 0x7FFF ) *//* Since we need to set the high bit to enable the completion interrupt this * can be made a lot simpler */#define cnv_bcnt(len)   (-(len))/* Status and config bits for the above */#define DMA_OWN         0x80	/* SmartDMA owns the descriptor */#define TX_STP          0x02	/* Tx: start of packet */#define TX_ENP          0x01	/* Tx: end of packet */#define RX_ERR          0x40	/* Rx: error (OR of next 4 bits) */#define RX_FRAM         0x20	/* Rx: framing error */#define RX_OFLO         0x10	/* Rx: overflow error */#define RX_CRC          0x08	/* Rx: CRC error */#define RX_HBUF         0x04	/* Rx: buffer error */#define RX_STP          0x02	/* Rx: start of packet */#define RX_ENP          0x01	/* Rx: end of packet *//* Interrupts from the card are caused by various events which are presented * in a circular buffer as several events may be processed on one physical int */#define MAX_CIRBUFF     32struct cirbuff {	u8 rdindex;		/* read, then increment and wrap */	u8 wrindex;		/* write, then increment and wrap */	u8 evntbuff[MAX_CIRBUFF];};/* Interrupt event codes. * Where appropriate the two low order bits indicate the port number */#define CTLA_CHG        0x18	/* Control signal changed */#define CTLB_CHG        0x19#define CTLC_CHG        0x1A#define CTLD_CHG        0x1B#define INIT_CPLT       0x20	/* Initialisation complete */#define INIT_FAIL       0x21	/* Initialisation failed */#define ABTA_SENT       0x24	/* Abort sent */#define ABTB_SENT       0x25#define ABTC_SENT       0x26#define ABTD_SENT       0x27#define TXA_UNDF        0x28	/* Transmission underflow */#define TXB_UNDF        0x29#define TXC_UNDF        0x2A#define TXD_UNDF        0x2B#define F56_INT         0x2C#define M32_INT         0x2D#define TE1_ALMA        0x30/* Port physical configuration. See farsync.h for field values */struct port_cfg {	u16 lineInterface;	/* Physical interface type */	u8 x25op;		/* Unused at present */	u8 internalClock;	/* 1 => internal clock, 0 => external */	u8 transparentMode;	/* 1 => on, 0 => off */	u8 invertClock;		/* 0 => normal, 1 => inverted */	u8 padBytes[6];		/* Padding */	u32 lineSpeed;		/* Speed in bps */};/* TE1 port physical configuration */struct su_config {	u32 dataRate;	u8 clocking;	u8 framing;	u8 structure;	u8 interface;	u8 coding;	u8 lineBuildOut;	u8 equalizer;	u8 transparentMode;	u8 loopMode;	u8 range;	u8 txBufferMode;	u8 rxBufferMode;	u8 startingSlot;	u8 losThreshold;	u8 enableIdleCode;	u8 idleCode;	u8 spare[44];};/* TE1 Status */struct su_status {	u32 receiveBufferDelay;	u32 framingErrorCount;	u32 codeViolationCount;	u32 crcErrorCount;	u32 lineAttenuation;	u8 portStarted;	u8 lossOfSignal;	u8 receiveRemoteAlarm;	u8 alarmIndicationSignal;	u8 spare[40];};/* Finally sling all the above together into the shared memory structure. * Sorry it's a hodge podge of arrays, structures and unused bits, it's been * evolving under NT for some time so I guess we're stuck with it. * The structure starts at offset SMC_BASE. * See farsync.h for some field values. */struct fst_shared {	/* DMA descriptor rings */	struct rxdesc rxDescrRing[FST_MAX_PORTS][NUM_RX_BUFFER];	struct txdesc txDescrRing[FST_MAX_PORTS][NUM_TX_BUFFER];	/* Obsolete small buffers */	u8 smallRxBuffer[FST_MAX_PORTS][NUM_RX_BUFFER][LEN_SMALL_RX_BUFFER];	u8 smallTxBuffer[FST_MAX_PORTS][NUM_TX_BUFFER][LEN_SMALL_TX_BUFFER];	u8 taskStatus;		/* 0x00 => initialising, 0x01 => running,				 * 0xFF => halted				 */	u8 interruptHandshake;	/* Set to 0x01 by adapter to signal interrupt,				 * set to 0xEE by host to acknowledge interrupt				 */	u16 smcVersion;		/* Must match SMC_VERSION */	u32 smcFirmwareVersion;	/* 0xIIVVRRBB where II = product ID, VV = major				 * version, RR = revision and BB = build				 */	u16 txa_done;		/* Obsolete completion flags */	u16 rxa_done;	u16 txb_done;	u16 rxb_done;	u16 txc_done;	u16 rxc_done;	u16 txd_done;	u16 rxd_done;	u16 mailbox[4];		/* Diagnostics mailbox. Not used */	struct cirbuff interruptEvent;	/* interrupt causes */	u32 v24IpSts[FST_MAX_PORTS];	/* V.24 control input status */	u32 v24OpSts[FST_MAX_PORTS];	/* V.24 control output status */	struct port_cfg portConfig[FST_MAX_PORTS];	u16 clockStatus[FST_MAX_PORTS];	/* lsb: 0=> present, 1=> absent */	u16 cableStatus;	/* lsb: 0=> present, 1=> absent */	u16 txDescrIndex[FST_MAX_PORTS];	/* transmit descriptor ring index */	u16 rxDescrIndex[FST_MAX_PORTS];	/* receive descriptor ring index */	u16 portMailbox[FST_MAX_PORTS][2];	/* command, modifier */	u16 cardMailbox[4];	/* Not used */	/* Number of times the card thinks the host has	 * missed an interrupt by not acknowledging	 * within 2mS (I guess NT has problems)	 */	u32 interruptRetryCount;	/* Driver private data used as an ID. We'll not	 * use this as I'd rather keep such things	 * in main memory rather than on the PCI bus	 */	u32 portHandle[FST_MAX_PORTS];	/* Count of Tx underflows for stats */	u32 transmitBufferUnderflow[FST_MAX_PORTS];	/* Debounced V.24 control input status */	u32 v24DebouncedSts[FST_MAX_PORTS];	/* Adapter debounce timers. Don't touch */	u32 ctsTimer[FST_MAX_PORTS];	u32 ctsTimerRun[FST_MAX_PORTS];	u32 dcdTimer[FST_MAX_PORTS];	u32 dcdTimerRun[FST_MAX_PORTS];	u32 numberOfPorts;	/* Number of ports detected at startup */	u16 _reserved[64];	u16 cardMode;		/* Bit-mask to enable features:				 * Bit 0: 1 enables LED identify mode				 */	u16 portScheduleOffset;	struct su_config suConfig;	/* TE1 Bits */	struct su_status suStatus;	u32 endOfSmcSignature;	/* endOfSmcSignature MUST be the last member of				 * the structure and marks the end of shared				 * memory. Adapter code initializes it as				 * END_SIG.				 */};/* endOfSmcSignature value */#define END_SIG                 0x12345678/* Mailbox values. (portMailbox) */#define NOP             0	/* No operation */#define ACK             1	/* Positive acknowledgement to PC driver */#define NAK             2	/* Negative acknowledgement to PC driver */#define STARTPORT       3	/* Start an HDLC port */#define STOPPORT        4	/* Stop an HDLC port */#define ABORTTX         5	/* Abort the transmitter for a port */#define SETV24O         6	/* Set V24 outputs *//* PLX Chip Register Offsets */#define CNTRL_9052      0x50	/* Control Register */#define CNTRL_9054      0x6c	/* Control Register */#define INTCSR_9052     0x4c	/* Interrupt control/status register */#define INTCSR_9054     0x68	/* Interrupt control/status register *//* 9054 DMA Registers *//* * Note that we will be using DMA Channel 0 for copying rx data * and Channel 1 for copying tx data */#define DMAMODE0        0x80#define DMAPADR0        0x84#define DMALADR0        0x88#define DMASIZ0         0x8c#define DMADPR0         0x90#define DMAMODE1        0x94#define DMAPADR1        0x98#define DMALADR1        0x9c#define DMASIZ1         0xa0#define DMADPR1         0xa4#define DMACSR0         0xa8#define DMACSR1         0xa9#define DMAARB          0xac#define DMATHR          0xb0#define DMADAC0         0xb4#define DMADAC1         0xb8#define DMAMARBR        0xac#define FST_MIN_DMA_LEN 64#define FST_RX_DMA_INT  0x01#define FST_TX_DMA_INT  0x02#define FST_CARD_INT    0x04/* Larger buffers are positioned in memory at offset BFM_BASE */struct buf_window {	u8 txBuffer[FST_MAX_PORTS][NUM_TX_BUFFER][LEN_TX_BUFFER];	u8 rxBuffer[FST_MAX_PORTS][NUM_RX_BUFFER][LEN_RX_BUFFER];};/* Calculate offset of a buffer object within the shared memory window */#define BUF_OFFSET(X)   ((unsigned int)&(((struct buf_window *)BFM_BASE)->X))#pragma pack()/*      Device driver private information *      ================================= *//*      Per port (line or channel) information */struct fst_port_info {        struct net_device *dev; /* Device struct - must be first */	struct fst_card_info *card;	/* Card we're associated with */	int index;		/* Port index on the card */	int hwif;		/* Line hardware (lineInterface copy) */	int run;		/* Port is running */	int mode;		/* Normal or FarSync raw */	int rxpos;		/* Next Rx buffer to use */	int txpos;		/* Next Tx buffer to use */	int txipos;		/* Next Tx buffer to check for free */	int start;		/* Indication of start/stop to network */	/*	 * A sixteen entry transmit queue	 */	int txqs;		/* index to get next buffer to tx */	int txqe;		/* index to queue next packet */	struct sk_buff *txq[FST_TXQ_DEPTH];	/* The queue */	int rxqdepth;};/*      Per card information */struct fst_card_info {	char *mem;		/* Card memory mapped to kernel space */	char *ctlmem;		/* Control memory for PCI cards */	unsigned int phys_mem;	/* Physical memory window address */	unsigned int phys_ctlmem;	/* Physical control memory address */	unsigned int irq;	/* Interrupt request line number */	unsigned int nports;	/* Number of serial ports */	unsigned int type;	/* Type index of card */	unsigned int state;	/* State of card */	spinlock_t card_lock;	/* Lock for SMP access */	unsigned short pci_conf;	/* PCI card config in I/O space */	/* Per port info */	struct fst_port_info ports[FST_MAX_PORTS];	struct pci_dev *device;	/* Information about the pci device */	int card_no;		/* Inst of the card on the system */	int family;		/* TxP or TxU */	int dmarx_in_progress;	int dmatx_in_progress;	unsigned long int_count;	unsigned long int_time_ave;	void *rx_dma_handle_host;	dma_addr_t rx_dma_handle_card;	void *tx_dma_handle_host;	dma_addr_t tx_dma_handle_card;	struct sk_buff *dma_skb_rx;	struct fst_port_info *dma_port_rx;	struct fst_port_info *dma_port_tx;	int dma_len_rx;	int dma_len_tx;	int dma_txpos;	int dma_rxpos;};/* Convert an HDLC device pointer into a port info pointer and similar */#define dev_to_port(D)  (dev_to_hdlc(D)->priv)#define port_to_dev(P)  ((P)->dev)/* *      Shared memory window access macros * *      We have a nice memory based structure above, which could be directly *      mapped on i386 but might not work on other architectures unless we use *      the readb,w,l and writeb,w,l macros. Unfortunately these macros take

⌨️ 快捷键说明

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