📄 qmc__hdl.c
字号:
/************************************************************************/
/* */
/* */
/* (C) Copyright Bangyan Information Technology Ltd, 2000/9. */
/* All right reserved */
/* */
/* Author: Zhuguosheng */
/* */
/* Description: */
/* Driver Set - QMC hdlc specific routines. */
/* */
/* Routines */
/* hdlc_qmc_tx */
/* hdlc_rx_internal */
/* hdlc_tx_internal */
/* qmc_hdlc_interrupt */
/* */
/************************************************************************/
#include "PUB\PUB_INCL.H"
#include "DRVS\DRV860\PUB\NETCOMM.H"
#include "DRVS\DRV860\PUB\D860_PUB.H"
#include "DRVS\DRV860\PUB\MPC860.H"
#include "DRVS\DRV860\PUB\MASKS860.h"
#include "DRVS\DRV860\QMC\QMC.H"
extern QMC_TABLE qmc_table;
extern QUICC_32_MANAGER mgr;
extern EPPC *quicc;
extern VOID RestartQmcChannelRecv( UC scc_num, UC channel_num );
extern VOID RestartQmcChannelSend(UC channel_num );
extern VOID DrvRecvMsu( SI channel_num, VOID *buf, SI length );
extern VOID qmc_glob_underrun(SI scc_num);
extern VOID qmc_glob_overrun(SI scc_num);
extern VOID qmc_chan_underrun(SI chan_num);
extern VOID qmc_chan_overrun(SI chan_num);
extern VOID qmc_chan_CRC_error(SI chan_num);
extern CommReportToNetMan( UC,UC,UI,UC*);
extern SEM_ID SemQMCHdlcSend_ID[64];
UL TestQmcRecvMsgTimes=0;
UL TestQmcRecvMsgFailTimes=0;
UL TestQmcSendMsgTimes=0;
UL TestQmcChansSendMsgTimes[64]={0};
UL TestQmcChansRecvMsgTimes[64]={0};
UL TestQmcChansRecvBsyTimes[64]={0};
UL TestQmcChansSendMissTimes[64]={0};
UL TestQmcChansCrcErrorTimes[64]={0};
int_routine qmc_hdlc_interrupt;
SI hdlc_qmc_tx(SI channel_num, VOID *buf, SI length, SI int_ena);
STATIC VOID hdlc_rx_internal(SI channel_num);
STATIC VOID hdlc_tx_internal(SI channel_num);
VOID qmc_hdlc_interrupt(UI interrupt_event);
VOID qmc_mgr_interrupt(SI scc_num);
BOOL hdlc_qmc_tx_buf_is_full(UI channel_num)
{
register QUICC_BD *tbd;
tbd = qmc_table[channel_num].NextFreeTbd;
if( (tbd->status&T_R)==T_R )
{
return TRUE;
}
return FALSE;
}
VOID QmcPrintTxBdStatus(QUICC_BD *tbd, SI channel_num)
{
QUICC_BD *print_db;
UI i;
print_db=tbd;
for( i=0; i<32; i++ )
{
INCREASE_TBD_32(print_db, quicc, qmc_table[channel_num].scc_number, channel_num);
}
}
SI hdlc_qmc_tx(SI channel_num, VOID *buf, SI length, SI int_ena)
{
SI i, old_sr, rc = TRUE;
register QUICC_BD *tbd;
struct qmc_hdlc_pram *pram;
pram = CHANNEL_PRAM_BASE(quicc,channel_num);
/* Is there free TDB ?*/
/* Point to next free TBD*/
tbd = qmc_table[channel_num].NextFreeTbd;
/* This TBD must be free, if we not in continuous mode.*/
if( (tbd->status&T_R)==T_R )
{
/*It is added by zhuguosheng in 2002/07/28 for Debug, when the queue is full.*/
QmcPrintTxBdStatus(tbd, channel_num);
/*BYPrintf("@@@@@@@@@@@@@@@@@@@@@@CHAN %d IN T_R MODE@@@@@@@@@@@@@@@@@@@@@@", channel_num);*/
rc = FALSE;
}
else
{
tbd->length = (UI)length;
memcpy( tbd->buf, buf, length );
tbd->status &= T_W; /* Clear all except Wrap bit*/
tbd->status |= T_R | T_L | T_TC; /* Ready to transmittion*/
if (qmc_table[channel_num].continuous_tx)
tbd->status |= T_CM; /* Continuous mode*/
if (int_ena)
tbd->status |= T_I; /* Enable interrupt if required*/
pram->chamr |= HDLC_CHAMR_POL; /* Enable polling*/
qmc_table[channel_num].tbd_len++;
INCREASE_TBD_32(qmc_table[channel_num].NextFreeTbd, quicc, qmc_table[channel_num].scc_number, channel_num);
TestQmcSendMsgTimes++;
TestQmcChansSendMsgTimes[channel_num]++;
}
return rc;
}
UL channel36error=0,channel36right=0;
UL channel33right=0,channel33error=0;
UL error_len_msg=0;
UL channelrightmsunum=0;
STATIC VOID hdlc_rx_internal(SI channel_num)
{
QUICC_BD *rbd;
SI once = 1;
rbd = qmc_table[channel_num].rbd;
while(qmc_table[channel_num].continuous_rx ? once : (!(rbd->status & R_E)))
{
once = 0;
if (rbd->status & HDLC_QMC_R_ERROR)
{
rbd->status &= ~HDLC_QMC_R_ERROR;
qmc_chan_CRC_error(channel_num);
TestQmcChansCrcErrorTimes[channel_num]++;
QmcCrcErrorNum[channel_num]++;
}
else
{
if( rbd->length == 2 )
QmcShortPacketNum[channel_num]++;
if( rbd->length>=3 && rbd->length<MRBLR_T )
channelrightmsunum++;
TestQmcChansRecvMsgTimes[channel_num]++;
DrvRecvMsu( channel_num, rbd->buf,rbd->length-2);
}
/* Reset this buffer status to be ready to next reception.*/
if (!qmc_table[channel_num].continuous_rx)
{
rbd->status &= R_W;
rbd->status |= R_E | R_I;
}
INCREASE_RBD_32(rbd, quicc, qmc_table[channel_num].scc_number, channel_num);
}
qmc_table[channel_num].rbd = rbd;
}
STATIC VOID hdlc_tx_internal(SI channel_num)
{
/* QUICC_BD *tbd;
tbd = qmc_table[channel_num].tbd;
while(qmc_table[channel_num].tbd_len && (!(tbd->status & T_R)))
{
tbd->status &= T_W;
tbd->status |= T_I;
INCREASE_TBD_32(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
if( qmc_table[channel_num].tbd_len>0 )
qmc_table[channel_num].tbd_len--;
}
qmc_table[channel_num].tbd = tbd;
*/
/* UI sended_bds,i;
tbd = qmc_table[channel_num].tbd;
sended_bds = qmc_table[channel_num].tbd_len;
for( i=0; i<qmc_table[channel_num].no_of_trn_bd; i++ )
{
if( (tbd->status&T_R)!=T_R )
{
tbd->status &= T_W;
tbd->status |= T_I;
INCREASE_TBD_32(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
if( qmc_table[channel_num].tbd_len>0 )
qmc_table[channel_num].tbd_len--;
}
else
{
qmc_table[channel_num].tbd = tbd;
break;
}
}
*/
}
VOID qmc_hdlc_interrupt(UI interrupt_event)
{
UI event;
UI channel_num;
channel_num = (interrupt_event & INTR_CH_NU) >> 6;
event = interrupt_event & INTR_MASK_BITS;
if (event & HDLC_UN) /* transmit underrun*/
{
QUICC_BD *tbd;
tbd = TBD_32_CUR_ADDR(quicc, qmc_table[channel_num].scc_number, channel_num);
DECREASE_TBD_32(tbd,quicc, qmc_table[channel_num].scc_number, channel_num);
/* if( ((*qmc_table[channel_num].handle_tx_error_ptr)
(qmc_table[channel_num].scc_number, channel_num, tbd)))
{
TBD_32_SET_CUR_ADDR(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
tbd->status |= T_R | T_L | T_TC;
}
*/
tbd->status &= ~HDLC_UN;
hdlc_tx_internal(channel_num);
}
if( event & HDLC_BSY )
{
/* RestartQmcRecvChannel( channel_num );*/
RestartQmcChannelRecv( qmc_table[channel_num].scc_number, channel_num );
}
if (event & HDLC_TXB)
{
hdlc_tx_internal(channel_num);
}
if (event & HDLC_RXF)
{
hdlc_rx_internal(channel_num);
}
if (event & HDLC_RXB)
{
hdlc_rx_internal(channel_num);
}
}
UL HDLC_UN_Times=0;
UL HDLC_BSY_Times=0;
VOID QmcEventHdl(UI interrupt_event,UI scc_num)
{
UI event;
UI channel_num;
channel_num = (interrupt_event & INTR_CH_NU) >> 6;
event = interrupt_event & INTR_MASK_BITS;
if (event & HDLC_UN) /* transmit underrun*/
{
QUICC_BD *tbd;
tbd = TBD_32_CUR_ADDR(quicc, qmc_table[channel_num].scc_number, channel_num);
DECREASE_TBD_32(tbd,quicc, qmc_table[channel_num].scc_number, channel_num);
/* if (qmc_table[channel_num].handle_tx_error_ptr &&
((*qmc_table[channel_num].handle_tx_error_ptr)
(qmc_table[channel_num].scc_number, channel_num, tbd)))
{
TBD_32_SET_CUR_ADDR(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
tbd->status |= T_R | T_L | T_TC;
}
*/
tbd->status &= ~HDLC_UN;
hdlc_tx_internal(channel_num);
HDLC_UN_Times++;
qmc_chan_underrun(channel_num);
}
if( event & HDLC_BSY )
{
HDLC_BSY_Times++;
TestQmcChansRecvBsyTimes[channel_num]++;
qmc_chan_overrun(channel_num);
}
if (event & HDLC_TXB)
{
hdlc_tx_internal(channel_num);
}
if (event & HDLC_RXF)
{
hdlc_rx_internal(channel_num);
}
if (event & HDLC_RXB)
{
hdlc_rx_internal(channel_num);
}/*Temp disable it.*/
}
UL QMC_SCCM_GOV_Times=0;
UL QMC_SCCM_GUN_Times=0;
UL QMC_SCCM_IQOV_Times=0;
VOID qmc_mgr_interrupt(SI scc_num)
{
struct scc_regs *regs;
UI old_sr;
UI event;
UI cur_intr;
struct global_qmc_pram *base;
base = QMC_BASE(quicc, scc_num);
regs = &quicc->scc_regs[scc_num];
event = regs->scc_scce;
/* clear the event register*/
CLEAR_BIT(regs->scc_scce, event);
/* clear the interrupt in service register*/
switch(scc_num)
{
case GLB_SCC_0:
CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC1);
break;
case GLB_SCC_1:
CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC2);
break;
case GLB_SCC_2:
CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC3);
break;
case GLB_SCC_3:
CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC4);
break;
}
if(event & QMC_SCCM_GOV)
{
qmc_glob_overrun(scc_num);
QMC_SCCM_GOV_Times++;
}
if(event & QMC_SCCM_GUN)
{
qmc_glob_underrun(scc_num);
QMC_SCCM_GUN_Times++;
}
if(event & QMC_SCCM_IQOV)
{
QMC_SCCM_IQOV_Times++;
}
if(event & QMC_SCCM_GINT)
{
/* go over the interrupt queue and handle it*/
while( (cur_intr = (*(mgr.CurrIntr[scc_num]))) & INTR_VALID)
{
/* call the appropiate interrupt handler*/
/* qmc_hdlc_interrupt (cur_intr);*/
QmcEventHdl(cur_intr,scc_num);
/* valid the entry , clear events*/
*(mgr.CurrIntr[scc_num]) &= INTR_WRAP;
if( cur_intr & INTR_WRAP)
mgr.CurrIntr[scc_num] = (UI *)base->intbase;
else
(mgr.CurrIntr[scc_num])++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -