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

📄 comx-hw-munich.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Hardware-level driver for the SliceCOM board for Linux kernels 2.4.X * * Current maintainer / latest changes: Pasztor Szilard <don@itc.hu> * * Original author: Bartok Istvan <bartoki@itc.hu> * Based on skeleton by Tivadar Szemethy <tiv@itc.hu> * * 0.51: *      - port for 2.4.x *	- clean up some code, make it more portable *	- busted direct hardware access through mapped memory *	- fix a possible race *	- prevent procfs buffer overflow * * 0.50: *	- support for the pcicom board, lots of rearrangements *	- handle modem status lines * * 0.50a: *	- fix for falc version 1.0 * * 0.50b: T&t *	- fix for bad localbus */#define VERSION		"0.51"#define VERSIONSTR	"SliceCOM v" VERSION ", 2002/01/07\n"#include <linux/config.h>#include <linux/ctype.h>#include <linux/module.h>#include <linux/version.h>#include <linux/types.h>#include <linux/sched.h>#include <linux/netdevice.h>#include <linux/proc_fs.h>#include <asm/delay.h>#include <asm/types.h>#include <asm/uaccess.h>#include <asm/io.h>#include <linux/ioport.h>#include <linux/pci.h>#include <linux/init.h>#define COMX_NEW#ifndef COMX_NEW#include "../include/comx.h"#include "../include/munich32x.h"#include "../include/falc-lh.h"#else#include "comx.h"#include "munich32x.h"#include "falc-lh.h"#endifMODULE_AUTHOR("Bartok Istvan <bartoki@itc.hu>, Gergely Madarasz <gorgo@itc.hu>, Szilard Pasztor <don@itc.hu>");MODULE_DESCRIPTION("Hardware-level driver for the SliceCOM and PciCOM (WelCOM) adapters");MODULE_LICENSE("GPL");/* *	TODO: az ilyenek a comxhw.h -ban szoktak lenni, idovel menjenek majd oda: */#define FILENAME_BOARDNUM	"boardnum"	/* /proc/comx/comx0.1/boardnum          */#define FILENAME_TIMESLOTS	"timeslots"	/* /proc/comx/comx0.1/timeslots         */#define FILENAME_FRAMING	"framing"	/* /proc/comx/comx0.1/framing           */#define FILENAME_LINECODE	"linecode"	/* /proc/comx/comx0.1/linecode          */#define FILENAME_CLOCK_SOURCE	"clock_source"	/* /proc/comx/comx0.1/clock_source      */#define FILENAME_LOOPBACK	"loopback"	/* /proc/comx/comx0.1/loopback          */#define FILENAME_REG		"reg"		/* /proc/comx/comx0.1/reg               */#define FILENAME_LBIREG		"lbireg"	/* /proc/comx/comx0.1/lbireg            */#define SLICECOM_BOARDNUM_DEFAULT	0#define SLICECOM_FRAMING_CRC4		1#define SLICECOM_FRAMING_NO_CRC4	2#define SLICECOM_FRAMING_DEFAULT	SLICECOM_FRAMING_CRC4#define SLICECOM_LINECODE_HDB3		1#define SLICECOM_LINECODE_AMI		2#define SLICECOM_LINECODE_DEFAULT	SLICECOM_LINECODE_HDB3#define SLICECOM_CLOCK_SOURCE_LINE	1#define SLICECOM_CLOCK_SOURCE_INTERNAL	2#define SLICECOM_CLOCK_SOURCE_DEFAULT	SLICECOM_CLOCK_SOURCE_LINE#define SLICECOM_LOOPBACK_NONE		1#define SLICECOM_LOOPBACK_LOCAL		2#define SLICECOM_LOOPBACK_REMOTE	3#define SLICECOM_LOOPBACK_DEFAULT	SLICECOM_LOOPBACK_NONE#define MUNICH_VIRT(addr) (void *)(&bar1[addr])struct slicecom_stringtable{    char *name;    int value;};/* A convention: keep "default" the last not NULL when reading from /proc,   "error" is an indication that something went wrong, we have an undefined value */struct slicecom_stringtable slicecom_framings[] ={    {"crc4", SLICECOM_FRAMING_CRC4},    {"no-crc4", SLICECOM_FRAMING_NO_CRC4},    {"default", SLICECOM_FRAMING_DEFAULT},    {"error", 0}};struct slicecom_stringtable slicecom_linecodes[] ={    {"hdb3", SLICECOM_LINECODE_HDB3},    {"ami", SLICECOM_LINECODE_AMI},    {"default", SLICECOM_LINECODE_DEFAULT},    {"error", 0}};struct slicecom_stringtable slicecom_clock_sources[] ={    {"line", SLICECOM_CLOCK_SOURCE_LINE},    {"internal", SLICECOM_CLOCK_SOURCE_INTERNAL},    {"default", SLICECOM_CLOCK_SOURCE_DEFAULT},    {"error", 0}};struct slicecom_stringtable slicecom_loopbacks[] ={    {"none", SLICECOM_LOOPBACK_NONE},    {"local", SLICECOM_LOOPBACK_LOCAL},    {"remote", SLICECOM_LOOPBACK_REMOTE},    {"default", SLICECOM_LOOPBACK_DEFAULT},    {"error", 0}};/* *	Some tunable values... * *	Note: when tuning values which change the length of text in *	/proc/comx/comx[n]/status, keep in mind that it must be shorter then *	PAGESIZE ! */#define MAX_BOARDS	4	/* ezzel 4 kartya lehet a gepben: 0..3          */#define RX_DESC_MAX	8	/* Rx ring size, must be >= 4                   */#define TX_DESC_MAX	4	/* Tx ring size, must be >= 2                   */				/* a sokkal hosszabb Tx ring mar ronthatja a nem-FIFO packet    */				/* schedulerek (fair queueing, stb.) hatekonysagat.             */#define MAX_WORK	10	/* TOD: update the info max. ennyi-1 esemenyt dolgoz fel egy interrupt hivasnal *//* *	These are tunable too, but don't touch them without fully understanding what is happening */#define UDELAY		20	/* We wait UDELAY usecs with disabled interrupts before and     */				/* after each command to avoid writing into each other's        */				/* ccb->action_spec. A _send_packet nem var, mert azt az        */				/* _interrupt()-bol is meghivhatja a LINE_tx()                  *//* *	Just to avoid warnings about implicit declarations: */static int MUNICH_close(struct net_device *dev);static struct comx_hardware slicecomhw;static struct comx_hardware pcicomhw;static unsigned long flags;static spinlock_t mister_lock = SPIN_LOCK_UNLOCKED;typedef volatile struct		/* Time Slot Assignment */{    u32 rxfillmask:8,		// ----------------------------+------+				//                             |      |      rxchannel:5,		// ----------------------+---+ |      |      rti:1,			// ---------------------+|   | |      |      res2:2,			// -------------------++||   | |      |				//                    ||||   | |      |      txfillmask:8,		// ----------+------+ ||||   | |      |				//           |      | ||||   | |      |      txchannel:5,		// ----+---+ |      | ||||   | |      |      tti:1,			// ---+|   | |      | ||||   | |      |      res1:2;			// -++||   | |      | ||||   | |      |				//   3          2          1    				//  10987654 32109876 54321098 76543210} timeslot_spec_t;typedef volatile struct		/* Receive Descriptor */{    u32 zero1:16, no:13, hi:1, hold:1, zero2:1;    u32 next;    u32 data;    u32 zero3:8, status:8, bno:13, zero4:1, c:1, fe:1;} rx_desc_t;typedef volatile struct		/* Transmit Descriptor */{    u32 fnum:11, csm:1, no13:1, zero1:2, v110:1, no:13, hi:1, hold:1, fe:1;    u32 next;    u32 data;} tx_desc_t;typedef volatile struct		/* Channel Specification */{    u32 iftf:1, mode:2, fa:1, trv:2, crc:1, inv:1, cs:1, tflag:7, ra:1, ro:1,	th:1, ta:1, to:1, ti:1, ri:1, nitbs:1, fit:1, fir:1, re:1, te:1, ch:1,	ifc:1, sfe:1, fe2:1;    u32 frda;    u32 ftda;    u32 itbs:6, zero1:26;} channel_spec_t;typedef volatile struct		/* Configuration Control Block */{    u32 action_spec;    u32 reserved1;    u32 reserved2;    timeslot_spec_t timeslot_spec[32];    channel_spec_t channel_spec[32];    u32 current_rx_desc[32];    u32 current_tx_desc[32];    u32 csa;			/* Control Start Address. CSA = *CCBA; CCB = *CSA */				/* MUNICH does it like: CCB = *( *CCBA )          */} munich_ccb_t;typedef volatile struct		/* Entry in the interrupt queue */{    u32 all;} munich_intq_t;#define MUNICH_INTQLEN	63	/* Rx/Tx Interrupt Queue Length				   (not the real len, but the TIQL/RIQL value)  */#define MUNICH_INTQMAX	( 16*(MUNICH_INTQLEN+1) )	/* Rx/Tx/Periph Interrupt Queue size in munich_intq_t's */#define MUNICH_INTQSIZE	( 4*MUNICH_INTQMAX )	/* Rx/Tx/Periph Interrupt Queue size in bytes           */#define MUNICH_PIQLEN	4	/* Peripheral Interrupt Queue Length. Unlike the RIQL/TIQL, */#define MUNICH_PIQMAX	( 4*MUNICH_PIQLEN )	/* PIQL register needs it like this                     */#define MUNICH_PIQSIZE	( 4*MUNICH_PIQMAX )typedef volatile u32 vol_u32;	/* TOD: ezek megszunnek ha atirom readw()/writew()-re - k閟z */typedef volatile u8 vol_u8;typedef volatile struct		/* counters of E1-errors and errored seconds, see rfc2495 */{    /* use here only unsigned ints, we depend on it when calculating the sum for the last N intervals */    unsigned line_code_violations,	/* AMI: bipolar violations, HDB3: hdb3 violations                       */      path_code_violations,	/* FAS errors and CRC4 errors                                                   */      e_bit_errors,		/* E-Bit Errors (the remote side received from us with CRC4-error) */      slip_secs,		/* number of seconds with (receive) Controlled Slip(s)          */      fr_loss_secs,		/* number of seconds an Out Of Frame defect was detected                */      line_err_secs,		/* number of seconds with one or more Line Code Violations              */      degraded_mins,		/* Degraded Minute - the estimated error rate is >1E-6, but <1E-3       */      errored_secs,		/* Errored Second - at least one of these happened:				   - Path Code Violation				   - Out Of Frame defect				   - Slip				   - receiving AIS				   - not incremented during an Unavailable Second                       */      bursty_err_secs,		/* Bursty Errored Second: (rfc2495 says it does not apply to E1)				   - Path Code Violations >1, but <320				   - not a Severely Errored Second				   - no AIS				   - not incremented during an Unavailabla Second                       */      severely_err_secs,	/* Severely Errored Second:				   - CRC4: >=832 Path COde Violations || >0 Out Of Frame defects				   - noCRC4: >=2048 Line Code Violations				   - not incremented during an Unavailable Second                       */      unavail_secs;		/* number of Unavailable Seconds. Unavailable state is said after:				   - 10 contiguous Severely Errored Seconds				   - or RAI || AIS || LOF || LOS 				   - (any) loopback has been set                                                */    /*     * we do not strictly comply to the rfc: we do not retroactively reduce errored_secs,     * bursty_err_secs, severely_err_secs when 'unavailable state' is reached     */} e1_stats_t;typedef volatile struct		/* ezek board-adatok, nem lehetnek a slicecom_privdata -ban     */{    int use_count;		/* num. of interfaces using the board                           */    int irq;			/* a kartya irq-ja. belemasoljuk a dev->irq -kba is, de csak hogy       */    /* szebb legyen az ifconfig outputja                            */    /* ha != 0, az azt jelenti hogy az az irq most nekunk sikeresen */    /* le van foglalva                                              */    struct pci_dev *pci;	/* a kartya PCI strukturaja. NULL, ha nincs kartya              */    u32 *bar1;			/* pci->base_address[0] ioremap()-ed by munich_probe(),         */    /* on x86 can be used both as a bus or virtual address.         */    /* These are the Munich's registers                             */    u8 *lbi;			/* pci->base_address[1] ioremap()-ed by munich_probe(),         */    /* this is a 256-byte range, the start of the LBI on the board  */    munich_ccb_t *ccb;		/* virtual address of CCB                                       */    munich_intq_t *tiq;		/* Tx Interrupt Queue                                           */    munich_intq_t *riq;		/* Rx Interrupt Queue                                           */    munich_intq_t *piq;		/* Peripheral Interrupt Queue (FALC interrupts arrive here)     */    int tiq_ptr,		/* A 'current' helyek a tiq/riq/piq -ban.                       */      riq_ptr,			/* amikor feldolgoztam az interruptokat, a legelso ures         */      piq_ptr;			/* interrupt_information szora mutatnak.                        */    struct net_device *twins[32];	/* MUNICH channel -> network interface assignment       */    unsigned long lastcheck;	/* When were the Rx rings last checked. Time in jiffies         */    struct timer_list modemline_timer;    char isx21;    char lineup;    char framing;		/* a beallitasok tarolasa                               */    char linecode;    char clock_source;    char loopback;    char devname[30];		/* what to show in /proc/interrupts                     */    unsigned histogram[MAX_WORK];	/* number of processed events in the interrupt loop     */    unsigned stat_pri_races;	/* number of special events, we try to handle them      */    unsigned stat_pti_races;    unsigned stat_pri_races_missed;	/* when it can not be handled, because of MAX_WORK      */    unsigned stat_pti_races_missed;#define SLICECOM_BOARD_INTERVALS_SIZE	97    e1_stats_t intervals[SLICECOM_BOARD_INTERVALS_SIZE];	/* E1 line statistics           */    unsigned current_interval;	/* pointer to the current interval                      */    unsigned elapsed_seconds;	/* elapsed seconds from the start of the current interval */    unsigned ses_seconds;	/* counter of contiguous Severely Errored Seconds       */    unsigned is_unavailable;	/* set to 1 after 10 contiguous Severely Errored Seconds */    unsigned no_ses_seconds;	/* contiguous Severely Error -free seconds in unavail state */    unsigned deg_elapsed_seconds;	/* for counting the 'Degraded Mins'                     */    unsigned deg_cumulated_errors;    struct module *owner;	/* pointer to our module to avoid module load races */} munich_board_t;struct slicecom_privdata{    int busy;			/* transmitter busy - number of packets in the Tx ring  */    int channel;		/* Munich logical channel ('channel-group' in Cisco)    */    unsigned boardnum;    u32 timeslots;		/* i-th bit means i-th timeslot is our                  */    int tx_ring_hist[TX_DESC_MAX];	/* histogram: number of packets in Tx ring when _send_packet is called  */    tx_desc_t tx_desc[TX_DESC_MAX];	/* the ring of Tx descriptors                           */    u8 tx_data[TX_DESC_MAX][TXBUFFER_SIZE];	/* buffers for data to transmit                 */    int tx_desc_ptr;		/* hanyadik descriptornal tartunk a beirassal   */    /* ahol ez all, oda irtunk utoljara                     */    rx_desc_t rx_desc[RX_DESC_MAX];	/* the ring of Rx descriptors                           */    u8 rx_data[RX_DESC_MAX][RXBUFFER_SIZE];	/* buffers for received data                            */    int rx_desc_ptr;		/* hanyadik descriptornal tartunk az olvasassal */    int rafutott;};static u32 reg, reg_ertek;	/* why static: don't write stack trash into regs if strtoul() fails */static u32 lbireg;static u8 lbireg_ertek;		/* why static: don't write stack trash into regs if strtoul() fails */static munich_board_t slicecom_boards[MAX_BOARDS];static munich_board_t pcicom_boards[MAX_BOARDS];/* * Reprogram Idle Channel Registers in the FALC - send special code in not used channels * Should be called from the open and close, when the timeslot assignment changes */void rework_idle_channels(struct net_device *dev){    struct comx_channel *ch = dev->priv;    struct slicecom_privdata *hw = ch->HW_privdata;    munich_board_t *board = slicecom_boards + hw->boardnum;    munich_ccb_t *ccb = board->ccb;    u8 *lbi = board->lbi;    int i, j, tmp;    spin_lock_irqsave(&mister_lock, flags);    for (i = 0; i < 4; i++)    {	tmp = 0xFF;	for (j = 0; j < 8; j++)	    if (ccb->timeslot_spec[8 * i + j].tti == 0) tmp ^= (0x80 >> j);	writeb(tmp, lbi + 0x30 + i);    }    spin_unlock_irqrestore(&mister_lock, flags);}/* * Set PCM framing - /proc/comx/comx0/framing */void slicecom_set_framing(int boardnum, int value)

⌨️ 快捷键说明

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