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

📄 device.c

📁 powerpc82xx mcc driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * device.c - mcc driver: bottom half side  *  * (C) Copyright 2002 * Gianfranco Morandi, Eurostudio s.r.l., gianfranco.morandi@euro-studio.it * See file CREDITS for list of people who contributed to this * project. * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA         * *  * 			   */#ifndef __KERNEL__#  define __KERNEL__#endif#ifndef MODULE#  define MODULE#endif#include <linux/kernel.h>#include <linux/fs.h>#include <linux/delay.h>#include <linux/param.h>#include <linux/module.h>#include <linux/sched.h>#include <asm/semaphore.h>#include <asm/io.h>#include <asm/system.h>#include <linux/time.h>#include <linux/malloc.h>#include "mcc.h"           /* Local header file */    #include "mpc8260.h"       /* IMM definitions and declarations */#include "mccIOC.h"/*--------------------------------------------------------------------------------- *								Global variables *--------------------------------------------------------------------------------- */volatile t_PQ2IMM *IMM;          /* Internal Memory Map base pointer */VUBYTE SI;              /* Which SI is in use for this example */VUBYTE MCC;             /* Which MCC is in use for this example *//* read & write handshaking (non volevo farlo cosi' !)*/extern int writeNow[BUFFER_SIZE];extern int valid[BUFFER_SIZE];extern int readNow[BUFFER_SIZE];/* buffer descriptors base pointer*/extern BDRINGS *RxTxBD;/*	TxRx data buffer */extern unsigned char *BufferPool;/* TxRx interrupt queue*/extern  unsigned int *txIntCQ;extern  unsigned int *rxIntCQ;/* spin lock variable*/extern spinlock_t lock;/* data stream read and write buffer*/extern FrameBuffer *ReadBuffer;extern FrameBuffer *WriteBuffer;/*--------------------------------------------------------------------------------- *								Function prototypes  *--------------------------------------------------------------------------------- */void    InitBDs(unsigned int,UBYTE);void    MCCGlobalInit(void);void    MCCChanSpecInit(UHWORD,UBYTE);void    MCCExChanSpecInit(unsigned int,UHWORD,UHWORD);void    InitTxRxParams(UHWORD);void    SIinit(void);void    startTxRx(void);void    stopTxRx(void);void 	mainInitMCC(unsigned int );void 	mcc_ISR(int , void *, struct pt_regs *);void 	BDsStatus(unsigned char, unsigned char, unsigned short *, unsigned short *, unsigned int *);void 	SiRamStatus(unsigned char,unsigned char*,unsigned char*,unsigned char*,unsigned short*,			unsigned short*,unsigned short*,unsigned char*,unsigned short*,unsigned short*,unsigned short*);void 	CpmReadRegisters(CPM_STATUS_IOC *);void 	getFrame(unsigned int, unsigned short);void 	sendFrame(unsigned int, unsigned short);void 	restoreBDs(unsigned short);void 	RestartServiceRoutine(void);void 	stopCpmMcc(unsigned char mcn);extern void mccFasync(void);/*--------------------------------------------------------------------------------- *								Functions  *--------------------------------------------------------------------------------- */ /* * Name: *	mainInitMCC * Description: *	main MCC and SI init */void mainInitMCC(unsigned int BASE_ADDR){	unsigned int chnOffset,chnNum;			/* work with MCC1,SI1 and TDMC	*/    SI = SI1;    MCC = MCC1;                   //TDM = TDMC;	/* pointer to MPC8260 internal memory map.	*/    IMM = (t_PQ2IMM *)(BASE_ADDR);	/*Initialize SI RAM : TDM1C and TDM1D routing	*/    SIinit();	/*Initialize TxRxBDs	*/	chnOffset = 0;	for(chnNum = CHNSTART;chnNum < (CHNSTART+NUMBER_OF_CHANNELS);chnNum++){		InitBDs(chnOffset,TRAN_NOTSUPERCHAN);		chnOffset+=NUM_RXBDS;		}			/*Initialize Global parameters	*/    MCCGlobalInit(); 		/*Initialize Extra Channel Specific parameters	*/	chnOffset = 0;	for(chnNum = CHNSTART;chnNum < (CHNSTART+NUMBER_OF_CHANNELS);chnNum++){		MCCExChanSpecInit(chnNum,chnOffset+TxBDSOFFSET,chnOffset);		chnOffset+=NUM_RXBDS;		}    /* Initialize Channel Specific parameters    */     for(chnNum = CHNSTART;chnNum < (CHNSTART+NUMBER_OF_CHANNELS);chnNum++){    	MCCChanSpecInit(chnNum,TRAN_NOTSUPERCHAN);	}} /* mainInitMCC *//* * Name: *	startTxRx * Description: *	start TDM */void startTxRx(){	/* Issue Init RX & TX Parameters Command for MCC1	*/    InitTxRxParams(64);    InitTxRxParams(96);     /* Enable TDM1C and TDM1D    */	IMM->si_regs[SI].sigmr = 0x0c; }/* * Name: *	stopTxRx * Description: *	stop TDM */void stopTxRx(){	unsigned char mcn;	/* Disable TDM1C and TDM1D    */	IMM->si_regs[SI].sigmr = 0x00;	/* stop CPM	*/	for(mcn = CHNSTART; mcn<(CHNSTART+NUMBER_OF_CHANNELS);mcn++) 		stopCpmMcc(mcn);} /* end of stopTxRx *//* * Name: *	stopCpmMcc * Description: *	stop MCC  */void stopCpmMcc(unsigned char mcn){    volatile unsigned int psbc;        if (MCC == MCC1)     	psbc = CPCR_MCC1_PSBC;    else    psbc = CPCR_MCC2_PSBC;   	while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD);     IMM->cpm_cpcr = CPCR_MCC_STOP_TX |                 psbc |                   (mcn<<6)|                 CPCR_FLG;              /* ISSUE COMMAND */    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD);	 	    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD);     IMM->cpm_cpcr = CPCR_MCC_STOP_RX |                 psbc |                   (mcn<<6)|                 CPCR_FLG;              /* ISSUE COMMAND */    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD);}/* * Name: *	SIinit * Description: *	SI ram entries configuration */void SIinit(){	unsigned short chnNum;	unsigned int count;		chnNum = CHNSTART; /*chnannel 64 */		/* SI1 entries for TDM1C	*/	for(count=0;count < 32;count++){		IMM->si_ram[SI].tx_siram[count] = 0x8002 | (chnNum << 5); /* see page 14-13*/		IMM->si_ram[SI].rx_siram[count] = 0x8002 | (chnNum << 5);		if(count == 31){			IMM->si_ram[SI].tx_siram[count] = 0x8003 | (chnNum << 5); /* see page 14-13*/			IMM->si_ram[SI].rx_siram[count] = 0x8003 | (chnNum << 5);		}		chnNum++;		    }	/* SI1 entries for TDM1D	*/	for(count=0;count < 32;count++){		IMM->si_ram[SI].tx_siram[count+64] = 0x8002 | (chnNum << 5); /* see page 14-13*/		IMM->si_ram[SI].rx_siram[count+64] = 0x8002 | (chnNum << 5);		if(count == 31){			IMM->si_ram[SI].tx_siram[count+64] = 0x8003 | (chnNum << 5); /* see page 14-13*/			IMM->si_ram[SI].rx_siram[count+64] = 0x8003 | (chnNum << 5);		}		chnNum++;		    }     IMM->si_regs[SI].sixmr[TDMC] = 0x0040;  /* 0 offset for SIRAM 1cond bank 1st 32 entries, CRT */    IMM->si_regs[SI].sixmr[TDMD] = 0x2040;  /* 64 offset for SIRAM 2cond bank 1st 32 entries, CRT */} /* SIinit *//* * Name: *	InitBDs * Description: *	Init Tx and Rx BDs */void InitBDs(unsigned int offset, UBYTE mode){   unsigned int index;unsigned int addr;   	/* Initialize RxBDs   	*/	for (index = 0; index < NUM_RXBDS; index++){		if( index != (NUM_RXBDS-1) ){/* If not the last RxBD for this channel */    		RxTxBD->RxBD[index+offset].bd_cstatus = 0x9000; /* Empty, Interrupt */ /* old 0x9000 */		} else {/* if last RxBD for this channel */        	RxTxBD->RxBD[index+offset].bd_cstatus = 0xB000; /* Empty, Interrupt,Wrap */    	}      	RxTxBD->RxBD[index+offset].bd_length = 0;/* clear the buffer length */      	/*address of receive area */      	addr = (unsigned int )BufferPool + BUFFER_SIZE*NUMBER_OF_CHANNELS*NUM_TXBDS + (offset+index)*BUFFER_SIZE;      	RxTxBD->RxBD[index+offset].bd_addr =(unsigned int )( addr - (unsigned int )PAGE_OFFSET );	}/* end for loop initializing RxBDs */ 	/* Initialize TxBDs	*/	for (index=0; index < NUM_TXBDS; index++){		if( index != (NUM_TXBDS-1) ) { /* If not the last TxBD for this channel */        	RxTxBD->TxBD[index+offset].bd_cstatus = 0x8000; /* Set Ready bit */                  	/*----------------------------------------------------*/         	/* If this channel is HDLC, also set Last and TC bits */         	/*----------------------------------------------------*/                  	/*if ( (mode == HDLC_NOTSUPERCHAN) || (mode == HDLC_SUPERCHAN) )            	RxTxBD->TxBD[index+offset].bd_cstatus |= 0x0C00;     */         			} else { /* if last TxBD for this channel */			RxTxBD->TxBD[index+offset].bd_cstatus = 0xA000;/* Set Ready, Wrap bits */         /*----------------------------------------------------*/         /* If this channel is HDLC, also set Last and TC bits */         /*----------------------------------------------------*/                  /*if ( (mode == HDLC_NOTSUPERCHAN) || (mode == HDLC_SUPERCHAN) )            RxTxBD->TxBD[index+offset].bd_cstatus |= 0x0C00;*/           	}            /* load the buffer length       */	  	      //if ( (mode == HDLC_NOTSUPERCHAN) || (mode == HDLC_SUPERCHAN) )            /* if this channel is HDLC */      //{      //   RxTxBD->TxBD[index+offset].bd_length = (BUFFER_SIZE-4);        //}           // else  /* Transparent */            RxTxBD->TxBD[index+offset].bd_length = (BUFFER_SIZE);/* set buffer length */      addr = ( (unsigned int ) BufferPool+(offset+index)*BUFFER_SIZE);      RxTxBD->TxBD[index+offset].bd_addr = (unsigned int )( addr - (unsigned int )PAGE_OFFSET);/* set address to point tx area */         }} /* end InitBDs *//* * Name: *	MCCGlobalInit * Description: *	configure MCC global parameter */void MCCGlobalInit(){	unsigned int addr;/* set up abbreviated pointer */t_Mcc_Pram* MCCglobal;	MCCglobal = (t_Mcc_Pram * ) &(IMM->pram.serials.mcc_pram[MCC]);         	addr = (unsigned int ) RxTxBD;      MCCglobal->mccbase  = addr - PAGE_OFFSET;/* base of BDs used by this MCC */    MCCglobal->mccstate = ALL_ZEROS;     MCCglobal->mrblr    = MCC_MRBLR;   /* max Rx buffer length */    MCCglobal->grfthr   = NUMBER_OF_CHANNELS*NUM_RXBDS;                                            MCCglobal->grfcnt   = MCCglobal->grfthr; /* grfthr decrementer */    MCCglobal->rinttmp  = ALL_ZEROS;    MCCglobal->data0    = ALL_ZEROS;    MCCglobal->data1    = ALL_ZEROS;        addr = (unsigned int) txIntCQ;        MCCglobal->tintbase = addr - PAGE_OFFSET;    /* base of Tx int. circular queue */    MCCglobal->tintptr  = MCCglobal->tintbase;  /* temp ptr for tx interrupts*/    MCCglobal->tinttmp  = ALL_ZEROS;    /* must be cleared by user */        MCCglobal->sctpbase = (unsigned int )NULL; 	  /*base of superchannel table*/     MCCglobal->c_mask32 = CRC32;        /* 32 bit crc constant */    MCCglobal->xtrabase = MCCXTRABASE; /*base of chan-specific xtra params */    MCCglobal->c_mask16 = CRC16;        /* 16 bit crc constant */    /* Note that we are using only 1 one of the four possible Rx int. queues */

⌨️ 快捷键说明

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