int pwan_cb_rx_packet(void *pMsg, uint msgLen, struct sk_buff *skb, uint pktLen)
{
#if (defined(TCSUPPORT_VOIP) && defined(RTP_RX_SHORTCUT)) || (defined(TCSUPPORT_CPU_PERFORMANCE_TEST)) || defined(TCSUPPORT_CT_PON_GDV20) || defined(TCSUPPORT_IS_FH_PON)
unsigned char vlanLayer=0;
unsigned short vlanId=0;
#endif
#if (defined(TCSUPPORT_VOIP) && defined(RTP_RX_SHORTCUT)) || (defined(TCSUPPORT_CPU_PERFORMANCE_TEST))
int isRtpFlag = 0; /*1: ip mode rtp packet 2: pppoe mode rtp packet*/
#endif
#if defined(TCSUPPORT_CPU_PERFORMANCE_TEST)
int ftpTestFlag = 0; // 1: ip mode ftp test packet 2: pppoe mode ftp test packet
#endif
#if defined(TCSUPPORT_CT_PON_GDV20) || defined(TCSUPPORT_IS_FH_PON)
int isTR143Test = 0;
#endif
char netIdx=0xFF ;
PWAN_NetPriv_T *pNetPriv = NULL ;
PWAN_FERxMsg_T *pRxBmMsg_tmp = (PWAN_FERxMsg_T *)pMsg ;
struct net_device *dev ;
unchar LbFlag = 0 ;
int ret = 0;
int free_skb_flag = 0; /* 0: do nothing; 1: only drop skb; 2: drop skb and learn ppe drop entry */
PWAN_FERxMsg_T pRxBmMsg_s;
PWAN_FERxMsg_T *pRxBmMsg = &pRxBmMsg_s;
char * macDa = NULL;
#if defined(TCSUPPORT_FWC_TRAFFIC_CLASSIFY) || defined(TCSUPPORT_CMCCV2)
unsigned char traffic_classify_flag = E_ECNT_FORWARD;
#endif
#if defined(TCSUPPORT_XPON_HYBIRD)
unchar wan_if = 0;
#endif
#ifdef TCSUPPORT_RA_HWNAT
int ppeMagic = 0 ;
#endif /* TCSUPPORT_RA_HWNAT */
#if defined(TCSUPPORT_L2_PPP_MCAST_SHORTCUT)
int isShortCut = 0;
#endif
memcpy(pRxBmMsg, pRxBmMsg_tmp, sizeof(PWAN_FERxMsg_T));
if(NULL == skb){
return -1;
}
#if defined(TCSUPPORT_XPON_HYBIRD)
wan_if = skb->ecnt_sk_buff.wan_if;
#endif
if((soft_ratelimit_enqueue_hook) && (fh_ipv6_rate_limit_hook(skb)))
{
if(1 == soft_ratelimit_enqueue_hook(skb, 0))
return -1 ;
}
if( pRxBmMsg->raw.oam )
skb = replace_oam_pkt(skb, pktLen);
#ifdef XPON_MAC_CONFIG_DEBUG
if(gpPonSysData->debugLevel & MSG_CONTENT) {
PON_MSG(MSG_CONTENT, "RX PKT LEN: %d, Rx Msg: %.8x, %.8x", pktLen, pRxBmMsg->word[0], pRxBmMsg->word[1]) ;
__dump_skb(skb, pktLen) ;
}
#endif
#ifdef TCSUPPORT_LAN_VLAN
skb->lan_vlan_tci = 0;
skb->lan_vlan_tci_valid = 0;
#endif
/* 1. process the message information *
* 2. calculate the netIdx value from GEM port or LLID value */
/* parer the packet to corresponding interface */
#ifdef TCSUPPORT_WAN_GPON
if(gpPonSysData->sysLinkStatus == PON_LINK_STATUS_GPON) {
if((netIdx = gwan_process_rx_message(pRxBmMsg, skb, pktLen, &LbFlag))<0 || (netIdx!=PWAN_IF_OMCI && (netIdx&0x7)!=PWAN_IF_DATA)) {
if ((netIdx +1+PWAN_IF_DATA) < 0)
{
/*broadcast, unknown unicast, multicast*/
ret = (netIdx +1+PWAN_IF_DATA) ;
}
goto drop ;
}
#ifdef TCSUPPORT_RA_HWNAT
ppeMagic = FOE_MAGIC_GPON ;
#endif /* TCSUPPORT_RA_HWNAT */
} else
#endif /* TCSUPPORT_WAN_GPON */
#ifdef TCSUPPORT_WAN_EPON
if(gpPonSysData->sysLinkStatus == PON_LINK_STATUS_EPON) {
if((netIdx = ewan_process_rx_message(pRxBmMsg, skb, pktLen, &LbFlag))<0 || (netIdx!=PWAN_IF_OAM && netIdx!=PWAN_IF_DATA)) {
goto drop ;
}
#ifdef TCSUPPORT_RA_HWNAT
ppeMagic = FOE_MAGIC_EPON ;
#endif /* TCSUPPORT_RA_HWNAT */
} else
#endif /* TCSUPPORT_WAN_EPON */
{
goto drop ;
}
PON_MSG(MSG_TRACE, "pwan_cb_rx_packet: netIdx = %d line = %d\n", netIdx, __LINE__);
/*broadcast, unknown unicast, multicast*/
if (netIdx > PWAN_IF_DATA)
{
ret = netIdx - PWAN_IF_DATA ;
netIdx = PWAN_IF_DATA ;
}
#if defined(TCSUPPORT_XPON_HYBIRD)
if ( HYBIRD_PWAN_IF_GPON0 == wan_if )
{
dev = gpWanPriv->pPonNetDev[(PWAN_IfType_t)PWAN_IF_GPON0] ;
pNetPriv = (PWAN_NetPriv_T *)netdev_priv(dev) ;
PON_MSG(MSG_TRACE, "[%s][%d] :device name = %s .\n",__FUNCTION__,__LINE__,dev->name);
}
else if ( HYBIRD_PWAN_IF_WAN0 == wan_if )
{
dev = gpWanPriv->pPonNetDev[(PWAN_IfType_t)PWAN_IF_WAN0] ;
pNetPriv = (PWAN_NetPriv_T *)netdev_priv(dev) ;
PON_MSG(MSG_TRACE, "[%s][%d] :device name = %s .\n",__FUNCTION__,__LINE__,dev->name);
}
else
{
dev = gpWanPriv->pPonNetDev[(PWAN_IfType_t)netIdx] ;
pNetPriv = (PWAN_NetPriv_T *)netdev_priv(dev) ;
PON_MSG(MSG_TRACE, "[%s][%d] :device name = %s .\n",__FUNCTION__,__LINE__,dev->name);
}
#else
dev = gpWanPriv->pPonNetDev[(PWAN_IfType_t)netIdx] ;
pNetPriv = (PWAN_NetPriv_T *)netdev_priv(dev) ;
#endif
if(LbFlag) {
skb_put(skb, pktLen) ;
pwan_net_start_xmit(skb, dev) ;
} else {
/* process the packet data to high layer */
skb_put(skb, pktLen) ;
#if defined(WAN2LAN)
/* do wan2lan after skb_put,
* because skb->len starts to have value from it */
#if defined(TCSUPPORT_WAN2LAN_EXT)
if(masko_on_off || (masko_ext & 0x02))
#else
if(masko_on_off)
#endif
{
struct sk_buff *skb2 = NULL;
int len = TX_STAG_LEN;
const u_char omciHdr[14] = {0x00,0x00,0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,0x00,0x02, 0x88, 0xb5};
if (netIdx == PWAN_IF_OMCI){
len += 14; // add dst mac, src mac, ether type
}
//Check the skb headroom is enough or not. shnwind 20100121.
if(skb_headroom(skb) < len)
skb2 = skb_copy_expand(skb, len, skb_tailroom(skb) , GFP_ATOMIC);
else
skb2 = skb_copy(skb, GFP_ATOMIC);
if(skb2 == NULL)
printk("\nFAILED: wan2lan skb2 allocation in pon rx direction.\n");
else
{
/* For oam: remove header 2 bytes: llid value */
if (netIdx == PWAN_IF_OAM){
skb_pull(skb2, 2) ;
}else if (netIdx == PWAN_IF_OMCI){
skb_push(skb2, 14);
memcpy(skb2->data, omciHdr, 14);
}
skb2->mark |= SKBUF_COPYTOLAN;
macSend(WAN2LAN_CH_ID,skb2); //tc3262_mac_tx
}
}
#endif
#if defined(TCSUPPORT_XPON_LED) && defined(TR068_LED)
#if !defined(TCSUPPORT_C9_ROST_LED)
#if defined(TCSUPPORT_XPON_HYBIRD)
if((pNetPriv->netIdx == PWAN_IF_DATA) ||
(pNetPriv->netIdx == PWAN_IF_WAN0) ||
(pNetPriv->netIdx == PWAN_IF_GPON0))
#else
if(pNetPriv->netIdx == PWAN_IF_DATA)
#endif
{
/*for interner traffic led*/
if(internet_led_on) //IP connected and IP traffic is passing
ledTurnOn(LED_INTERNET_ACT_STATUS);
else
{
if(!internet_trying_led_on)
{
ledTurnOff(LED_INTERNET_STATUS);
ledTurnOff(LED_INTERNET_TRYING_STATUS);
}
}
}
#endif
#endif
#if defined(TCSUPPORT_L2_PPP_MCAST_SHORTCUT)
if(pppoeBridgeMultiShortCut == 1)
{
isShortCut = pppoe_bridge_multicast_handle(skb);
if(isShortCut)
goto MulticastShortCut;
}
#endif
skb->dev = dev ;
dev->last_rx = jiffies ;
#if defined(TCSUPPORT_VOIP) && defined(RTP_RX_SHORTCUT)
isRtpFlag = isRtpPacket(skb, &vlanLayer, &vlanId);
#endif
#if defined(TCSUPPORT_CPU_PERFORMANCE_TEST)
if(isRtpFlag == 0)
{
ftpTestFlag = isFtpTestPacket(skb, &vlanLayer, &vlanId);
}
#endif
#if defined(TCSUPPORT_CT_PON_GDV20) || defined(TCSUPPORT_IS_FH_PON)
if ( tr143_test_enable )
isTR143Test = isTR143TestPkt(skb, &vlanLayer, &vlanId);
#endif
skb->protocol = eth_type_trans(skb, dev) ;
if ((pRxBmMsg->raw.ipv4 || pRxBmMsg->raw.ipv6) && (pRxBmMsg->raw.l4vld) &&
(!pRxBmMsg->raw.ipv4f && !pRxBmMsg->raw.l4f)){
skb->ip_summed = CHECKSUM_UNNECESSARY ;
}else{
skb->ip_summed = CHECKSUM_NONE;
}
if (PWAN_IF_OMCI == netIdx ){
skb->protocol = 0;
}
if(wan_speed_test_hook)
{
if(wan_speed_test_hook(skb)==SPEED_TEST_SUCCESS){
/* calculate the statistic counters */
pNetPriv->stats.rx_packets++ ;
pNetPriv->stats.rx_bytes += pktLen ;
return SPEED_TEST_SUCCESS;
}
}
#ifdef TCSUPPORT_RA_HWNAT
if(ra_sw_nat_hook_rxinfo && ppeMagic) {
ra_sw_nat_hook_rxinfo(skb, ppeMagic, (char *)&(pRxBmMsg->word[1]), 4);
}
if(ra_sw_nat_hook_rx != NULL) {
if(ra_sw_nat_hook_rx(skb)) {
#if defined(TCSUPPORT_FWC_TRAFFIC_CLASSIFY) || defined(TCSUPPORT_CMCCV2)
if(PWAN_IF_DATA == netIdx)
{
#if defined(TCSUPPORT_CMCCV2)
skb->mark2 &= (~(QUEUE_MARK_MASK));
skb->mark2 |= QUEUE_FROM_WAN;
#else
skb->mark &= (~(PORT_MASK << PORT_MASK_OFFSET));
skb->mark |= ((E_WAN_PORT & PORT_MASK) << PORT_MASK_OFFSET);
#endif
ECNT_TRAFFIC_CLASSIFY_HOOK(skb, &traffic_classify_flag);
if(E_ECNT_DROP == traffic_classify_flag)
{
#if defined(TCSUPPORT_RA_HWNAT) && defined(TCSUPPORT_RA_HWNAT_ENHANCE_HOOK)
if(ra_sw_nat_hook_drop_packet)
{
ra_sw_nat_hook_drop_packet(skb);
}
#endif
goto drop;
}
}
#endif
if(PWAN_IF_DATA == netIdx){
}
#if defined(TCSUPPORT_VOIP) && defined(RTP_RX_SHORTCUT)
if(isRtpFlag)
{
rtpRxShortCut(skb, vlanLayer, isRtpFlag);
}
else
#endif
#if defined(TCSUPPORT_CPU_PERFORMANCE_TEST)
if(ftpTestFlag)
{
ftpRxShortCut(skb, vlanLayer, vlanId, ftpTestFlag);
}
else
#endif
#if defined(TCSUPPORT_CT_PON_GDV20) || defined(TCSUPPORT_IS_FH_PON)
if ( isTR143Test
&& 0 == tr143RxShortCut(tr143_test_enable, skb, vlanLayer
, tr143_test_iface, isTR143Test
) )
{
isTR143Test = 0;
}
else
#endif
{
#if defined(TCSUPPORT_XPON_HAL_API_MCST)
#if !defined(TCSUPPORT_CPU_EN7527) && !defined(TCSUPPORT_CPU_EN7580)
if(mtk_multicast_data_handle_hook && PWAN_IF_DATA == netIdx)
{
#if !defined(TCSUPPORT_XPON_HAL_API_EXT)
if(0 == mtk_multicast_data_handle_hook(skb))
{
free_skb_flag = 1;
goto free_skb;
}
#endif
}
#endif
#endif
if((PWAN_IF_DATA == netIdx)&&(0 == ECNT_HOOK_MULTICAST_DATA_HANLDE(skb)))
{
free_skb_flag = 1;
goto free_skb;
}
#if 1 //def CONFIG_USE_RX_NAPI
#if defined(WAN2LAN)
#if defined(TCSUPPORT_WAN2LAN_EXT)
if(masko_ext & 0x08)
{
struct sk_buff *skb2 = NULL;
int len = TX_STAG_LEN;
const u_char omciHdr[14] = {0x00,0x00,0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,0x00,0x02, 0x88, 0xb5};
if (netIdx == PWAN_IF_OMCI){
len += 14; // add dst mac, src mac, ether type
}
//Check the skb headroom is enough or not. shnwind 20100121.
if(skb_headroom(skb) < len)
skb2 = skb_copy_expand(skb, len, skb_tailroom(skb) , GFP_ATOMIC);
else
skb2 = skb_copy(skb, GFP_ATOMIC);
if(skb2 == NULL)
printk("\nFAILED: wan2lan skb2 allocation in pon rx direction.\n");
else
{
skb_push(skb2,14);
/* For oam: remove header 2 bytes: llid value */
if (netIdx == PWAN_IF_OAM){
skb_pull(skb2, 2) ;
}else if (netIdx == PWAN_IF_OMCI){
skb_push(skb2, 14);
memcpy(skb2->data, omciHdr, 14);
}
skb2->mark |= SKBUF_COPYTOLAN;
macSend(WAN2LAN_CH_ID,skb2); //tc3262_mac_tx
}
}
#endif
#endif
#if defined(TCSUPPORT_SWNAT)
if(sw_downstream_nat_rx_hook){
if(sw_downstream_nat_rx_hook(skb)){
return 0;
}
}
#endif
macDa = skb_mac_header(skb);
#if defined(TCSUPPORT_XPON_IGMP)
if((PWAN_IF_DATA == netIdx) && (0x01 == (0x01 & macDa[0]) ) && xpon_hgu_down_multicast_incoming_hook)
{
if (xpon_hgu_down_multicast_incoming_hook(skb, 1) > 0 )
{
goto drop;
}
}
#endif
if(PWAN_IF_DATA != netIdx || (0 != gpon_ds_transmit_packet(skb)))
{
#ifdef TCSUPPORT_TLS
if(-1 == FE_API_TLS_FORWARD(skb,FE_TLS_FORWARD_DOWNSTREAM))
#endif
rx_qos_scheduler(skb);
//netif_receive_skb(skb) ;
}
#else
netif_rx(skb) ;
#endif /* CONFIG_USE_RX_NAPI */
}
}
} else
#endif /* TCSUPPORT_RA_HWNAT */
{
#if defined(TCSUPPORT_FWC_TRAFFIC_CLASSIFY) || defined(TCSUPPORT_CMCCV2)
if(PWAN_IF_DATA == netIdx)
{
#if defined(TCSUPPORT_CMCCV2)
skb->mark2 &= (~(QUEUE_MARK_MASK));
skb->mark2 |= QUEUE_FROM_WAN;
#else
skb->mark &= (~(PORT_MASK << PORT_MASK_OFFSET));
skb->mark |= ((E_WAN_PORT & PORT_MASK) << PORT_MASK_OFFSET);
#endif
ECNT_TRAFFIC_CLASSIFY_HOOK(skb, &traffic_classify_flag);
if(E_ECNT_DROP == traffic_classify_flag)
{
goto drop;
}
}
#endif
if(PWAN_IF_DATA == netIdx){
}
#if defined(TCSUPPORT_VOIP) && defined(RTP_RX_SHORTCUT)
if(isRtpFlag)
{
rtpRxShortCut(skb, vlanLayer, isRtpFlag);
}
else
#endif
#if defined(TCSUPPORT_CPU_PERFORMANCE_TEST)
if(ftpTestFlag)
{
ftpRxShortCut(skb, vlanLayer, vlanId, ftpTestFlag);
}
else
#endif
#if defined(TCSUPPORT_CT_PON_GDV20) || defined(TCSUPPORT_IS_FH_PON)
if ( isTR143Test
&& 0 == tr143RxShortCut(tr143_test_enable, skb, vlanLayer
, tr143_test_iface, isTR143Test
) )
{
isTR143Test = 0;
}
else
#endif
{
#if defined(TCSUPPORT_XPON_HAL_API_MCST)
#if !defined(TCSUPPORT_CPU_EN7527) && !defined(TCSUPPORT_CPU_EN7580)
if(mtk_multicast_data_handle_hook && PWAN_IF_DATA == netIdx)
{
#if !defined(TCSUPPORT_XPON_HAL_API_EXT)
if(0 == mtk_multicast_data_handle_hook(skb))
{
free_skb_flag = 1;
goto free_skb;
}
#endif
}
#endif
#endif
if((PWAN_IF_DATA == netIdx)&&(0 == ECNT_HOOK_MULTICAST_DATA_HANLDE(skb)))
{
free_skb_flag = 1;
goto free_skb;
}
#if 1 //def CONFIG_USE_RX_NAPI
#if defined(WAN2LAN)
#if defined(TCSUPPORT_WAN2LAN_EXT)
if(masko_ext & 0x08)
{
struct sk_buff *skb2 = NULL;
int len = TX_STAG_LEN;
const u_char omciHdr[14] = {0x00,0x00,0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,0x00,0x02, 0x88, 0xb5};
if (netIdx == PWAN_IF_OMCI){
len += 14; // add dst mac, src mac, ether type
}
//Check the skb headroom is enough or not. shnwind 20100121.
if(skb_headroom(skb) < len)
skb2 = skb_copy_expand(skb, len, skb_tailroom(skb) , GFP_ATOMIC);
else
skb2 = skb_copy(skb, GFP_ATOMIC);
if(skb2 == NULL)
printk("\nFAILED: wan2lan skb2 allocation in pon rx direction.\n");
else
{
skb_push(skb2,14);
/* For oam: remove header 2 bytes: llid value */
if (netIdx == PWAN_IF_OAM){
skb_pull(skb2, 2) ;
}else if (netIdx == PWAN_IF_OMCI){
skb_push(skb2, 14);
memcpy(skb2->data, omciHdr, 14);
}
skb2->mark |= SKBUF_COPYTOLAN;
macSend(WAN2LAN_CH_ID,skb2); //tc3262_mac_tx
}
}
#endif
#endif
#if defined(TCSUPPORT_SWNAT)
if(sw_downstream_nat_rx_hook){
if(sw_downstream_nat_rx_hook(skb)){
return 0;
}
}
#endif
macDa = skb_mac_header(skb);
#if defined(TCSUPPORT_XPON_IGMP)
if((PWAN_IF_DATA == netIdx) && (0x01 == (0x01 & macDa[0]) ) && xpon_hgu_down_multicast_incoming_hook)
{
if (xpon_hgu_down_multicast_incoming_hook(skb, 1) > 0 )
{
goto drop;
}
}
#endif
if(PWAN_IF_DATA != netIdx || (0 != gpon_ds_transmit_packet(skb)))
{
rx_qos_scheduler(skb);
//netif_receive_skb(skb) ;
}
#else
netif_rx(skb) ;
#endif /* CONFIG_USE_RX_NAPI */
}
}
}
#if defined(TCSUPPORT_L2_PPP_MCAST_SHORTCUT)
MulticastShortCut:
#endif
free_skb:
if(free_skb_flag)
{
if(free_skb_flag == 2) {
#if defined(TCSUPPORT_RA_HWNAT) && defined(TCSUPPORT_RA_HWNAT_ENHANCE_HOOK)
if(ra_sw_nat_hook_drop_packet&&mtk_xpon_is_multicast_addr(skb))
{
ra_sw_nat_hook_drop_packet(skb);
}
#endif
}
dev_kfree_skb(skb);
skb = NULL;
}
/* calculate the statistic counters */
pNetPriv->stats.rx_packets++ ;
pNetPriv->stats.rx_bytes += pktLen ;
return ret ;
drop:
/* Dropped the packet */
dev_kfree_skb(skb);
/* calculate the statistic counters */
gpWanPriv->dropUnknownPackets++ ;
return -EFAULT+ret ;
}
/*****************************************************************************
******************************************************************************/
int pwan_cb_event_handler(QDMA_EventType_t event)
{
switch(event) {
case QDMA_EVENT_RECV_PKTS:
#ifdef CONFIG_USE_RX_NAPI
{
struct net_device *dev = gpWanPriv->pPonNetDev[PWAN_IF_DATA] ;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
PWAN_NetPriv_T *pNetPriv = (PWAN_NetPriv_T *)netdev_priv(dev) ;
if(pNetPriv == NULL) {
return IRQ_HANDLED ;
}
if(napi_schedule_prep(&pNetPriv->napi)) {
QDMA_API_DISABLE_RXPKT_INT(ECNT_QDMA_WAN) ;
__napi_schedule(&pNetPriv->napi) ;
}
#else
if(netif_rx_schedule_prep(dev)) {
QDMA_API_DISABLE_RXPKT_INT(ECNT_QDMA_WAN) ;
__netif_rx_schedule(dev) ;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */
}
#endif /* CONFIG_USE_RX_NAPI */
break ;
case QDMA_EVENT_NO_RX_BUFFER:
break ;
case QDMA_EVENT_TX_CROWDED:
break ;
default:
break ;
}
return 0 ;
}
#if defined(TCSUPPORT_CPU_PERFORMANCE_TEST) omci报文是怎么被处理的
最新发布