rtl8812驱动分析(一)

wifi驱动的入口->os_dep/linux/usb_intf.c

insmod 8188.ko和rmmod 8188.ko时分别调用的是:

module_init(rtw_drv_entry);
module_exit(rtw_drv_halt);

所以,找到这两个函数,就分别找到了初始化和退出函数

初始化:

static int __init rtw_drv_entry(void)
{
#ifdef CONFIG_PLATFORM_RTK_DMP
    u32 tmp;
    tmp=readl((volatile unsigned int*)0xb801a608);
    tmp &= 0xffffff00;
    tmp |= 0x55;
    writel(tmp,(volatile unsigned int*)0xb801a608);//write dummy register for 1055
#endif
#ifdef CONFIG_PLATFORM_ARM_SUNxI
#ifndef CONFIG_RTL8723A
    int ret = 0;
    /* ----------get usb_wifi_usbc_num------------- */
    ret = script_parser_fetch("usb_wifi_para", "usb_wifi_usbc_num", (int *)&usb_wifi_host, 64);
    if(ret != 0){
        printk("ERR: script_parser_fetch usb_wifi_usbc_num failed\n");
        ret = -ENOMEM;
        return ret;
    }
    printk("sw_usb_enable_hcd: usbc_num = %d\n", usb_wifi_host);
    sw_usb_enable_hcd(usb_wifi_host);
#endif //CONFIG_RTL8723A
#endif //CONFIG_PLATFORM_ARM_SUNxI

#ifdef CONFIG_PLATFORM_ARM_SUN6I
    script_item_value_type_e type;

    type = script_get_item("wifi_para", "wifi_usbc_id", &item);
    if(SCIRPT_ITEM_VALUE_TYPE_INT != type){
        printk("ERR: script_get_item wifi_usbc_id failed\n");
        return -ENOMEM;
    }

    printk("sw_usb_enable_hcd: usbc_num = %d\n", item.val);
    wifi_pm_power(1);
    mdelay(10);
    sw_usb_enable_hcd(item.val);
#endif //CONFIG_PLATFORM_ARM_SUN6I

    RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_drv_entry\n"));

    DBG_871X(DRV_NAME " driver version=%s\n", DRIVERVERSION);
    DBG_871X("build time: %s %s\n", __DATE__, __TIME__);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
    //console_suspend_enabled=0;
#endif

    rtw_suspend_lock_init();

    usb_drv->drv_registered = _TRUE;
    return usb_register(&usb_drv->usbdrv);
}

初始化函数主要做的事情:

  1. 打开wifi模块的电源,会根据不同的平台不同的模块进行处理;
  2. 初始化挂起锁,这个后边再分析,猜是防止多线程同时挂起模块时会引起模块问题;
  3. 驱动注册标志位置1;
  4. 注册usb驱动,因为我们的模块接口是USB接口的,所以对系统来说其实就是个USB设备,自然要注册usb驱动。

接着,我们来重点看一下这个注册的usb驱动:

#ifdef CONFIG_RTL8192C
static struct usb_device_id rtl8192c_usb_id_tbl[] ={
    RTL8192C_USB_IDS
    {}  /* Terminating entry */
};

struct rtw_usb_drv rtl8192c_usb_drv = {
    .usbdrv.name = (char*)"rtl8192cu",
    .usbdrv.probe = rtw_drv_init,
    .usbdrv.disconnect = rtw_dev_remove,
    .usbdrv.id_table = rtl8192c_usb_id_tbl,
    .usbdrv.suspend =  rtw_suspend,
    .usbdrv.resume = rtw_resume,
    #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
    .usbdrv.reset_resume   = rtw_resume,
    #endif
    #ifdef CONFIG_AUTOSUSPEND
    .usbdrv.supports_autosuspend = 1,
    #endif

    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
    .usbdrv.drvwrap.driver.shutdown = rtw_dev_shutdown,
    #else
    .usbdrv.driver.shutdown = rtw_dev_shutdown,
    #endif
};

static struct rtw_usb_drv *usb_drv = &rtl8192c_usb_drv;
#endif /* CONFIG_RTL8192C */

我们的模块是8812CUS,但是不知道为何是8192c的配置选项?留着疑问,后边解决。
注册的usb驱动中主要提供的接口如下:

  1. probe探测函数
  2. disconnet函数
  3. idtable列表,表示支持的设备的PIDVID信息
  4. 挂起和唤醒函数

在idtables中我们可以看到 RTL8192C_USB_IDS的定义,找到它,我们发现,我们的8812CUS模块也在其中(通过查看PID和VID发现我们的模块型号为PID8176,即列表中的第二行):

#define RTL8192C_USB_IDS \
    /*=== Realtek demoboard ===*/ \
    {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191)},/* Default ID */ \
    /****** 8188CUS ********/ \
    {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8176)},/* 8188cu 1*1 dongole */ \
    {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170)},/* 8188CE-VAU USB minCard */ \
    {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817E)},/* 8188CE-VAU USB minCard */ \
    {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817A)},/* 8188cu Slim Solo */ \

这个驱动insmod后,注册到USB驱动链上,当usb设备接入,由usb子系统枚举后,获取设备的描述符,最后通过描述符中的PID和VID信息为其匹配驱动,通过遍历usb驱动链上的id列表的方式找到支持该设备的驱动,最后在这个列表中找到匹配,并将设备和这个驱动绑定。
后续继续分析wifi驱动的probe的过程,以及一些内核线程的创建过程。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RK3566是一款高性能的64位四核芯片,可提供丰富的接口和功能,广泛应用于各种嵌入式系统中。而RTL8211F是一款高集成度的Gigabit以太网PHY芯片,用于处理以太网通信。 要调试RK3566与RTL8211F的驱动,首先需要确保硬件连接正确。RTL8211F芯片通过PHY接口与RK3566芯片连接,需要将各个引脚正确连接,确保通信能够正常进行。 其次,需要加载正确的驱动程序。在RK3566的系统中,需要加载相应的网卡驱动程序,以支持与RTL8211F的通信。可以通过在系统中运行lspci命令来确认网卡设备的驱动程序是否正确加载。 接下来,可以通过网络配置工具来设置与RTL8211F的通信参数。在Linux系统中,可以使用ifconfig命令或者网络管理工具,如NetworkManager来配置网络接口。可以设置IP地址、子网掩码、网关等参数,确保RK3566能够与RTL8211F正常通信。 调试过程中,还可以使用网络诊断工具来检查网络连接是否正常。例如,可以使用ping命令来测试RK3566与另一个设备之间的连通性。如果ping命令成功返回,则表示网络连接正常。 最后,还可以使用网络分析工具来进行包的抓取和分析,以进一步调试和排查可能出现的问题。例如,可以使用Wireshark对网络数据包进行抓取和分析,以确认数据包的发送和接收情况。 总之,调试RK3566与RTL8211F的驱动需要确保硬件连接正确、加载正确的驱动程序、配置正确的网络参数,并使用网络诊断工具和分析工具进行进一步的调试和排查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值