码迷,mamicode.com
首页 > 其他好文 > 详细

ndis网卡驱动收发包

时间:2020-10-30 12:40:37      阅读:25      评论:0      收藏:0      [点我收藏+]

标签:初始化   set   offset   start   tail   case   article   tps   not   

尝试描述ndis网卡驱动的收发包过程

  1. 设置一个_NDIS_MINIPORT_DRIVER_CHARACTERISTICS结构,包含初始化,处理中断,发包等很多自己写的handle,初作为参数提供给MRegisterMiniportDriver函数
  2. MRegisterMiniportDriver会首先调用其中初始化handle模型如下
    NDIS_STATUS MiniportInitialize(
    ...NDIS_HANDLE NdisMiniportHandle,
    ...NDIS_HANDLE MiniportDriverContext,
    ...PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters // 系统给我们提供的_NDIS_MINIPORT_INIT_PARAMETERS结构
    )
    其中_NDIS_MINIPORT_INIT_PARAMETERS结构里包含一项 PNDIS_RESOURCE_LIST AllocatedResources, 这个AllocatedResources包含下面数据;
    switch (resource->Type) 【参考https://blog.csdn.net/xiangbaohui/article/details/105179813】
    {
    ... case CmResourceTypePort:
    ......Adapter->IoBaseAddress = resource->u.Port.Start ; // 得到了一个IoBaseAddress
    ......Adapter->IoRange = resource->u.Port.Length; //
    ...
    }
  3. 调用函数 NdisMRegisterIoPortRange去得到一个操控网卡的IO Port
    Status = NdisMRegisterIoPortRange(
    ... (PVOID *)&Adapter->PortOffset, // 返回一个portoffset,就是通过这个portoffset去操控硬件的,和以前的in out端口指令一样
    ... Adapter->AdapterHandle,
    ... NdisGetPhysicalAddressLow ( Adapter->IoBaseAddress ) , // 上面我们得到的IoBaseAddress
    ... Adapter->IoRange);
  4. 有了上面的portoffset,我们可以给硬件下命令,设置收发包的地址,RxDescStartAddr和TxDescStartAddr都是【portoffset+寄存器偏移】,操作相应地址等于下相应的命令
    case SCB_RUC_LOAD_BASE : // 设置收包地址,为我们要收包的地址
    ... RTL_W32 ( RxDescStartAddr, NdisGetPhysicalAddressLow ( Adapter->HwRbdBasePa ) ); // 地址是自己分配的
    ... RTL_W32 ( RxDescStartAddr + 4, NdisGetPhysicalAddressHigh ( Adapter->HwRbdBasePa ));
    case SCB_TBD_LOAD_BASE : // 设置发包地址,写地址【portoffset+寄存器偏移】为我们要发包的地址
    ... RTL_W32 ( TxDescStartAddr, NdisGetPhysicalAddressLow ( Adapter->HwTbdBasePa ) ); // 地址是自己分配的
    ... RTL_W32 ( TxDescStartAddr + 4, NdisGetPhysicalAddressHigh ( Adapter->HwTbdBasePa ) );
  5. 地址设置好了,以后
    【 收包 - 网卡写数据到收包地址,生成一个中断,通知驱动程序的中断处理函数去取数据 】
    【 发包 - 我们把数据写到发包地址,通过portoffset通知网卡去取数据 】
    =================================================================================================================

大概流程如此,从系统得到一个portoffset,通过给portoffset下相应的命令,来完成对应的工作 (以前都是通过cpu的In out指令下的命令)。
-- 设置收发包地址(所谓的地址其实是一连串的地址描述符,下面)
-- 收包 - 数据写入后,产生硬件中断,通知我们去取
-- 发包 - 数据写好后,给portoffset下对应指令,让网卡去发

传给网卡的地址,参考 https://blog.csdn.net/hz5034/article/details/79794615这篇文章
设定的收发包地址,是一串的连续的描述符,addr->[描述符][描述符][描述符].N个.[描述符],把这个addr通过portoffset下命令传给网卡,网卡或是dma能够认识这个描述符的,他们会自动工作。
描述符的结构大概如下:
typedef struct _TBD_STRUC { // 发包的描述符, 一个包一个描述符
... UINT16 FrameLength ;
... UINT16 status;
... UINT32 notused;
... UINT32 TbdBufferAddress; // 网卡会去这个地址取发包的数据
... UINT32 TbdBufferAddressHigh ;
} TBD_STRUC, *PTBD_STRUC;

typedef struct _RTK_RECEIVE_BUFFER_DESCRIPOR_STRUC { // 收包的描述符,网卡会挨个往里面的buf_addr地址写数据
... UINT32 status;
... UINT32 vlan_tag;
... UINT32 buf_addr; // 网卡会把数据写到这个地址
... UINT32 buf_Haddr;
} HW_RBD, *PHW_RBD;

参考:NDIS 6.0的miniport设备驱动 ---- http://www.codesoso.com/code/NDIS-miniport-driver.aspx

ndis网卡驱动收发包

标签:初始化   set   offset   start   tail   case   article   tps   not   

原文地址:https://www.cnblogs.com/asmalleyu/p/13899008.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!