📄 ppp_framer.c
字号:
start |= p->is_last;
DRV_WriteReg32(PFC_START,start);
PFC_START_TIMER();
#if defined(PFC_USE_INT)
{
kal_uint32 flags;
kal_retrieve_eg_events(pfc_dcb.event,PFC_EVENT ,KAL_AND_CONSUME,&flags,KAL_SUSPEND);
}
#else
PFC_WAIT_COMPLETE();
#endif
PFC_STOP_TIMER();
DRV_WriteReg32(PFC_START,PFC_START_RESET_VALUE);
p->src = DRV_Reg32(PFC_ECSRC);
p->dst = DRV_Reg32(PFC_ECDES);
p->src_len = DRV_Reg(PFC_EUSLEN);
p->dst_len = DRV_Reg(PFC_EUWBLEN);
pfc_dcb.state = PFC_READY_STATE;
DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_PFC,PDN_PFC);
return (kal_int32)pfc_dcb.status;
}
#if defined(PFC_USE_INT)
void PFC_LISR(void)
{
IRQMask(IRQ_PFC_CODE);
kal_activate_hisr(pfc_dcb.hisr);
}
void PFC_HisrEntry(void)
{
kal_set_eg_events(pfc_dcb.event,PFC_EVENT,KAL_OR);
IRQClearInt(IRQ_PFC_CODE);
IRQUnmask(IRQ_PFC_CODE);
}
void PFC_Initialize(void)
{
kal_uint32 i;
if(pfc_dcb.event == 0)
{
GPTI_GetHandle(&pfc_dcb.gpt_handle);
pfc_dcb.event = kal_create_event_group("PFC_EVENT");
pfc_dcb.hisr = kal_create_hisr("PFC_HISR",2,512,PFC_HisrEntry,NULL);
IRQ_Register_LISR(IRQ_PFC_CODE, PFC_LISR,"PFC_LISR");
IRQSensitivity(IRQ_PFC_CODE,LEVEL_SENSITIVE);
IRQUnmask(IRQ_PFC_CODE);
}
}
#else
void PFC_Initialize(void)
{
if(pfc_dcb.gpt_handle == 0)
GPTI_GetHandle(&pfc_dcb.gpt_handle);
IRQMask(IRQ_PFC_CODE);
PFC_Reset();
}
#endif // PFC_USE_INT
#endif // MT6228
#if defined(MT6229) || defined(MT6230)
/*************************************************************************
* FUNCTION
* PFC_Initialize
*
* DESCRIPTION
* This function is to initalize the PFC driver
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void PFC_Initialize(void)
{
if(pfc_dcb.gpt_handle == 0)
GPTI_GetHandle(&pfc_dcb.gpt_handle);
IRQMask(IRQ_PFC_CODE);
PFC_RESET();
DRV_WriteReg(PFC_INTEN, PFC_INTEN_ALL);
}
/*************************************************************************
* FUNCTION
* PFC_CheckStatus
*
* DESCRIPTION
* This function is to check the interrupt status and update the state.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
static pfc_status_enum PFC_CheckStatus(pfc_id_struct* id_ptr)
{
pfc_status_enum status;
status = id_ptr->status = DRV_Reg(PFC_STAT);
if(status == PFC_STAT_BUSY)
ASSERT(0);
if(id_ptr->d_state == PFC_DECODE_BUSY)
{
if(status == PFC_STAT_OK)
{
id_ptr->d_state = PFC_DECODE_READY;
pfc_dcb.state = PFC_READY_STATE;
}
else if(status == PFC_STAT_PAUSE || status == PFC_STAT_DST_FULL)
{
id_ptr->d_state = PFC_DECODE_PAUSE;
}
else
{
id_ptr->d_state = PFC_DECODE_ERR;
}
}
else //PFC_ENCODE_BUSY
{
if(status == PFC_STAT_OK)
{
id_ptr->e_state = PFC_ENCODE_READY;
pfc_dcb.state = PFC_READY_STATE;
}
else if(status == PFC_STAT_PAUSE || status == PFC_STAT_DST_FULL)
{
id_ptr->e_state = PFC_ENCODE_PAUSE;
ASSERT(0);
}
else
{
id_ptr->e_state = PFC_ENCODE_ERR;
ASSERT(0);
}
}
return status;
}
/*************************************************************************
* FUNCTION
* PFC_EncodeStart
*
* DESCRIPTION
* 1. This function is to encode a ppp frame
* 2. Not support partial frame encoding
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
static kal_uint32 PFC_EncodeStart(kal_uint8 id)
{
kal_uint32 status;
kal_uint16 start;
pfc_id_struct* id_ptr;
pfc_encode_cfg_struct *p;
ASSERT(pfc_dcb.state == PFC_READY_STATE);
DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_PFC,PDN_PFC);
PFC_RESET();
pfc_dcb.state = PFC_ENCODE_STATE;
p = &pfc_dcb.id[id].encode_cfg;
id_ptr = &pfc_dcb.id[id];
DRV_WriteReg32(PFC_ACCM,p->eaccm);
DRV_WriteReg32(PFC_PTC,p->protocol);
DRV_WriteReg32(PFC_CON,(p->control | PFC_CON_ENC));
start = PFC_START_ENABLE;
DRV_WriteReg32(PFC_DES, p->dst);
DRV_WriteReg32(PFC_UDLEN,p->dst_len);
DRV_WriteReg32(PFC_SRC, p->src);
DRV_WriteReg32(PFC_USLEN,p->src_len);
start |= p->is_last;
id_ptr->e_state = PFC_ENCODE_BUSY;
DRV_WriteReg32(PFC_START,start);
PFC_START_TIMER();
PFC_WAIT_COMPLETE();
PFC_STOP_TIMER();
status = PFC_CheckStatus(id_ptr);
p->src = DRV_Reg32(PFC_SRC);
p->dst = DRV_Reg32(PFC_DES);
p->src_len = DRV_Reg(PFC_USLEN);
p->dst_len = DRV_Reg(PFC_UDLEN);
pfc_dcb.state = PFC_READY_STATE;
DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_PFC,PDN_PFC);
return (kal_int32)status;
}
/*************************************************************************
* FUNCTION
* PFC_DecodeStart
*
* DESCRIPTION
* This function is to decode a ppp frame.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
static kal_int32 PFC_DecodeStart(kal_uint8 id)
{
kal_uint32 status;
kal_uint16 start;
pfc_id_struct* id_ptr;
register pfc_decode_cfg_struct *p;
DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_PFC,PDN_PFC);
ASSERT(pfc_dcb.state == PFC_READY_STATE);
pfc_dcb.state = PFC_DECODE_STATE;
p = &pfc_dcb.id[id].decode_cfg;
id_ptr = &pfc_dcb.id[id];
//if(p->reset == KAL_TRUE)
if(id_ptr->d_state == PFC_DECODE_READY)
PFC_RESET();
DRV_WriteReg32(PFC_ACCM,p->daccm);
DRV_WriteReg32(PFC_CON,(p->control));
DRV_WriteReg32(PFC_SADDR,id_ptr->d_buf);
start = PFC_START_ENABLE;
if(p->dst != NULL)
{
DRV_WriteReg32(PFC_DES, p->dst);
DRV_WriteReg32(PFC_UDLEN,p->dst_len);
start |= (PFC_START_M_DES|PFC_START_M_DL);
}
// if(p->src != NULL)
{
DRV_WriteReg32(PFC_SRC, p->src);
DRV_WriteReg32(PFC_USLEN,p->src_len);
start |= (PFC_START_M_SRC|PFC_START_M_SL);
}
if(id_ptr->d_state == PFC_DECODE_READY)
{
start |= PFC_START_WSTAT;
}
else if(id_ptr->d_state == PFC_DECODE_PAUSE)
{
start |= (PFC_START_WSTAT|PFC_START_RSTAT);
}
if(KAL_TRUE == p->df7e)
{
start |= PFC_START_DF7E;
}
if(KAL_TRUE == p->dset7e)
{
start |= PFC_START_DSET7E;
}
id_ptr->d_state = PFC_DECODE_BUSY;
DRV_WriteReg32(PFC_START,start);
PFC_START_TIMER();
PFC_WAIT_COMPLETE();
PFC_STOP_TIMER();
pfc_dcb.state = PFC_DECODE_READY;
status = PFC_CheckStatus(id_ptr);
p->protocol =(p->control & PFC_CON_PFC)?(DRV_Reg(PFC_PTC)&0xff)
: DRV_Reg(PFC_PTC);
p->src = DRV_Reg32(PFC_SRC);
p->dst = DRV_Reg32(PFC_DES);
p->src_len = DRV_Reg(PFC_USLEN);
p->dst_len = DRV_Reg(PFC_UDLEN);
DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_PFC,PDN_PFC);
return (kal_int32)status;
}
#endif // MT6229 || defined(MT6230)
#if defined(MT6228) || defined(MT6229) || defined(MT6230)
/*************************************************************************
* FUNCTION
* ppp_frame_encode_hw
*
* DESCRIPTION
* encode a ppp frame
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_bool ppp_frame_encode_hw( ppp_buff_head_struct *dst,
ppp_buff_head_struct* src, ahdlc_state_struct* state,kal_uint8 id)
{
kal_uint8 control;
pfc_status_enum status;
#if defined(MT6228)
register pfc_encode_cfg_struct *en_cfg = &pfc_dcb.encode_cfg;
#else // MT6229
register pfc_encode_cfg_struct *en_cfg = &pfc_dcb.id[id].encode_cfg;
#endif
#ifdef PPP_STATUS_REPORT
ppp_frame_statistic_struct * statistic = NULL;
statistic = ENCODE_STA_PTR;
if(GET_ENCODE_ID%10 == 0)
RESET_ENCODE_STA;
if((statistic->id != GET_ENCODE_ID)||(GET_ENCODE_ID == 0)) {
statistic->time_100us = ppp_get_current_time();
statistic->id = GET_ENCODE_ID;
statistic->time_stamp = L1I_GetTimeStamp();
statistic->data_size = src->used;
} else /* Previous Frame fail*/
ASSERT(0);
#endif /* PPP_STATUS_REPORT */
en_cfg->dst = (kal_uint32)dst->end_ptr ;
en_cfg->dst_len = dst->size;
en_cfg->src = (kal_uint32)src->cur_ptr;
en_cfg->src_len = src->used;
en_cfg->eaccm = state->xaccm;
en_cfg->protocol= src->protocol;
en_cfg->is_last = PFC_START_ELASTS;
control = PFC_CON_ENC;
if(state->is_acfc_tx)
control |= PFC_CON_EACFC;
if(state->is_pfc_tx)
control |= PFC_CON_EPFC;
en_cfg->control = control;
#if defined(MT6228)
status = PFC_EncodeStart(en_cfg);
#else //MT6229
status = PFC_EncodeStart(id);
#endif
src->used = en_cfg->src_len;
src->cur_ptr = (kal_uint8*)en_cfg->src;
dst->used = en_cfg->dst - (kal_uint32)dst->cur_ptr;
dst->end_ptr = (kal_uint8*)en_cfg->dst;
if(status == PFC_STAT_OK)
{
#ifdef PPP_STATUS_REPORT
statistic->time_100us = ppp_get_duration_100us(statistic->time_100us);
statistic->frame_size = dst->used;
if(GET_ENCODE_ID%10 == 9)
ppp_sta_ctx_ptr->is_status_report = PPP_STA_REPORT_SET(PPP_STA_ENCODE);
/*INITIAL for the next frame */
INC_ENCODE_ID;
#endif /* PPP_STATUS_REPORT */
return KAL_TRUE;
}
if(status == PFC_STAT_PAUSE)
{
ASSERT(0);
return KAL_FALSE;
}
else
{
ASSERT(0);
}
return KAL_FALSE;
}
/*************************************************************************
* FUNCTION
* ppp_frame_decode
*
* DESCRIPTION
* 1. decode a ppp frame in the src buffer and update the used, cur_ptr of src.
* 2. output the decoded result in the dst buffer and update the used, end_ptr of dst.
* 3. if decoding a invalid frame or destination buffer full,
skip this frame and find next 0x7e and decode it.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_bool ppp_frame_decode_hw( ppp_buff_head_struct *dst,
ppp_buff_head_struct *src, ahdlc_state_struct *state, kal_uint8 id)
{
kal_uint8 control =0;
pfc_status_enum status;
pfc_decode_state_enum *decode_state;
#ifdef PPP_STATUS_REPORT
ppp_frame_statistic_struct * statistic = NULL;
#endif /* PPP_STATUS_REPORT */
#if defined(MT6228)
register pfc_decode_cfg_struct *de_cfg = &pfc_dcb.decode_cfg;
decode_state = &pfc_dcb.decode_state;
#else // MT6229
register pfc_decode_cfg_struct *de_cfg = &pfc_dcb.id[id].decode_cfg;
decode_state = &pfc_dcb.id[id].d_state;
#endif
de_cfg->reset = KAL_FALSE;
de_cfg->dset7e = KAL_FALSE;
de_cfg->df7e = KAL_FALSE;
de_cfg->src = (kal_uint32)src->cur_ptr;
de_cfg->src_len = src->used;
if(*decode_state == PFC_DECODE_FIND_NO_7E)
{
// try to find next 0x7E
de_cfg->df7e = KAL_TRUE;
#if defined(MT6228)
status = PFC_DecodeStart(de_cfg);
#else
status = PFC_DecodeStart(id);
#endif
src->used = de_cfg->src_len;
src->cur_ptr = (kal_uint8*)de_cfg->src;
if(status == PFC_STAT_OK && de_cfg->src_len != 0)
{
// find 7E and src_len != 0
*decode_state = PFC_DECODE_READY;
de_cfg->df7e = KAL_FALSE;
}
else if(status == PFC_STAT_NOT_0x7E && de_cfg->src_len == 0)
{
*decode_state = PFC_DECODE_FIND_NO_7E;
PFC_RESET_SRC_BUFFER();
return KAL_FALSE;
}
else if(status == PFC_STAT_OK && de_cfg->src_len == 0)
{
*decode_state = PFC_DECODE_READY;
PFC_RESET_SRC_BUFFER();
return KAL_FALSE;
}
else
{
ASSERT(0);
}
}
// start to decode a PPP frame
while(1)
{
/* PH add */
if(src->used == 0)
{
PFC_RESET_SRC_BUFFER();
return KAL_FALSE;
}
if(*decode_state == PFC_DECODE_READY)
{
kal_uint8 * ptr = src->cur_ptr;
// decode a new frame
#ifdef PPP_STATUS_REPORT
statistic = DECODE_STA_PTR;
if(GET_DECODE_ID%10 == 0)
RESET_DECODE_STA;
if((statistic->id != GET_DECODE_ID)||(GET_DECODE_ID == 0))
{
statistic->time_100us = ppp_get_current_time();
statistic->id = GET_DECODE_ID;
statistic->time_stamp = L1I_GetTimeStamp();
statistic->frame_size = src->used;
}
else /* Previous Frame fail*/
{
ASSERT(0);
}
#endif /* PPP_STATUS_REPORT */
de_cfg->dst = (kal_uint32)dst->end_ptr;
de_cfg->dst_len = dst->size;
dst->protocol = 0;
/* PH add ACFC and PFC judgement here! */
if(ptr[0] == 0x7E) {
if(ptr[1] == 0xFF ) {
state->is_acfc_rx = KAL_FALSE;
state->is_pfc_rx = KAL_FALSE;
} else if ((ptr[1] == 0x80)||(ptr[1] == 0xC0)||(ptr[1] == 0x00)||(ptr[1] == 0xC2)) {
state->is_acfc_rx = KAL_TRUE;
state->is_pfc_rx = KAL_FALSE;
} else if (ptr[1] == 0x21) {
state->is_acfc_rx = KAL_TRUE;
state->is_pfc_rx = KAL_TRUE;
dst->protocol = PPP_PROTOCOL_IP;
}
} else {
if(ptr[0] == 0xFF ) {
state->is_acfc_rx = KAL_FALSE;
state->is_pfc_rx = KAL_FALSE;
} else if ((ptr[0] == 0x80)||(ptr[0] == 0xC0)||(ptr[0] == 0x00)||(ptr[0] == 0xC2)) {
state->is_acfc_rx = KAL_TRUE;
state->is_pfc_rx = KAL_FALSE;
} else if (ptr[0] == 0x21) {
state->is_acfc_rx = KAL_TRUE;
state->is_pfc_rx = KAL_TRUE;
dst->protocol = PPP_PROTOCOL_IP;
}
}
}
else if(*decode_state == PFC_DECODE_PAUSE)
{
de_cfg->dst = NULL;
}
else
{
ASSERT(0);
}
if(state->is_acfc_rx)
control |= PFC_CON_DACFC;
if(state->is_pfc_rx)
control |= PFC_CON_DPFC;
de_cfg->control = control;
de_cfg->daccm = state->raccm;
#if defined(MT6228)
de_cfg->esc_count = 0;
#endif
/* PH add end */
#if defined(MT6228)
status = PFC_DecodeStart(de_cfg);
#else
status = PFC_DecodeStart(id);
#endif
src->used = de_cfg->src_len;
src->cur_ptr = (kal_uint8*)de_cfg->src;
if(src->cur_ptr > src->end_ptr)
ASSERT(0);
dst->used = dst->size - de_cfg->dst_len;
dst->end_ptr = (kal_uint8*)de_cfg->dst;
if(status == PFC_STAT_OK)
{ // a complete frame decoded
if(dst->protocol == 0) // We add this field to 0x21 before, if we detected it's an IP pkt.
dst->protocol = de_cfg->protocol;
*decode_state = PFC_DECODE_READY;
#ifdef PPP_STATUS_REPORT
statistic = DECODE_STA_PTR;
ASSERT(statistic->id == GET_DECODE_ID);
statistic->time_100us = ppp_get_duration_100us(statistic->time_100us);
statistic->data_size = dst->used;
if(GET_DECODE_ID%10 == 9)
ppp_sta_ctx_ptr->is_status_report = PPP_STA_REPORT_SET(PPP_STA_DECODE);
/*INITIAL for the next frame */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -