rtl8812驱动分析(二)

我们已经知道在insmod 8812.ko的时候,已经注册了一个usb驱动usb_drv->usbdrv, 其中的成员probe是最关键的,接下来我们来详细看一下probe的过程。

.usbdrv.probe = rtw_drv_init,
第一步:

static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *did)
{
	int i;
	uint status = _FAIL;
	_adapter *if1 = NULL, *if2 = NULL;
	struct dvobj_priv *dvobj = NULL;


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


	//step 0.
	process_spec_devid(did);

从函数名可以知道这是为了处理一些特别的设备,识别这些特殊设备也是通过PIDVID信息来的。

static void process_spec_devid(const struct usb_device_id *pdid)
{
	u16 vid, pid;
	u32 flags;
	int i;
	int num = sizeof(specific_device_id_tbl)/sizeof(struct specific_device_id);

	for(i=0; i<num; i++)
	{
		vid = specific_device_id_tbl[i].idVendor;
		pid = specific_device_id_tbl[i].idProduct;
		flags = specific_device_id_tbl[i].flags;

#ifdef CONFIG_80211N_HT
		if((pdid->idVendor==vid) && (pdid->idProduct==pid) && (flags&SPEC_DEV_ID_DISABLE_HT))
		{
			 rtw_ht_enable = 0;
			 rtw_cbw40_enable = 0;
			 rtw_ampdu_enable = 0;
		}
#endif

#ifdef RTK_DMP_PLATFORM
		// Change the ifname to wlan10 when PC side WFD dongle plugin on DMP platform.
		// It is used to distinguish between normal and PC-side wifi dongle/module.
		if((pdid->idVendor==vid) && (pdid->idProduct==pid) && (flags&SPEC_DEV_ID_ASSIGN_IFNAME))
		{
			extern char* ifname;
			strncpy(ifname, "wlan10", 6);
			//DBG_871X("%s()-%d: ifname=%s, vid=%04X, pid=%04X\n", __FUNCTION__, __LINE__, ifname, vid, pid);
		}
#endif /* RTK_DMP_PLATFORM */

	}
}

specific_device_id_tbl是一张特殊设备列表,rtw_ht_enable、rtw_cbw40_enable、rtw_ampdu_enable这三个标志暂时不知道是用来做什么,后续分析。

第二步:

/* Initialize dvobj_priv */
	if ((dvobj = usb_dvobj_init(pusb_intf)) == NULL) {
		RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n"));
		goto exit;
	}

初始化dvobj_priv结构体,结构体中存放了设备的接口信息、端点信息。

第三步:

/* Initialize if1 */
	if ((if1 = rtw_usb_if1_init(dvobj, pusb_intf, did)) == NULL) {
		DBG_871X("rtw_usb_if1_init Failed!\n");
		goto free_dvobj;
	}

初始化wlan0的无线网络节点:

  1. 识别芯片的型号和硬件型号并记录在wlan0的接口描述结构体中;
  2. 根据芯片型号将一些处理函数的地址赋给wlan0的描述结构体;
  3. 为结构体的intf_start和intf_stop两个成员赋值,这两个函数会在ifconfig wlan0 up和down的时候被调用;
  4. 将一些直接操作结构体的函数地址赋值到结构体中;
  5. 获取芯片的版本信息,并从芯片的eeprom中读取芯片的mac地址等信息,赋值到结构体中;
  6. 初始化一些software资源,这里需要进一步分析;
  7. 设置mac地址。
//dev_alloc_name && register_netdev
	if((status = rtw_drv_register_netdev(if1)) != _SUCCESS) {
		goto free_if1;
	}

完成wlan0的注册。

#ifdef CONFIG_HOSTAPD_MLME
	hostapd_mode_init(if1);
#endif

这张网卡是支持AP和STA两种模式的,因此这里也需要初始化AP模式下的一些资源。

probe的主体流程就结束了,这时候有关wlan0这块无线网卡的信息就记录下来了,相关的处理函数接口也都有了,网络设备节点也注册完成了,ifconfig -a就可以看到wlan0的信息了。
下一步是ifconfig wlan0 up,也就是上文中的usb_intf_start函数,了解网卡的启动过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值