rt2860v2源码分析二

本文深入剖析rt2860v2的源码,重点关注设备模块初始化和卸载过程。详细解释了如何分配无线网络适配器、初始化底层设备以及注册cfg80211网络设备。内容涵盖pci设备初始化,使用全局变量pAd表示的网络适配器结构体,以及涉及的数据结构和回调函数。此外,还提及了无线扩展wext及其在sta和ap模式下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查看rbus_main_dev.c文件中的设备模块初始化和模块卸载:


int rt2880_module_init(VOID)
{
    struct  net_device      *net_dev;
    ULONG               csr_addr;
    INT                 rv;
    PVOID               *handle = NULL;
    RTMP_ADAPTER        *pAd;
    unsigned int            dev_irq;
    RTMP_OS_NETDEV_OP_HOOK  netDevHook;


    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2880_probe\n"));  


/*RtmpRaBusInit============================================ */
    /* map physical address to virtual address for accessing register */
    csr_addr = (unsigned long)RTMP_MAC_CSR_ADDR;
    dev_irq = RTMP_MAC_IRQ_NUM;


/*RtmpDevInit============================================== */
    /* Allocate RTMP_ADAPTER adapter structure */
/*  handle = kmalloc(sizeof(struct os_cookie) , GFP_KERNEL); */
    os_alloc_mem(NULL, (UCHAR **)&handle, sizeof(struct os_cookie));
    if (!handle)
    {
        DBGPRINT(RT_DEBUG_ERROR, ("Allocate memory for os_cookie failed!\n"));
        goto err_out;
    }
    NdisZeroMemory(handle, sizeof(struct os_cookie));

#ifdef OS_ABL_FUNC_SUPPORT
    /* get DRIVER operations */
    RTMP_DRV_OPS_FUNCTION(pRtmpDrvOps, NULL, NULL, NULL);
#endif /* OS_ABL_FUNC_SUPPORT */

    rv = RTMPAllocAdapterBlock(handle, (VOID **)&pAd);
    if (rv != NDIS_STATUS_SUCCESS)
    {
        DBGPRINT(RT_DEBUG_ERROR, (" RTMPAllocAdapterBlock !=  NDIS_STATUS_SUCCESS\n"));
/*      kfree(handle); */
        os_free_mem(NULL, handle);

        goto err_out;
    }
    /* Here are the RTMP_ADAPTER structure with rbus-bus specific parameters. */
    pAd->CSRBaseAddress = (PUCHAR)csr_addr;

    RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_RBUS);


/*NetDevInit============================================== */
    net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
    if (net_dev == NULL)
        goto err_out_free_radev;

    /* Here are the net_device structure with pci-bus specific parameters. */
    net_dev->irq = dev_irq;         /* Interrupt IRQ number */
    net_dev->base_addr = csr_addr;      /* Save CSR virtual address and irq to device structure */
    ((POS_COOKIE)handle)->pci_dev = NULL; //net_dev;

#ifdef CONFIG_STA_SUPPORT
    pAd->StaCfg.OriDevType = net_dev->type;
#endif /* CONFIG_STA_SUPPORT */



#ifdef RT_CFG80211_SUPPORT
    /*
        In 2.6.32, cfg80211 register must be before register_netdevice();
        We can not put the register in rt28xx_open();
        Or you will suffer NULL pointer in list_add of
        cfg80211_netdev_notifier_call().
    */
    CFG80211_Register(pAd, pAd->pCfgDev, pNetDev);
#endif /* RT_CFG80211_SUPPORT */

/*All done, it's time to register the net device to kernel. */
    /* Register this device */
    rv = RtmpOSNetDevAttach(pAd->OpMode, net_dev, &netDevHook);
    if (rv)
    {
        DBGPRINT(RT_DEBUG_ERROR, ("failed to call RtmpOSNetDevAttach(), rv=%d!\n", rv));
        goto err_out_free_netdev;
    }

    /* due to we didn't have any hook point when do module remove, we use this static as our hook point. */
    rt2880_dev = net_dev;

    wl_proc_init();

    DBGPRINT(RT_DEBUG_TRACE, ("%s: at CSR addr 0x%lx, IRQ %u. \n", net_dev->name, (ULONG)csr_addr, net_dev->irq));

    DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2880_probe\n"));

#if defined(CONFIG_RA_CLASSIFIER)&&(!defined(CONFIG_RA_CLASSIFIER_MODULE))   
    proc_ptr = proc_ralink_wl_video;     
    if(ra_classifier_init_func!=NULL)    
        ra_classifier_init_func();   
#endif

    return 0;

err_out_free_netdev:
    RtmpOSNetDevFree(net_dev);

err_out_free_radev:
    /* free RTMP_ADAPTER strcuture and os_cookie*/
    RTMPFreeAdapter(pAd);

err_out:
    return -ENODEV;

} 



VOID rt2880_module_exit(VOID)
{
    struct net_device   *net_dev = rt2880_dev;
    RTMP_ADAPTER *pAd;


    if (net_dev == NULL)
        return;

    /* pAd = net_dev->priv; */
    GET_PAD_FROM_NET_DEV(pAd, net_dev);

    if (pAd != NULL)
    {
        RtmpPhyNetDevExit(pAd, net_dev);
        RtmpRaDevCtrlExit(pAd);
    }
    else
    {
        RtmpOSNetDevDetach(net_dev);
    }

    /* Free the root net_device. */
    RtmpOSNetDevFree(net_dev);

#if defined(CONFIG_RA_CLASSIFIER)&&(!defined(CONFIG_RA_CLASSIFIER_MODULE))
    proc_ptr = proc_ralink_wl_video;     
    if(ra_classifier_release_func!=NULL)     
        ra_classifier_release_func();    
#endif

    wl_proc_exit();
}

其中重要的内容:
RTMPAllocAdapterBlock 函数,该函数分配了无线网络的适配器
RtmpPhyNetDevInit 函数,和pci中probe中的一样,用来初始化底层的设备
CFG80211_Register 函数,cfg80211的网络设备注册接口
RtmpOSNetDevAttach 函数,实现无线网络设备的创建

根据网络设备的不同来选择网络设备模块的初始化,openwrt的路由器网络模块初始化使用pci,以后的分析按照pci设备来进行。

在分配网络设备时,使用到了pAd,用来表示网络适配器的全局变量,它是结构体_RTMP_ADAPTER,定义如下:

/* */
/*  The miniport adapter structure */
/* */
struct _RTMP_ADAPTER {
    PVOID OS_Cookie;    /* save specific structure relative to 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值