📄 device.c
字号:
MCCglobal->rinttmp0 = ALL_ZEROS; /* must be cleared by user */ MCCglobal->rinttmp1 = ALL_ZEROS; /* must be cleared by user */ MCCglobal->rinttmp2 = ALL_ZEROS; /* must be cleared by user */ MCCglobal->rinttmp3 = ALL_ZEROS; /* must be cleared by user */ addr = (unsigned int )rxIntCQ; MCCglobal->rintbase0 = addr - PAGE_OFFSET; /* base of Rx int. circular queue #0*/ MCCglobal->rintptr0 = MCCglobal->rintbase0; /* current RxINTCQ0 ptr */ MCCglobal->rintbase1 = ALL_ZEROS; /* base of Rx int. circular queue #1*/ MCCglobal->rintptr1 = MCCglobal->rintbase1; /* current RxINTCQ1 ptr */ MCCglobal->rintbase2 = ALL_ZEROS; /* base of Rx int. circular queue #2*/ MCCglobal->rintptr2 = MCCglobal->rintbase2; /* current RxINTCQ2 ptr */ MCCglobal->rintbase3 = ALL_ZEROS; /* base of Rx int. circular queue #3*/ MCCglobal->rintptr3 = MCCglobal->rintbase3; /* current RxINTCQ3 ptr */ IMM->si_regs[MCC].mccr = 0x1b; /* gruppo 1 a TDMA1, gruppo 2 a TDMB1 gruppo 3 a TDMC1 gruppo 4 a TDMD1 */ /* Enable all interrupts */ IMM->si_regs[MCC].mccm = 0xff0f ; /* Clear MCCE Register by writing all 1's */ IMM->si_regs[MCC].mcce = (unsigned short )ALL_ONES;} /* end MCCGlobalInit() *//* * Name: * MCCChanSpecInit * Description: * configure MCC channel specific parameter */void MCCChanSpecInit(unsigned short mcn, unsigned char mode){ t_Mch_Pram* MCCmch; MCCmch = (t_Mch_Pram*) ((unsigned int )IMM + (64 * ((unsigned int ) mcn))); /* Channel-Specific Parameter RAM Initialization */ MCCmch->zistate = 0x10000207; /* regular channel */ MCCmch->zidata0 = ALL_ONES; MCCmch->zidata1 = ALL_ONES; MCCmch->tbdflags = ALL_ZEROS; MCCmch->tbdcnt = ALL_ZEROS; MCCmch->tbdptr = ALL_ZEROS; if (mcn == CHNINT2 ) MCCmch->intmask = 0x0001; /* enable interrupts for RXB */ else MCCmch->intmask = 0x0000; /* disable interrupts for RXB */ if ((mode==HDLC_SUPERCHAN) || (mode==HDLC_NOTSUPERCHAN)){ /* HDLC*/ MCCmch->chamr = 0xE480; /* set MODE to HDLC, POL, CRC, Reversed bit ordering*/ MCCmch->maxrlen = MCC_MRBLR; /* HDLC max frame receive length */ MCCmch->zdstate = 0x00FFFFE0; } else { /* TRANSPARENT */ MCCmch->chamr = 0x7400; /* set MODE to TRAN, POL */ MCCmch->maxrlen = BUFFER_SIZE; /* in transparent, this should be to exactly the amount of data desired to fill the BD */ MCCmch->zdstate = 0x50ffffe0; /* changed for ucode patch for non-sync tran. */ }; MCCmch->tcrc = ALL_ZEROS; MCCmch->zddata0 = ALL_ONES; MCCmch->zddata1 = ALL_ONES; MCCmch->rbdflags = ALL_ZEROS; MCCmch->rbdcnt = ALL_ZEROS; MCCmch->rbdptr = ALL_ZEROS; MCCmch->sync_maxcnt = ALL_ZEROS; MCCmch->rcrc = ALL_ZEROS; if ((mode==HDLC_NOTSUPERCHAN) || (mode==TRAN_NOTSUPERCHAN)){ MCCmch->tstate = 0x38800000; /* global, big endian*/ MCCmch->rstate = 0x38800000; /* global, big endian*/ if (BD_BUS == LOCAL) { MCCmch->tstate |= 0x01000000; /* set BDB */ MCCmch->rstate |= 0x01000000; /* set BDB */ } if (BUFFER_BUS == LOCAL) { MCCmch->tstate |= 0x02000000; /* set DTB */ MCCmch->rstate |= 0x02000000; /* set DTB */ } } else { /* initialize states for superchannelling (to be set in StartChannel) */ MCCmch->tstate = ALL_ZEROS; MCCmch->rstate = ALL_ZEROS; }; } /* end MCCChanSpecInit() *//* * Name: * MCCExChanSpecInit * Description: * configure MCC channel extra specific parameter */void MCCExChanSpecInit(unsigned int mcn, unsigned short mctbase, unsigned short mcrbase) { t_MchXtra_Pram* MCCmchx; MCCmchx=(t_MchXtra_Pram * ) ((unsigned int )IMM + MCCXTRABASE + (8 * mcn)); /*-----------------------------------------------------------------*/ /* Let MCC1 know where base of TxBDs are for this logical channel. */ /* Note that tbase is an offset from MCCBASE in the global params. */ /*-----------------------------------------------------------------*/ MCCmchx->tbase = mctbase; MCCmchx->tbptr = MCCmchx->tbase; /* init "current TxBD ptr" */ /*-----------------------------------------------------------------*/ /* Let MCC1 know where base of RxBDs are for this logical channel */ /* Note that rbase is an offset from MCCBASE in the global params. */ /*-----------------------------------------------------------------*/ MCCmchx->rbase = mcrbase; MCCmchx->rbptr = MCCmchx->rbase; /* init "current RxBD ptr" */ } /* MCCExChanSpecInit *//* * Name: * InitTxRxParams * Description: * Issues the INIT_TX_RX_PARAMS command to the CPCR for the given mcn * NOTE: * issuing an init params command to an MCC channel * actually initializes the 32 consecutive channels starting with * channel number specified.*/void InitTxRxParams (unsigned short 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_INIT_TX_RX_PARAMS | psbc | (mcn<<6)| CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); } /* InitTxRxParams *//* * Name: * getFrame * Description: * copy read data from RxBDs into the read buffer * Input parameter: * chn:channel number, * offset:chn offset in BufferPool area, * index: BD identifier */void getFrame(unsigned int chn, unsigned short offset) { unsigned int index=0; unsigned char *rx; FrameBuffer *read = (FrameBuffer *) ((unsigned int )ReadBuffer + (sizeof(FrameBuffer))*chn); unsigned int i; while(index<NUM_RXBDS){ if( (RxTxBD->RxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD filled */ rx = BufferPool + BUFFER_SIZE*NUMBER_OF_CHANNELS*NUM_TXBDS + (offset+index)*BUFFER_SIZE; index++; } for(i = 0; i < BUFFER_SIZE; i++){ read->data[i] = (unsigned char) *rx++; } readNow[chn] = 1;} /* getFrame *//* * Name: * sendFrame * Description: * copy from write buffer into the TxBDs * Input parameter: * chn:channel number, * offset:chn offset in BufferPool area, * index: BD identifier */void sendFrame(unsigned int chn,unsigned short offset) { unsigned int index=0; unsigned char *tx; unsigned short i; FrameBuffer *write = (FrameBuffer *) ( (unsigned int ) WriteBuffer + (sizeof(FrameBuffer))*chn); while (index<NUM_TXBDS){ if( (RxTxBD->TxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD serviced */ tx = BufferPool+((offset+index)*BUFFER_SIZE); index++; } if ( valid[chn] == 0){ for (i = 0; i < BUFFER_SIZE; i++) { *tx++ = ((chn == 0) || (chn == 32) )? SYNC_PATTERN : SILENCE_PATTERN; } } else { for (i = 0; i < BUFFER_SIZE; i++) { *tx++ = (unsigned char) write->data[i]; } valid[chn] = 0; } writeNow[chn] = 1;} /* end of sendFrame *//* * Name: * restoreBDs * Description: * reinitilize BDs */void restoreBDs(unsigned short offset){ unsigned int index=0; while (index<NUM_RXBDS){ if( index != (NUM_RXBDS-1) ){/* If not the last RxBD for this channel */ if( (RxTxBD->RxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD filled */ RxTxBD->RxBD[index+offset].bd_cstatus = 0x9000; /* Empty, No Interrupt */ /* old 0x9000 */ RxTxBD->TxBD[index+offset].bd_cstatus = 0x8000; /* Set Ready bit */ } else {/* if last RxBD for this channel */ if( (RxTxBD->RxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD filled */ RxTxBD->RxBD[index+offset].bd_cstatus = 0xB000; /* Empty, Interrupt,Wrap */ RxTxBD->TxBD[index+offset].bd_cstatus = 0xA000;/* Set Ready, Wrap bits */ } index++; }}/* * Name: * mcc_ISR * Description: * MCC Interrupt handler * a new interrupt comes when 32癱hannel buffer has been recieved */void mcc_ISR(int irq, void *dev_id, struct pt_regs *regs) { unsigned int mcce; unsigned int chnOffset; unsigned int chnNum; /* lock intetruupt handler */ spin_lock_irq(&lock); /* Copy the MCC event register */ mcce = IMM->si_regs[MCC].mcce; /* Save off scce */ /* Clear MCC1 Event Register (by writing 1s) */ IMM->si_regs[MCC].mcce = (unsigned short )ALL_ONES; if (mcce & RINT0){/* at last one new entry was added in the Rx interrupt table */ chnOffset = 0; for(chnNum = 0; chnNum < (NUMBER_OF_CHANNELS); chnNum++){ getFrame(chnNum,chnOffset); sendFrame(chnNum,chnOffset); restoreBDs(chnOffset); chnOffset+=NUM_RXBDS; } memset((unsigned char *)&rxIntCQ[0], 0,NUM_CHN_INT*NUM_RXBDS*4); *((unsigned int *)&rxIntCQ[0] + NUM_CHN_INT*NUM_RXBDS - 1) = 0x40000000; /* set wrap bit at end of RX intcq */ } else { /* may be underrun, fatal error */ printk("MCC:interrupt error:0x%x\n",mcce); /* Restart the driver RestartServiceRoutine();*/ /* asyncronous notification */ mccFasync(); } /* unlock intetruupt handler */ spin_unlock_irq(&lock); /* Enable RINT0 interrupts */ IMM->si_regs[MCC].mccm =0xff0f; /* all source interrupt abled, see page 27-19*/} /* end of mcc_ISR *//* * Name: * BDsStatus * Description: * read TxRxBDs satus */void BDsStatus(unsigned char TxRx, unsigned char offset, unsigned short *bd_status, unsigned short *bd_length, unsigned int *bd_addr){ unsigned char index; if (TxRx == TX){ for (index=0;index<NUM_TXBDS;index++){ bd_status[index]=RxTxBD->TxBD[index+offset].bd_cstatus; bd_length[index]=RxTxBD->TxBD[index+offset].bd_length; bd_addr[index]=RxTxBD->TxBD[index+offset].bd_addr; } } else { for (index=0;index<NUM_RXBDS;index++){ bd_status[index]=RxTxBD->RxBD[index+offset].bd_cstatus; bd_length[index]=RxTxBD->RxBD[index+offset].bd_length; bd_addr[index]=RxTxBD->RxBD[index+offset].bd_addr; } }}/* BDsStatus end *//* * Name: * SiRamStatus * Description: * read Si ram satus */void SiRamStatus(unsigned char chn,unsigned char *sigmr,unsigned char *sicmdr, unsigned char *sistr,unsigned short *sirsr,unsigned short *mcce, unsigned short *mccm,unsigned char *mccr,unsigned short *sixmr, unsigned short *tx_siram,unsigned short *rx_siram){ *sigmr=IMM->si_regs[SI].sigmr; *sicmdr=IMM->si_regs[SI].sicmdr; *sistr=IMM->si_regs[SI].sistr; *sirsr=IMM->si_regs[SI].sirsr; *mcce=IMM->si_regs[SI].mcce; *mccm=IMM->si_regs[SI].mccm; *mccr=IMM->si_regs[SI].mccr; *sixmr=IMM->si_regs[SI].sixmr[(chn<32)?TDMC:TDMD]; *tx_siram=IMM->si_ram[SI].tx_siram[(chn<32)?chn:(chn+32)]; *rx_siram=IMM->si_ram[SI].rx_siram[(chn<32)?chn:(chn+32)];}/* SiRamStatus end*/ /* * Name: * CpmReadRegisters * Description: * read CPM register */void CpmReadRegisters(CPM_STATUS_IOC *CpmStatusRegisterIOCTL){ CpmStatusRegisterIOCTL->cpm_cpcr=IMM->cpm_cpcr; CpmStatusRegisterIOCTL->cpm_rccr=IMM->cpm_rccr; CpmStatusRegisterIOCTL->cpm_rmdr=IMM->cpm_rmdr; CpmStatusRegisterIOCTL->cpm_rctr1=IMM->cpm_rctr1; CpmStatusRegisterIOCTL->cpm_rctr2=IMM->cpm_rctr2; CpmStatusRegisterIOCTL->cpm_rctr3=IMM->cpm_rctr3; CpmStatusRegisterIOCTL->cpm_rctr3=IMM->cpm_rctr3; CpmStatusRegisterIOCTL->cpm_rter=IMM->cpm_rter; CpmStatusRegisterIOCTL->cpm_rtmr=IMM->cpm_rtmr; CpmStatusRegisterIOCTL->cpm_rtscr=IMM->cpm_rtscr; CpmStatusRegisterIOCTL->cpm_rmds=IMM->cpm_rmds; CpmStatusRegisterIOCTL->cpm_rtsr=IMM->cpm_rtsr;} /* CpmReadRegisters end *//* * Name: * RestartServiceRoutine * Description: * restart of mcc after a fatal error */void RestartServiceRoutine(void){ unsigned char chnOffset,chnNum; /* reinizilize the mcc. */ stopTxRx(); /*Reinitialize TxRxBDs */ chnOffset = 0; for(chnNum = CHNSTART;chnNum < (CHNSTART+NUMBER_OF_CHANNELS);chnNum++){ InitBDs(chnOffset,TRAN_NOTSUPERCHAN); chnOffset+=NUM_RXBDS; } startTxRx(); return;} /* end of RestartServiceRoutine */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -