VxWorks 6.6網(wǎng)絡(luò)協(xié)議棧分析及網(wǎng)絡(luò)接口基本知識

本文包含網(wǎng)絡(luò)接口的硬件基本原理和VxWorks 6.6網(wǎng)絡(luò)協(xié)議棧/驅(qū)動的分析,適用于VxWorks6.6以及之前的版本,并可用作其他版本協(xié)議棧的參考。

0. 概述

0.1 網(wǎng)絡(luò)接口

以太網(wǎng)目前有兩種模型,即ISO(國際標(biāo)準(zhǔn)化組織)定義的的OSI七層模型和IETF(互聯(lián)網(wǎng)工程任務(wù)組)的TCP/IP五層模型,具體可參考TCP/IP協(xié)議詳解。目前,TCP/IP為互聯(lián)網(wǎng)的事實(shí)標(biāo)準(zhǔn),具體分層如下所示:

OSI TCP/IP 實(shí)體
應(yīng)用層
表示層 應(yīng)用層 FTP/HTTP等
會話層
傳輸層 傳輸層 TCP/UDP
網(wǎng)絡(luò)層 網(wǎng)絡(luò)層 IP
鏈路層 鏈路層 MAC(介質(zhì)訪問控制器)
物理層 物理層 PHY(物理層)

上表中:

  • 以太網(wǎng)報文格式與上表的分層對應(yīng):
    物理層 鏈路層 網(wǎng)絡(luò)層 傳輸層 應(yīng)用層 鏈路層
    前導(dǎo)位、起始標(biāo)志 以太網(wǎng)頭 IP頭 TCP/UDP頭等 FTP/HTTP數(shù)據(jù)等 CRC校驗(yàn)
  • MAC又稱為以太網(wǎng)控制器,既具有獨(dú)立的鏈路層地址(MAC地址,又稱為以太網(wǎng)地址),也就是通常意義上或者狹義上的網(wǎng)口,用于控制鏈路層數(shù)據(jù)的傳輸;
  • PHY用于控制物理層傳輸,用于物理鏈路與MAC之間數(shù)據(jù)的編解碼、物理鏈路控制、載波偵聽、線序交換等功能,通常只包含PCS(物理編碼子層)、PMD(物理介質(zhì)相關(guān)子層)、PMA(物理介質(zhì)附加子層)等,但是1000Mbps以上的高速鏈路需要更多的子層(DTE XGXS、PHY XGXS);
  • MAC通過MII(狹義上的介質(zhì)獨(dú)立接口)/RGMII(簡化的千兆介質(zhì)無關(guān)接口)/SGMII(串行千兆介質(zhì)無關(guān)接口)/XGMII(超高速介質(zhì)無關(guān)接口)總線等連接到PHY上;
  • 每個MAC通常只需要一個PHY,但是1000Mbps以上的高速網(wǎng)口的PHY設(shè)備需要可能還需要先通過內(nèi)部PHY將TBI接口轉(zhuǎn)換成SGMII接口或者將XGMII接口轉(zhuǎn)換成XAUI接口,再連接到外部PHY,從而降低外部PHY的布線難度;
  • TBI、XAUI和MII、RGMII、SGMII、XGMII、GMII、QGMII等接口都屬于廣義上的MII接口,對應(yīng)于MII總線;
  • PHY必須掛在MII總線上,通過MII控制器訪問;
  • MII接口有MDIO22和MIDO45兩種標(biāo)準(zhǔn),分別定義在802.3ap clasue22和Clasue 45中, 前者支持5位PHY地址和5位寄存器地址,后者增加了5位設(shè)備地址,允許控制PHY的不同子層;因此,每個MII控制器最多通過MII總線支持32個PHY設(shè)備
  • 廣義上的網(wǎng)口指的是MAC、MII控制器和PHY的綜合體。

0.2 約定

  1. socket即套接字,是BSD協(xié)議棧提出的網(wǎng)絡(luò)接口,包含一個接收緩沖區(qū),用于收發(fā)數(shù)據(jù)和控制數(shù)據(jù)傳輸;
  2. MBLK/Cluster/data是BSD協(xié)議棧提出的緩沖區(qū)模型,每個數(shù)據(jù)區(qū)data對應(yīng)一個Cluster,每個Cluster關(guān)聯(lián)到1個MBLK上;MBLK作為以太網(wǎng)報文的代表,可以將多個以太網(wǎng)報文分片串成一個鏈表,用以提升數(shù)據(jù)收發(fā)效率;
  3. 分析以VxWorks6.6上的MPC5200 FEC網(wǎng)口為例,適用于VxWorks6.6以及之前的版本,并可用作其他版本協(xié)議棧的參考;
  4. 流程圖中的非關(guān)鍵函數(shù)參數(shù)和非關(guān)鍵流程被省略以突出重點(diǎn)和降低工作量;

1. END驅(qū)動架構(gòu)

END驅(qū)動整體架構(gòu)如下所示:


Snipaste_2022-08-13_11-59-17.png

其中:

  1. 用戶可以通過3種接口訪問協(xié)議棧接口:
    • socket:由sockLib庫提供,包括socket/bind/connect/listen/accept/getsockopt/setsockopt/recv/recvfrom/recvmsg/send/sendmsg/sendto()等;其中:
    • 通用IO接口:由sockLib庫提供,包括close/ioctl/write/ioctl()
    • ipcom/ipnet接口:由ipcom/ipnet提供,包括ifconfig等;
  2. sockLib庫位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket,提供socket接口,并調(diào)用iosDrvInstall()接口安裝IO設(shè)備驅(qū)動,從而為每個socket套接字創(chuàng)建描述符以提供通用IO接口,其中:
    • socket/accept接口除了調(diào)用ipcom/ipnet注冊的socketRtn/acceptRtn()鉤子函數(shù),還需要調(diào)用iosLib庫接口創(chuàng)建IO設(shè)備作為socket描述符;
    • 其余socket接口在進(jìn)行簡單的參數(shù)檢查后直接調(diào)用ipcom/ipnet注冊的對應(yīng)鉤子函數(shù);
    • 通用IO接口對應(yīng)于sockLib庫在安裝IO設(shè)備驅(qū)動時注冊的socketClose/socketRead/socketWrite/socketIoctl()接口,這些接口在進(jìn)行簡單的參數(shù)檢查后直接調(diào)用ipcom/ipnet注冊的對應(yīng)鉤子函數(shù);
  3. ipnet/ipcom位于components/ip_net2-6.6,使用sockLibAdd()將AF_NET/AF_PACKET等協(xié)議棧及包含socket/bind/connect/listen/accept/getsockopt/setsockopt/recv/recvfrom/recvmsg/send/sendmsg/sendto()等鉤子的功能列表注冊到sockLib的sockLibMap[];其中:
    • ipcom提供OS封裝層,用于屏蔽OS的不同,并綁定到MUX層,主要代碼位于components/ip_net2-6.6、ipcom/port/vxworks
    • ipnet/ipcom調(diào)用muxLib提供的muxDevStart/muxDevStop/muxIoctl/muxSend/muxDevLoad/muxDevUnload/muxBind/muxUnbind()接口來完成協(xié)議棧綁定、、驅(qū)動加載、網(wǎng)口控制和數(shù)據(jù)收發(fā)功能;
  4. muxLib位于vxworks-6.6/target/src/wrn/coreip/common/mux,用于將協(xié)議棧綁定到不同的網(wǎng)口上,并提供網(wǎng)卡控制接口,包括:
    • muxDevStart/muxDevStop/muxIoctl接口:主要通過調(diào)用endLib封裝的網(wǎng)口驅(qū)動功能列表中相應(yīng)的start/stop/ioctl鉤子來完成;
    • muxSend接口:首先通過endLib封裝的網(wǎng)口驅(qū)動功能列表中的formAddress鉤子生成地址,然后調(diào)用endLib封裝的網(wǎng)口驅(qū)動功能列表中的packetDataGet鉤子和muxBind接口安裝的stackRcvRtn來過濾本地數(shù)據(jù)包,最后調(diào)用endLib封裝的網(wǎng)口驅(qū)動功能列表中的send/formAddress/packetDataGet鉤子來完成發(fā)送功能;
    • muxReceive接口:通過muxBind接口安裝的stackRcvRtn將數(shù)據(jù)上傳到ipnet/ipcom
    • muxDevLoad接口:調(diào)用驅(qū)動提供的xxxEndLoad接口加載網(wǎng)口驅(qū)動,然后調(diào)用endLib提供的endFlagsSet設(shè)置END_MIB_2233標(biāo)志(m5200FecEnd不支持2233 MIB),并使用ioctl判斷end類型以設(shè)置pEnd->receiveRtnmuxReceivem5200FecEnd類型為END_STYLE_END);
  5. end層用于提供網(wǎng)卡驅(qū)動的封裝結(jié)構(gòu)和公用代碼。

2. 網(wǎng)卡驅(qū)動全工作流程

2.1 初始化流程

網(wǎng)卡驅(qū)動初始化入口為usrNetworkInit():

  1. usrNetworkInit:該位于<工程目錄>/prjConfig.c中,調(diào)用usrNetEndLibInit(),用于初始化網(wǎng)卡驅(qū)動;
  2. usrNetEndLibInit:該接口位于vxworks-6.6/target/src/config/usrNetwork.cvxworks-6.6/target/config/comps/src/net/coreip/usrNetEndLib.c中,關(guān)鍵流程如下所示:
    Snipaste_2022-08-13_11-55-29.png

    其中:
    • vxbDevMethodRun()遍歷VxBus驅(qū)動,調(diào)用所有提供muxDevConnect接口的網(wǎng)卡驅(qū)動,不適用于lite5200b的Legacy網(wǎng)卡驅(qū)動;
    • endDevTbl[]數(shù)組包含Legacy網(wǎng)卡驅(qū)動,定義于BSP目錄的configNet.h中:
      #define FEC_LOAD_FUNC   m5200FecEndLoad
      ...
      #define FEC_LOAD_STR "-1:0x0:-1:-1:0x40:0x30:0x0:0xff:2:0x4:" \
              FEC_CLOCK_SPEED(IPB_CLOCK_LITERAL)
      
      #define FEC_BUFF_LOAN   1
      ...
      END_TBL_ENTRY endDevTbl [] =
      {
      #ifdef INCLUDE_FEC_END
          { 0, FEC_LOAD_FUNC, FEC_LOAD_STR, FEC_BUFF_LOAN, NULL, FALSE},
      #endif /* INCLUDE_FEC_END */
      ...
      };
      
    • endPollStatsInit()用于初始化網(wǎng)口驅(qū)動的統(tǒng)計信息。
  3. muxDevLoad():位于vxworks-6.6/target/src/wrn/coreip/common/mux/muxLib.c中,用于調(diào)用endDevTbl[]數(shù)組中Legacy網(wǎng)口驅(qū)動的初始化函數(shù)endLoad,關(guān)鍵流程如下所示:
    Snipaste_2022-08-13_11-56-17.png

    其中:
    • 第一次調(diào)用endLoad時參數(shù)為空字符串,用于獲取網(wǎng)口名稱,例如'fec';
    • 第二次調(diào)用endLoad時參數(shù)為網(wǎng)口單元號與初始化字符串的組合,用于正式加載網(wǎng)口;
  4. muxDevStart():位于vxworks-6.6/target/src/wrn/coreip/common/mux/muxLib.c中,用于調(diào)用驅(qū)動注冊的pEnd->pFuncTable->start()接口啟動網(wǎng)口,并將網(wǎng)口設(shè)置為IFF_UP | IFF_RUNNING狀態(tài)
  5. m5200FecEndLoad():驅(qū)動接口,主要功能是注冊到endLib:
    • 分配驅(qū)動信息結(jié)構(gòu)和PHY信息結(jié)構(gòu);
    • 調(diào)用m5200FecInitParse解析初始化字符串并保存在驅(qū)動信息結(jié)構(gòu)中;
    • 調(diào)用m5200FecInitMem申請臨時發(fā)送緩沖區(qū),并創(chuàng)建netpool網(wǎng)絡(luò)緩沖池;
    • 調(diào)用m5200FecSdmaTaskInit創(chuàng)建Bestcomm SDMA任務(wù);
    • 調(diào)用END_OBJ_INITendObjInit初始化END結(jié)構(gòu),注冊網(wǎng)口驅(qū)動功能列表;
    • 調(diào)用END_FLAGS_SET設(shè)置多播和廣播標(biāo)志;
  6. m5200FecStart():驅(qū)動接口,主要功能是啟動網(wǎng)口:
    • 調(diào)用m5200FecReset復(fù)位以太網(wǎng)控制器;
    • 調(diào)用m5200FecTbdInit/m5200FecRbdInit初始化收發(fā)緩沖區(qū)描述符環(huán);
    • 調(diào)用SYS_FEC_INT_CONNECTintConnect掛接BestComm發(fā)送和接收任務(wù)中斷以及通用中斷處理函數(shù);
    • 調(diào)用SYS_FEC_INT_ENABLEintEnable使能中斷;
    • 調(diào)用m5200FecPrePhyConfig初始化MAC地址、設(shè)置中斷事件掩碼、清除中斷事件、配置內(nèi)部MII控制器接口等;
    • 調(diào)用m5200FecPhyPreInit根據(jù)驅(qū)動信息結(jié)構(gòu)中的標(biāo)志設(shè)置PHY信息結(jié)構(gòu)中的工作模式標(biāo)志;
    • 調(diào)用_func_m5200FecPhyInitm5200FecPhyInit初始化PHY,并根據(jù)PHY信息結(jié)構(gòu)中的工作模式標(biāo)志選擇自協(xié)商模式或強(qiáng)制模式;
    • 調(diào)用TaskIntClear清除Bsetcomm接收任務(wù)中斷;
    • 調(diào)用TaskStart啟動Bsetcomm接收任務(wù);
    • 調(diào)用FEC_END_ETH_ENABLE使能以太網(wǎng)控制器;
    • 調(diào)用END_FLAGS_SET將網(wǎng)口標(biāo)志為IFF_UP | IFF_RUNNING,即工作狀態(tài);
    • 調(diào)用netJobAddmuxTxRestart添加到tNet0任務(wù)維護(hù)的netJobQueueId隊(duì)列,進(jìn)而調(diào)用綁定在網(wǎng)口上的協(xié)議棧的stackTxRestartRtn接口以復(fù)位協(xié)議棧。

2.2 發(fā)送流程

發(fā)送流程的入口為socket庫提供的send/sendto/sendmsg()和ios子系統(tǒng)提供的write()

  1. send/sendto/sendmsg():調(diào)用協(xié)議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的sendRtn/sendtoRtn/sendmsgRtn(),即ipcom_windnet_send/sendto/sendmsg()位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  2. write():調(diào)用socket庫安裝到ios子系統(tǒng)的socket驅(qū)設(shè)備的socketWrite()鉤子,進(jìn)而調(diào)用協(xié)議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的socketwriteRtn(),即ipcom_windnet_socketwrite(),位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  3. ipcom_windnet_send/sendto/sendmsg/socketwrite():調(diào)用ipcom_send/sendto/sendmsg/send(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  4. ipcom_send/sendto/sendmsg/send():調(diào)用ipcom_sendmsg(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  5. ipcom_sendmsg():調(diào)用sock->ops->send(),即ipnet_init()注冊并由socket()接口使用ipcom_socket()安裝的iptcp_send和ipnet_sock_udp_send接口;
  6. iptcp_send和ipnet_sock_udp_send():
    • UDP分支:
      • ipnet_sock_udp_send():調(diào)用ops->i.network_send(),即ipnet_ip4_sendto(),位于components/ip_net2-6.6/ipnet2/src/ipnet_udp.c
    • TCP分支:
      • iptcp_send():調(diào)用iptcp_create_output_seg(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
      • iptcp_create_output_seg():調(diào)用iptcp_output(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
      • iptcp_output():調(diào)用iptcp_sendto(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
      • iptcp_sendto():調(diào)用sock->ops->network_send(),即ipnet_ip4_sendto(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
        7.ipnet_ip4_sendto():調(diào)用netif->link_ip4_output(),即ipnet_eth_if_init安裝的ipnet_eth_ip4_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_ip4.c
  7. ipnet_eth_ip4_output():調(diào)用ipnet_if_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_eth.c
  8. ipnet_if_output():調(diào)用ipnet_if_drv_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  9. ipnet_if_drv_output():調(diào)用netif->ipcom.drv_output(),即ipcom_drv_eth_init安裝的ipcom_drv_eth_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  10. ipcom_drv_eth_output():調(diào)用muxSend(),位于components/ip_net2-6.6/ipcom/port/vxworks/src/ipcom_drv_eth.c
  11. muxSend():位于components/ip_net2-6.6/ipcom/port/vxworks/src/ipcom_drv_eth.c,使用pEnd->pFuncTable->send()作為參數(shù)調(diào)用_muxTkSendEnd進(jìn)行通用處理,參數(shù)檢查失敗則直接釋放pMBlk發(fā)送緩沖區(qū);
  12. _muxTkSendEnd:位于components/ip_net2-6.6/ipcom/port/vxworks/src/ipcom_drv_eth.c,進(jìn)行通用處理:
    • 更新2233 MIB中的發(fā)包統(tǒng)計信息;
    • 如果目的MAC地址非空,則調(diào)用pEnd->pFuncTable->formAddressm5200FecEndLoad安裝的endEtherAddressForm構(gòu)造以太網(wǎng)頭并放到pMBlk發(fā)送緩沖區(qū);
    • 如果網(wǎng)口已綁定協(xié)議棧,則調(diào)用pEnd->pFuncTable->packetDataGetendEtherPacketDataGet獲取pMBlk發(fā)送緩沖區(qū)的數(shù)據(jù)指針,然后調(diào)用muxEndRcvRtn接收數(shù)據(jù)到協(xié)議棧;
    • 調(diào)用muxSend傳遞過來鉤子調(diào)用pEnd->pFuncTable->send(),即m5200FecEndLoad函數(shù)安裝的m5200FecSend()
    • 如果發(fā)送阻塞即網(wǎng)口忙,則從pMBlk發(fā)送緩沖區(qū)移除以太網(wǎng)頭,返回錯誤信息等待協(xié)議棧再次發(fā)送;
  13. m5200FecSend():驅(qū)動接口,將數(shù)據(jù)寫入發(fā)送緩沖區(qū)并發(fā)送,
    • 檢查參數(shù)和工作模式,失敗則返回;
    • 計算pMBlk發(fā)送緩沖區(qū)的分片數(shù);
    • 如果發(fā)送緩沖區(qū)描述符個數(shù)為0,則調(diào)用m5200FecTbdClean清理發(fā)送緩沖區(qū);
    • 如果送緩沖區(qū)描述符個數(shù)大于pMBlk發(fā)送緩沖區(qū)的分片數(shù)、緩沖區(qū)地址滿足對齊要求且m5200FecForceCopy為false,則調(diào)用m5200FecPktTransmit;否則,調(diào)用m5200FecPktCopyTransmit
  14. m5200FecPktTransmit():驅(qū)動接口,使用pMBlk發(fā)送緩沖區(qū)進(jìn)行零拷貝傳輸:
    • 調(diào)用m5200FecTbdListSet獲取發(fā)送緩沖區(qū)描述符列表;
    • 使用將pMBlk發(fā)送緩沖區(qū)各分片對應(yīng)的數(shù)據(jù)指針設(shè)置發(fā)送緩沖區(qū)描述符的緩沖區(qū)指針并更新發(fā)送緩沖區(qū)描述符標(biāo)志;
    • 調(diào)用TaskStart啟動BestComm發(fā)送任務(wù);
    • 調(diào)用CACHE_PIPE_FLUSH刷新寫緩沖;
  15. m5200FecPktCopyTransmit():驅(qū)動接口,從驅(qū)動創(chuàng)建的netpool中申請新的MBLK用于保存pMBlk發(fā)送緩沖區(qū)中的所有數(shù)據(jù),然后發(fā)送:
    • 調(diào)用NET_BUF_ALLOC申請cluster即數(shù)據(jù)緩沖區(qū),申請失敗則使用臨時發(fā)送緩沖區(qū),仍然失敗則返回發(fā)送阻塞;
    • 對齊發(fā)送緩沖區(qū)數(shù)據(jù)地址到32字節(jié);
    • 調(diào)用m5200FecTbdListSet獲取發(fā)送緩沖區(qū)描述符列表;
    • 使用將pMBlk發(fā)送緩沖區(qū)各分片對應(yīng)的數(shù)據(jù)拷貝到申請的新發(fā)送緩沖區(qū)中;
    • 使用新發(fā)送緩沖區(qū)的指針設(shè)置發(fā)送緩沖區(qū)描述符的緩沖區(qū)指針并更新發(fā)送緩沖區(qū)描述符標(biāo)志;
    • 調(diào)用TaskStart啟動BestComm發(fā)送任務(wù);
    • 調(diào)用CACHE_PIPE_FLUSH刷新寫緩沖;
  16. m5200FecWdmaInt():驅(qū)動接口,BestComm發(fā)送任務(wù)完成后會觸發(fā)BestComm發(fā)送任務(wù)中斷,并調(diào)用該函數(shù):
    • 調(diào)用SDMA_INT_DISABLE關(guān)閉BestComm發(fā)送任務(wù)中斷;
    • 調(diào)用TaskIntClear清除BestComm發(fā)送任務(wù)中斷;
    • 調(diào)用CACHE_PIPE_FLUSH刷新寫緩沖;
    • 調(diào)用netJobAddm5200FecTxHandle添加到tNet0任務(wù)維護(hù)的netJobQueueId隊(duì)列,失敗則調(diào)用SDMA_INT_ENABLE使能BestComm發(fā)送任務(wù)退出;
  17. m5200FecTxHandle():清理發(fā)送緩沖區(qū)描述符和BestComm發(fā)送任務(wù):
    • 調(diào)用m5200FecTbdClean清理發(fā)送緩沖區(qū);
    • 調(diào)用intLock鎖中斷;
    • 如果BestComm發(fā)送任務(wù)狀態(tài)非空,則清除當(dāng)前BestComm發(fā)送任務(wù)狀態(tài),調(diào)用intUnlock解鎖中斷,再次回到調(diào)用m5200FecTbdClean清理發(fā)送緩沖區(qū),直到BestComm發(fā)送任務(wù)狀態(tài)為空再調(diào)用intUnlock解鎖中斷并退出。

2.3 接收流程

接收流程的用戶程序入口為socket庫提供的recv/recvfrom/recvmsg()和ios子系統(tǒng)提供的read()

  1. recv/recvfrom/recvmsg():調(diào)用協(xié)議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的recvRtn/recvfromRtn/recvmsgRtn(),即ipcom_windnet_recv/recvfrom/recvmsg()位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  2. read():調(diào)用socket庫安裝到ios子系統(tǒng)的socket驅(qū)設(shè)備的socketRead()鉤子,進(jìn)而調(diào)用協(xié)議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的socketresdRtn(),即ipcom_windnet_socketread(),位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  3. ipcom_windnet_recv/socketread():調(diào)用ipcom_recv(),進(jìn)而調(diào)用ipcom_recvfrom,位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  4. ipcom_windnet_recvfrom/recvmsg():調(diào)用ipcom_recvfrom/recvmsg(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  5. ipcom_recvfrom():調(diào)用ipcom_recvmsg(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  6. ipcom_recvmsg():調(diào)用sock->ops->recv(),即ipnet_init()注冊并由socket()接口使用ipcom_socket()安裝的iptcp_recv和ipnet_sock_pkt_recv接口;
  7. iptcp_recv/ipnet_sock_pkt_recv():如果socket的接收緩沖區(qū)中沒有報文,則根據(jù)用戶傳入的標(biāo)志決定直接返回或者掛起任務(wù)等待報文到來;否則,則取出報文,處理后返還給用戶程序入口。

接收流程的驅(qū)動程序入口為驅(qū)動的m5200FecRdmaInt

  1. m5200FecRdmaInt():調(diào)用m5200FecRxHandle接收數(shù)據(jù):
    • 讀取接收FIFO狀態(tài)并打印調(diào)試信息;
    • 調(diào)用intLock鎖中斷;
    • 調(diào)用SDMA_INT_DISABLE關(guān)閉接收DMA任務(wù)中斷;
    • 調(diào)用TaskIntClear清除BestComm接收任務(wù)中斷;
    • 調(diào)用intUnlock解鎖中斷;
    • 調(diào)用CACHE_PIPE_FLUSH刷新寫緩沖;
    • 調(diào)用netJobAddm5200FecRxHandle添加到tNet0任務(wù)維護(hù)的netJobQueueId隊(duì)列并退出;
  2. m5200FecRxHandle():處理BestComm接收任務(wù)中斷,
    • 調(diào)用m5200FecHandleRecvInt接收數(shù)據(jù);
    • 調(diào)用intLock鎖中斷;
    • 如果仍有BestComm接收任務(wù)中斷待處理,則調(diào)用TaskIntClear清除BestComm接收任務(wù)中斷,調(diào)用intUnlock解鎖中斷,調(diào)用netJobAddm5200FecRxHandle添加到tNet0任務(wù)維護(hù)的netJobQueueId隊(duì)列,調(diào)用intLock鎖中斷,并再次回到第一步調(diào)用m5200FecHandleRecvInt接收數(shù)據(jù),直到?jīng)]有BestComm接收任務(wù)中斷需要處理,才調(diào)用SDMA_INT_ENABLE使能BestComm接收任務(wù)中斷并退出;
  3. m5200FecHandleRecvInt():遍歷接收緩沖區(qū)描述符環(huán)形隊(duì)列,調(diào)用m5200FecReceive接收數(shù)據(jù)并上送協(xié)議棧;
  4. m5200FecReceive():接收數(shù)據(jù)并上送協(xié)議棧,
    • 如果接收緩沖區(qū)描述符有錯誤,則調(diào)用m5200FecRbdClean清除接收緩沖區(qū)描述符并退出;
    • 從驅(qū)動的netpool緩沖池申請MBLK和cluster,并關(guān)聯(lián)到接收緩沖區(qū)描述符的緩沖區(qū)指針,同時從驅(qū)動的netpool緩沖池申請新的緩沖區(qū)用以更新接收緩沖描述符的緩沖區(qū)指針;
    • 調(diào)用m5200FecRbdClean清除接收緩沖區(qū)描述符;
    • 調(diào)用END_RCV_RTN_CALL上傳數(shù)據(jù)到協(xié)議棧。
  5. END_RCV_RTN_CALL:調(diào)用pEnd->receiveRtnmuxReceive,失敗則調(diào)用netMblkClChainFree釋放發(fā)送緩沖區(qū)pMBLK;
  6. muxReceive():接收數(shù)據(jù)上傳協(xié)議棧:
    • 調(diào)用pEnd->pFuncTable->packetDataGetendEtherPacketDataGet獲取pMBlk接收緩沖區(qū)的數(shù)據(jù)指針;
    • 獲取以太網(wǎng)頭中的報文類型;
    • 遍歷綁定在網(wǎng)口上的協(xié)議棧,若匹配則調(diào)用協(xié)議棧的接收函數(shù)pProto->rr.endRcvmuxEndRcvRtn將數(shù)據(jù)放入?yún)f(xié)議棧的緩沖區(qū);
    • 更新2233 MIB接收統(tǒng)計信息;
    • 調(diào)用netMblkClChainFree釋放發(fā)送緩沖區(qū)`pMBLK。
  7. muxEndRcvRtn():調(diào)用pBinding->stackRcvRtn,即協(xié)議棧調(diào)用muxBind綁定的deng stackRcvRtn函數(shù)指針將數(shù)據(jù)上傳到協(xié)議棧的緩沖區(qū)。

3. ifconfig up/down流程

ifconfig的入口位于vxworks-6.6/target/src/wrn/coreip/wrapper/utilslib/ifconfig.c,主要流程如下所示:

  1. ifconfig():調(diào)用ipnet_cmd_ifconfig(),位于vxworks-6.6/target/src/wrn/coreip/wrapper/utilslib/ifconfig.c
  2. ipnet_cmd_ifconfig():調(diào)用ipcom_socket()創(chuàng)建socket,然后使用IP_TRUE和IP_FALSE調(diào)用ipnet_ifconfig_if_change_state(),位于components/ip_net2-6.6/ipnet2/src/ipnet_cmd_ifconfig.c
  3. ipnet_ifconfig_if_change_state():使用IP_SIOCSIFFLAGS,并設(shè)置或清除IP_IFF_UP來調(diào)用ipcom_socketioctl(),位于
    components/ip_net2-6.6/ipnet2/src/ipnet_ioctl.c
  4. ipcom_socketioctl():調(diào)用ipnet_do_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_ioctl.c
  5. ipnet_do_ioctl():調(diào)用ipnet_ioctl_if(),位于components/ip_net2-6.6/ipnet2/src/ipnet_ioctl.c
  6. ipnet_ioctl_if():使用IP_SIOCXOPEN或IP_SIOCXCLOSE調(diào)用ipnet_if_link_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  7. ipnet_if_link_ioctl():調(diào)用netif->link_ioctl(),即通過ipnet_eth_if_init()安裝的ipnet_eth_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  8. ipnet_eth_ioctl():調(diào)用ipnet_if_drv_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_eth.c
  9. ipnet_if_drv_ioctl():調(diào)用ipnet_if_clean_snd_queue()清理并復(fù)位當(dāng)前接口上的隊(duì)列,然后調(diào)用netif->ipcom.drv_ioctl(),即通過ipcom_drv_eth_init()安裝的ipcom_drv_eth_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  10. ipcom_drv_eth_ioctl():為IP_SIOCXOPEN調(diào)用ipnet_drv_eth_sync_with_end_flags(),為IP_SIOCXCLOSE調(diào)用netif->link_ioevent即ipnet_eth_ioevent()通知協(xié)議棧網(wǎng)口處于IP_EIOXSTOP,位于components/ip_net2-6.6/ipnet2/src/ipnet_eth.c
  11. ipnet_drv_eth_sync_with_end_flags():調(diào)用muxIoctl獲取網(wǎng)口標(biāo)志和狀態(tài),若網(wǎng)口處于活動狀態(tài)度,則調(diào)用netif->link_ioevent即ipnet_eth_ioevent()通知協(xié)議棧網(wǎng)口處于IP_EIOXRUNNING狀態(tài)。

綜上所述,ifconfig up/down不會真正操作網(wǎng)口驅(qū)動,只是清理并復(fù)位當(dāng)前網(wǎng)口上的隊(duì)列,然后通知協(xié)議棧網(wǎng)口處于IP_EIOXRUNNING或IP_EIOXSTOP狀態(tài)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,690評論 2 370

推薦閱讀更多精彩內(nèi)容