交换芯片CPSS-MARVELL 98DXX交换处理流程

一、Forward数据包的存储转发:

1、fwdPktSend线程

{

While(1)

{

recvmsg(fwdPktSockFd, &msg);

fwdPktSendPacket();

-> osMsgQSend(txMsgQ);

}

}

2、fwdPktRecv线程

{

appDemoDxChNetRxPacketCbRegister(appDemoDxChForwardPktCb);

While(1)

{

osMsgQRecv(fwdPktTaskQueueId, );

...

sendmsg(fwdPktSockFd,&msg);        //netlink发送数据包       

}

}

3、transmitTask线程

{

While(1)

{

osMsgQRecv(transmitTaskQueueId, );

}

}

evHandler_recv_fifo函数中,调用appDemoDxChForwardPktCb(),该函数中

osMsgQSend(fwdPktTaskQueueId, &packets);来唤醒fwdPktRecv线程的 osMsgQRecv(fwdPktTaskQueueId, );

osMsgQSend和osMsgQRecv的实现在驱动mv_kernelExt中.

osMsgQRecv->mvKernelExt_MsgQRecv->mv_do_wait_on_queue_timeout:

While(q->messages == 0)

while (tsk->waitqueue && timeout)

    {

        if (unlikely(signal_pending(tsk->task)))

        {

            tsk->tasklockflag = 0;

            mv_delete_from_waitqueue(tsk);

            return -1;

        }

        set_task_state(tsk->task, TASK_INTERRUPTIBLE);

        MV_GLOBAL_UNLOCK();

        timeout = schedule_timeout(timeout);

        MV_GLOBAL_LOCK();

    }

Schedule_timeout()已经进入INTERRUPTIBLE的睡眠状态。

osMsgQSend->mvKernelExt_MsgQSend()

While(q-Messages == q->maxmsgs)

{

mv_do_wait_on_queue_timeout();

}

...

Wake_up_process();

整个数据转发的流程比较清晰:

中断的event函数中,调用evHandler_recv_fifo->appDemoDxChForwardPktCb(),

osMsgQSend(fwdPktTaskQueueId, &packets)像消息队列发送packates后wakeup osMsgRecv(fwdPktTaskQueueId),及线程fwdPktRecv:sendmsg(fwdPktSockFd,&msg),向内核发送netlink数据包;

内核arch/arm/plat-feroceon/my_drivers_lsp/mv_prestera_net/mv_prestera_mux.c中通过netlink_kernel_create()创建内核线程netlink_recv_packet,来接收应用线程fwdPktRecv的sendmsg请求;

netlink_recv_packet的工作如下:

fwd_skb = alloc_skb(NLMSG_PAYLOAD(nlh));

memcpy(fwd_skb->data, NLMSG_DATA(nlh), len);

kfree_skb(skb);

appDemoFwdRxPkt(fwd_skb);

appDemoFwdRxPkt()函数完成net网卡的端口数据转发:

Struct net_device *dev = __dev_get_by_name(&init_net, “mux0”);  //获取mux0的网卡

Fwd_skb->dev = dev;

mvPortForward(fwd_skb, dev);

-> netif_receive_skb(skb);  //linux协议栈入口,数据包送上层处理

(1)、fwdPktSend线程:

recvmsg线程neilink方式阻塞获取内核mux0的出来的报文,并调用cpssFdbMacFindPort查找port号,最后通过osMsgQSend(transmitTaskQueueId, &packet, size)向port转发该报文;

(2)、transmitTask线程:

osMsgRecv(transmitTaskQueueId, &packet);获取该类型报文后,send_acket_DxCh();->dxChNetIfSdmaTxPacketSend(); DMA方式发送packet到交换机;

(3)、fwdPktRecv线程:

交换芯片中断收包后,osMsgQSend(fwdPktTaskQueueId, &packets)唤醒该线程的osMsgQRecv(fwdPktTaskQueueId, );来向内核netlink发送该二层包;内核netlink线程收到该包后,发送到内核linux协议栈,并绑定网口mux0;

(4)、lldp线程:

该线程通过

appDemoDxChNetRxPacketCbRegister(appDemoDxChNetLldpProtocolCb);

注册中断hook函数,该函数中通过osMsgQSend(lldpTaskQueueId);唤醒osMsgQRecv(lldpTaskQueueId, &packet),memcpy拷贝packet来实现对该packet的协议处理;最后通过osMsgQSend(transmitTaskQueueId)来转发出去。

可以看到,该协议的处理,至少有4次内存拷贝,收发的各2次内存拷贝:存储转发到接收缓缓冲池lldpTaskQueueId的1次内存拷贝,协议任务获取从该缓冲池获取包的一次内存拷贝;发送到transmitTaskQueueId缓冲池的1次内存拷贝,transmitTask线程从transmitTaskQueueId缓冲池转发到交换芯片端口的一次内存拷贝。

fwdPktRecv线程的示意图如下所示:

二、event处理流程:

  1. 创建event_handle任务:

userEventHandler.c 里面,appdemoEventRequestDrvnModeInit()函数中,for创建了10个evHndl_x任务线程,均执行appDemoEvHndlr()处理函数:

While(1)

{

Select();

cpssEventRecv();

->appDemoEnPpEvTreat();

    case CPSS_PP_RX_BUFFER_QUEUE0_E:

        case CPSS_PP_RX_BUFFER_QUEUE1_E:

        case CPSS_PP_RX_BUFFER_QUEUE2_E:

        case CPSS_PP_RX_BUFFER_QUEUE3_E:

        case CPSS_PP_RX_BUFFER_QUEUE4_E:

        case CPSS_PP_RX_BUFFER_QUEUE5_E:

        case CPSS_PP_RX_BUFFER_QUEUE6_E:

        case CPSS_PP_RX_BUFFER_QUEUE7_E:

cpssEnRxPacketGet(queue_num);

->appDemoDxChNetRxPktHandle();

->cpssDxChNetIfSdmaRxPacketGet();

->dxChNetIfRxPacketGet();

  packetBuffsAddrPtr[i] = phy2virt(rxDesc>buffPointer);

这里获取到了rc_packet的地址。

-> for(ii = 0 ; ii < numRegistrations ; ii++)

        {

            (rxPktReceiveCbArray[ii])(devNum,queueIdx,numOfBuff,

                                    packetBuffs,buffLenArr,&rxParams);

         }

依次调用所有注册的hook函数。

Hook函数的注册通过appDemoDxChNetRxPacketCbRegister()来实现,所有的协议都需要通过该函数来注册hook():

    appDemoDxChNetRxPacketCbRegister(appDemoLink);    

appDemoDxChNetRxPacketCbRegister(appDemoDxChForwardPktCb);    

appDemoDxChNetRxPacketCbRegister(appDemoDxChNetLldpProtocolCb);

1)、appDemoLink:

如果22端口目的mac==0x01 80 c2 00 00 86的packate,获取千兆口mac的link状态,checkPhyLinkStatus();更新mac千兆口的link状态;

2)、appDemoDxChForwardPktCb:

fwdPktRecv任务线程中,通过appDemoDxChNetRxPacketCbRegister(appDemoDxChForwardPktCb);  来注册hook;

appDemoDxChForwardPktCb()函数中,主要通过

osMemCpy()报文拷贝;

osMsgQSend(fwdPktTaskQueueId, &packets);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值