BCM43438 android6.0移植

编译的全部源码位于drivers/net/wireless/bcmdhd目录下。

 

初始化流程:

  1. dhd_linux.c中dhd_module_init()调用dhd_wifi_platform_register_drv()

  2. dhd_linux_plat.c中dhd_wifi_platform_register_drv()调用platform_driver_register()

	if (cfg_multichip) {   //值为FALSE不执行
		dev = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_EXT, wifi_platdev_match);
		if (dev == NULL) {
			DHD_ERROR(("bcmdhd wifi platform data device not found!!\n"));
			return -ENXIO;
		}
		err = platform_driver_register(&dhd_wifi_platform_dev_driver);
	} else {
		err = wifi_ctrlfunc_register_drv();

		/* no wifi ctrl func either, load bus directly and ignore this error */
		if (err) {
			if (err == -ENXIO) {
				/* wifi ctrl function does not exist */
				err = dhd_wifi_platform_load();
			} else {
				/* unregister driver due to initialization failure */
				wifi_ctrlfunc_unregister_drv();
			}
		}
	}

执行wifi_ctrlfunc_register_drv():

static int wifi_ctrlfunc_register_drv(void)
{
	int err = 0;
	struct device *dev1, *dev2;
	wifi_adapter_info_t *adapter;
dhd_exynos7420_platdev.c中注册了名为WIFI_PLAT_NAME的devices。
	dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match);
	dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match);

#if !defined(CONFIG_DTS)
	if (!dts_enabled) {
		if (dev1 == NULL && dev2 == NULL) {
			DHD_ERROR(("no wifi platform data, skip\n"));
			return -ENXIO;
		}
	}
#endif /* !defined(CONFIG_DTS) */

	/* multi-chip support not enabled, build one adapter information for
	 * DHD (either SDIO, USB or PCIe)
	 */
	adapter = kzalloc(sizeof(wifi_adapter_info_t), GFP_KERNEL);
	adapter->name = "DHD generic adapter";
	adapter->bus_type = -1;
	adapter->bus_num = -1;
	adapter->slot_num = -1;
	adapter->irq_num = -1;
	is_power_on = FALSE;
	wifi_plat_dev_probe_ret = 0;
	dhd_wifi_platdata = kzalloc(sizeof(bcmdhd_wifi_platdata_t), GFP_KERNEL);
	dhd_wifi_platdata->num_adapters = 1;
	dhd_wifi_platdata->adapters = adapter;

	if (dev1) {
		err = platform_driver_register(&wifi_platform_dev_driver);
		if (err) {
			DHD_ERROR(("%s: failed to register wifi ctrl func driver\n",
				__FUNCTION__));
			return err;
		}
	}

执行platform_driver_register(&wifi_platform_dev_driver),因为是注册

static struct platform_driver dhd_wifi_platform_dev_driver = {
	.probe          = bcmdhd_wifi_plat_dev_drv_probe,
	.remove         = bcmdhd_wifi_plat_dev_drv_remove,
	.driver         = {
	.name   = WIFI_PLAT_EXT,
	}
};

所以调用bcmdhd_wifi_plat_dev_drv_probe():

static int bcmdhd_wifi_plat_dev_drv_probe(struct platform_device *pdev)
{
	dhd_wifi_platdata = (bcmdhd_wifi_platdata_t *)(pdev->dev.platform_data);

	return dhd_wifi_platform_load();
}

再执行dhd_wifi_platform_load():

static int dhd_wifi_platform_load()
{
	int err = 0;
	printf("%s: Enter\n", __FUNCTION__);

	wl_android_init();

	if ((err = dhd_wifi_platform_load_usb()))
		goto end;
	else if ((err = dhd_wifi_platform_load_sdio())){
		printk("1\n");
		goto end;
		}
	else
		err = dhd_wifi_platform_load_pcie();




end:
	if (err)
		wl_android_exit();
#if !defined(MULTIPLE_SUPPLICANT)
	else
		wl_android_post_init();
#endif

	return err;
}

由于在Makefile中定义了宏BCMSDIO,所以调用dhd_wifi_platform_load_sdio()

Makefile中定义了多个宏

DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER -DSDTEST       \
	-DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE            \
	-DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DBCMDBG -DGET_OTP_MAC_ENABLE   \
	-DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY             \
	-DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DPNO_SUPPORT -DDHDTCPACK_SUPPRESS  \
	-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DRXFRAME_THREAD          \
	-DBCMSDIOH_TXGLOM_EXT                                                 \
	-DENABLE_INSMOD_NO_FW_LOAD                                            \
	-Idrivers/net/wireless/bcmdhd -Idrivers/net/wireless/bcmdhd/include

DHDCFLAGS += \
	-DBCMSDIO -DMMC_SDIO_ABORT -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR          \
	-DBDC -DPROP_TXSTATUS -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM           \
	-DCUSTOM_SDIO_F2_BLKSIZE=128

dhd_wifi_platform_load_sdio()代码:

#ifdef BCMSDIO
static int dhd_wifi_platform_load_sdio(void)
{
	int i;
	int err = 0;
	wifi_adapter_info_t *adapter;

	printk("dhd_wifi_platform_load_sdio\n");

	BCM_REFERENCE(i);
	BCM_REFERENCE(adapter);
	/* Sanity check on the module parameters
	 * - Both watchdog and DPC as tasklets are ok
	 * - If both watchdog and DPC are threads, TX must be deferred
	 */
	if (!(dhd_watchdog_prio < 0 && dhd_dpc_prio < 0) &&
		!(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx))
		return -EINVAL;

#if defined(BCMLXSDMMC)
	if (dhd_wifi_platdata == NULL) {
		DHD_ERROR(("DHD wifi platform data is required for Android build\n"));
		return -EINVAL;
	}

	sema_init(&dhd_registration_sem, 0);
	/* power up all adapters */
	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
		bool chip_up = FALSE;
		int retry = POWERUP_MAX_RETRY;
		struct semaphore dhd_chipup_sem;

		adapter = &dhd_wifi_platdata->adapters[i];


		DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));  //name= DHD generic adapter
		DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
			adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path));
		DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
			adapter->bus_type, adapter->bus_num, adapter->slot_num));

		do {
			sema_init(&dhd_chipup_sem, 0);
			err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
			if (err) {
				DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n",
					__FUNCTION__, err));
				return err;
			}
//dhd_exynos7420_platdev.c中函数espresso_wifi_power()
			err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
			if (err) {
				/* WL_REG_ON state unknown, Power off forcely */
				wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
				
				continue;
			} else {   //执行到这
				wifi_platform_bus_enumerate(adapter, TRUE);
				err = 0;
			}

			if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
				dhd_bus_unreg_sdio_notify();
				chip_up = TRUE;
				//执行到这表示获取到信号量退出while循环, 由于dhd_wifi_platdata->num_adapters等于1,也会退出for循环
				break;
			}

			DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry));
			dhd_bus_unreg_sdio_notify();
			wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
			wifi_platform_bus_enumerate(adapter, FALSE);
		} while (retry--);

		if (!chip_up) {
			DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name));
			return -ENODEV;
		}

	}

	err = dhd_bus_register();

	if (err) {
		DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
		goto fail;
	}


	/*
	 * Wait till MMC sdio_register_driver callback called and made driver attach.
	 * It's needed to make sync up exit from dhd insmod  and
	 * Kernel MMC sdio device callback registration
	 */
	err = down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
	if (err) {
		DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__));
		dhd_bus_unregister();
		goto fail;
	}

	
	return err;

fail:
	/* power down all adapters */
	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
		adapter = &dhd_wifi_platdata->adapters[i];
		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
		wifi_platform_bus_enumerate(adapter, FALSE);
	}
#else

	/* x86 bring-up PC needs no power-up operations */
	err = dhd_bus_register();

#endif 

	return err;
}
#else /* BCMSDIO */

<1>上面for循环中遍历dhd_wifi_platdata->num_adapters,apdpter是适配器的意思,它在函数wifi_ctrlfunc_register_drv()初始了一个实体:

	adapter = kzalloc(sizeof(wifi_adapter_info_t), GFP_KERNEL);
	adapter->name = "DHD generic adapter";
	adapter->bus_type = -1;
	adapter->bus_num = -1;
	adapter->slot_num = -1;
	adapter->irq_num = -1;
	is_power_on = FALSE;
	wifi_plat_dev_probe_ret = 0;
	dhd_wifi_platdata = kzalloc(sizeof(bcmdhd_wifi_platdata_t), GFP_KERNEL);
	dhd_wifi_platdata->num_adapters = 1;
	dhd_wifi_platdata->adapters = adapter;

Adapter一个重要的成员是wifi_plat_data,它在函数wifi_plat_dev_drv_probe中被赋值(还有其它成员被初始化):

static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
{
	struct resource *resource;
	wifi_adapter_info_t *adapter;
#ifdef CONFIG_DTS
	int irq, gpio;
#endif /* CONFIG_DTS */

	/* Android style wifi platform data device ("bcmdhd_wlan" or "bcm4329_wlan")
	 * is kept for backward compatibility and supports only 1 adapter
	 */
	ASSERT(dhd_wifi_platdata != NULL);
	ASSERT(dhd_wifi_platdata->num_adapters == 1);
	adapter = &dhd_wifi_platdata->adapters[0];  //由于只支持一个adapter,所以只简单取数组0的值。
	adapter->wifi_plat_data = (struct wifi_platform_data *)(pdev->dev.platform_data);

Wifi_plat_dev_drv_probe()来自:

static struct platform_driver wifi_platform_dev_driver = {
	.probe          = wifi_plat_dev_drv_probe,
	.remove         = wifi_plat_dev_drv_remove,
	.suspend        = wifi_plat_dev_drv_suspend,
	.resume         = wifi_plat_dev_drv_resume,
	.driver         = {
	.name   = WIFI_PLAT_NAME,
#ifdef CONFIG_DTS
	.of_match_table = wifi_device_dt_match,
#endif /* CONFIG_DTS */
	}
};

这个设备在上面说过的函数wifi_ctrlfunc_register_drv()中初始化,见代码:

static int wifi_ctrlfunc_register_drv(void)
{
	wifi_adapter_info_t *adapter;

#ifndef CUSTOMER_HW
	int err = 0;
	struct device *dev1, *dev2;
	dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match);
	dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match);
#endif

#if !defined(CONFIG_DTS) && !defined(CUSTOMER_HW)
	if (!dts_enabled) {
		if (dev1 == NULL && dev2 == NULL) {
			DHD_ERROR(("no wifi platform data, skip\n"));
			return -ENXIO;
		}
	}
#endif /* !defined(CONFIG_DTS) */

	/* multi-chip support not enabled, build one adapter information for
	 * DHD (either SDIO, USB or PCIe)
	 */
	adapter = kzalloc(sizeof(wifi_adapter_info_t), GFP_KERNEL);
	adapter->name = "DHD generic adapter";
	adapter->bus_type = -1;
	adapter->bus_num = -1;
	adapter->slot_num = -1;
	adapter->irq_num = -1;
	is_power_on = FALSE;
	wifi_plat_dev_probe_ret = 0;
	dhd_wifi_platdata = kzalloc(sizeof(bcmdhd_wifi_platdata_t), GFP_KERNEL);
	dhd_wifi_platdata->num_adapters = 1;
	dhd_wifi_platdata->adapters = adapter;

#ifndef CUSTOMER_HW
	if (dev1) {
		err = platform_driver_register(&wifi_platform_dev_driver);     初始化
		if (err) {
			DHD_ERROR(("%s: failed to register wifi ctrl func driver\n",
				__FUNCTION__));
			return err;
		}
	}
	if (dev2) {
		err = platform_driver_register(&wifi_platform_dev_driver_legacy);
		if (err) {
			DHD_ERROR(("%s: failed to register wifi ctrl func legacy driver\n",
				__FUNCTION__));
			return err;
		}
	}
#endif
注:Dhd_linux_platdev.c的入口函数是dhd_wifi_platform_register_drv(),它调用了wifi_ctrlfunc_register_drv()做了初始化。

wifi_plat_data的初始化在文件dhd_exynos7420_platdev.c中,它注册了platform_device。

注:整个wifi源码的核心是名称为” bcmdhd_wlan”, platform_device的源码是dhd_exynos7420_platdev.c,platform_driver的源码是dhd_linux_platdev.c。

<2> wifi_platform_set_power()函数分析:
int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec)
{
	int err = 0;
#ifdef CONFIG_DTS
	if (on) {
		err = regulator_enable(wifi_regulator);
		is_power_on = TRUE;
	}
	else {
		err = regulator_disable(wifi_regulator);
		is_power_on = FALSE;
	}
	if (err < 0)
		DHD_ERROR(("%s: regulator enable/disable failed", __FUNCTION__));
#else
	struct wifi_platform_data *plat_data;

	if (!adapter || !adapter->wifi_plat_data)
		return -EINVAL;
	plat_data = adapter->wifi_plat_data;   //在上面<1>分析了wifi_plat_data,它其实是pdev->dev.platform_data, 代码在dhd_exynos7420_platdev.c中。

	DHD_ERROR(("%s = %d\n", __FUNCTION__, on));
	if (plat_data->set_power) {
#ifdef ENABLE_4335BT_WAR
		if (on) {
			printk("WiFi: trying to acquire BT lock\n");
			if (bcm_bt_lock(lock_cookie_wifi) != 0)
				printk("** WiFi: timeout in acquiring bt lock**\n");
			printk("%s: btlock acquired\n", __FUNCTION__);
		}
		else {
			/* For a exceptional case, release btlock */
			bcm_bt_unlock(lock_cookie_wifi);
		}
#endif /* ENABLE_4335BT_WAR */

		err = plat_data->set_power(on);
	}

	if (msec && !err)
		OSL_SLEEP(msec);

	if (on && !err)
		is_power_on = TRUE;
	else
		is_power_on = FALSE;

#endif /* CONFIG_DTS */

	return err;
}

<3>wifi_platform_bus_enumerate()函数分析:

//下面两个变量是程序员调试用的代码。
extern void (*wifi_status_cb)(struct platform_device *, int state); //定义在mmc/host/dw_mmc.c中。
extern struct platform_device *wifi_mmc_dev;  //
int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present)
{
	int err = 0;
	struct wifi_platform_data *plat_data;

	if (!adapter || !adapter->wifi_plat_data)
		return -EINVAL;
	plat_data = adapter->wifi_plat_data;

	DHD_ERROR(("%s device present %d\n", __FUNCTION__, device_present));
	if (plat_data->set_carddetect) {    //调用dhd_exynos7420_platdev.c中的set_carddetect()
		err = plat_data->set_carddetect(device_present);
	}
	return err;

}

<4>信号量dhd_chipup_sem, 相关代码:

static int dhd_wifi_platform_load_sdio(void)
{
…略

		do {
			sema_init(&dhd_chipup_sem, 0);     //初始化
			err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem);  //注册到sdio的驱动中
			if (err) {
				DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n",
					__FUNCTION__, err));
				return err;
			}
			err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
			if (err) {
				/* WL_REG_ON state unknown, Power off forcely */
				wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
				printk("continue.\n");
				continue;
			} else {
				wifi_platform_bus_enumerate(adapter, TRUE);
				printk("wifi_platform_bus_enumerate ok.\n");
				err = 0;
			}

          //获取到信号量表示sdio初始化成功,过程见分析。
			if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
				dhd_bus_unreg_sdio_notify();
				chip_up = TRUE;
				printk("down_timeout.\n");
				break;
			}

			DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry));
			dhd_bus_unreg_sdio_notify();
			wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
			wifi_platform_bus_enumerate(adapter, FALSE);
		} while (retry--);

		if (!chip_up) {
			DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name));
			return -ENODEV;
		}

	}

dhd_bus_reg_sdio_notify(&dhd_chipup_sem)的代码:

Dhd_sdio.c中:
int dhd_bus_reg_sdio_notify(void* semaphore)
{
	return bcmsdh_reg_sdio_notify(semaphore);
}
Bcmsdh_linux.c
int bcmsdh_reg_sdio_notify(void* semaphore)
{
	return sdio_func_reg_notify(semaphore);
}
Bcmsdh_emmc_linux.c
int sdio_func_reg_notify(void* semaphore)
{
	notify_semaphore = semaphore;
	return sdio_register_driver(&dummy_sdmmc_driver);
}

Dummy_sdmmc_driver的相关代码如下:

static int dummy_probe(struct sdio_func *func,
                              const struct sdio_device_id *id)
{
	if (func && (func->num != 2)) {
		return 0;
	}

	if (notify_semaphore)
		up(notify_semaphore);           //这里会释放信号量,关键代码在上面的func->num!=2
	return 0;
}

static void dummy_remove(struct sdio_func *func)
{
}

static struct sdio_driver dummy_sdmmc_driver = {
	.probe		= dummy_probe,
	.remove		= dummy_remove,
	.name		= "dummy_sdmmc",
	.id_table	= bcmsdh_sdmmc_ids,
	};

<4> dhd_bus_register()分析:

Dhd_sdio.c
static bcmsdh_driver_t dhd_sdio = {
	dhdsdio_probe,
	dhdsdio_disconnect,
	dhdsdio_suspend,
	dhdsdio_resume
};

int
dhd_bus_register(void)
{
	DHD_TRACE(("%s: Enter\n", __FUNCTION__));

	return bcmsdh_register(&dhd_sdio);
}
Bcmsdh_linux.c
int
bcmsdh_register(bcmsdh_driver_t *driver)
{
	int error = 0;

	drvinfo = *driver;
	SDLX_MSG(("%s: register client driver\n", __FUNCTION__));
	error = bcmsdh_register_client_driver();
	if (error)
		SDLX_MSG(("%s: failed %d\n", __FUNCTION__, error));

	return error;
}
Bcmsdh_emmc_linux.c
int bcmsdh_register_client_driver(void)
{
#ifdef GLOBAL_SDMMC_INSTANCE
	gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL);
	if (!gInstance)
		return -ENOMEM;
#endif

	return sdio_register_driver(&bcmsdh_sdmmc_driver);
}

static struct sdio_driver bcmsdh_sdmmc_driver = {
	.probe		= bcmsdh_sdmmc_probe,
	.remove		= bcmsdh_sdmmc_remove,
	.name		= "bcmsdh_sdmmc",
	.id_table	= bcmsdh_sdmmc_ids,
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
	.drv = {
	.pm	= &bcmsdh_sdmmc_pm_ops,
	},
#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
};

然后执行它的bcmsdh_sdmmc_probe():
static int bcmsdh_sdmmc_probe(struct sdio_func *func,
                              const struct sdio_device_id *id)
{
	int ret = 0;

	if (func == NULL)
		return -EINVAL;

	sd_err(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__));
	sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
	sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
	sd_info(("sdio_device: 0x%04x\n", func->device));
	sd_info(("Function#: 0x%04x\n", func->num));

#ifdef GLOBAL_SDMMC_INSTANCE
	gInstance->func[func->num] = func;
#endif

	/* 4318 doesn't have function 2 */
	if ((func->num == 2) || (func->num == 1 && func->device == 0x4))
		ret = sdioh_probe(func);

	return ret;
}

发现LOG的最后是:

[ 15.015549] [5: swapper/0: 1] [c5] [WLAN] Wifi Power Off.

找到打印这个的是在函数wifi_platform_set_power,于是在这个函数中打印这句的上面加上dump_stace(),打印的信息如下:

[   14.508148]  [6:      swapper/0:    1] [c6] sdioh_set_mode: set txglom_mode to multi-desc
[   14.516457]  [6:      swapper/0:    1] [c6] dhd_bus_devreset:  WLAN OFF DONE
[   14.523752]  [6:      swapper/0:    1] [c6] wifi_platform_set_power = 0
[   14.530504]  [6:      swapper/0:    1] [c6] CPU: 6 PID: 1 Comm: swapper/0 Not tainted 3.10.61-svn57 #3
[   14.539939]  [6:      swapper/0:    1] [c6] Call trace:
[   14.545242]  [6:      swapper/0:    1] [c6] [] dump_backtrace+0x0/0x110
[   14.553545]  [6:      swapper/0:    1] [c6] [] show_stack+0x10/0x1c
[   14.561507]  [6:      swapper/0:    1] [c6] [] dump_stack+0x1c/0x28
[   14.569415]  [6:      swapper/0:    1] [c6] [] wifi_platform_set_power+0x58/0xd0
[   14.578505]  [6:      swapper/0:    1] [c6] [] dhd_register_if+0x24c/0x274
[   14.587081]  [6:      swapper/0:    1] [c6] [] dhdsdio_probe+0x560/0x5b4
[   14.595417]  [6:      swapper/0:    1] [c6] [] bcmsdh_probe+0x110/0x188
[   14.603719]  [6:      swapper/0:    1] [c6] [] bcmsdh_sdmmc_probe+0x1e4/0x25c
[   14.612557]  [6:      swapper/0:    1] [c6] [] sdio_bus_probe+0x94/0x110
[   14.620955]  [6:      swapper/0:    1] [c6] [] driver_probe_device+0xd4/0x244
[   14.629728]  [6:      swapper/0:    1] [c6] [] __driver_attach+0x60/0x90
[   14.638065]  [6:      swapper/0:    1] [c6] [] bus_for_each_dev+0x74/0x94
[   14.646545]  [6:      swapper/0:    1] [c6] [] driver_attach+0x1c/0x28
[   14.654760]  [6:      swapper/0:    1] [c6] [] bus_add_driver+0xec/0x208
[   14.663091]  [6:      swapper/0:    1] [c6] [] driver_register+0x94/0x110
[   14.671580]  [6:      swapper/0:    1] [c6] [] sdio_register_driver+0x20/0x2c
[   14.680412]  [6:      swapper/0:    1] [c6] [] bcmsdh_register_client_driver+0x14/0x20
[   14.690026]  [6:      swapper/0:    1] [c6] [] bcmsdh_register+0x40/0x70
[   14.698430]  [6:      swapper/0:    1] [c6] [] dhd_bus_register+0x38/0x44
[   14.706854]  [6:      swapper/0:    1] [c6] [] dhd_wifi_platform_load+0x28c/0x3b8
[   14.716033]  [6:      swapper/0:    1] [c6] [] wifi_plat_dev_drv_probe+0x6c/0x84
[   14.725129]  [6:      swapper/0:    1] [c6] [] platform_drv_probe+0x14/0x20
[   14.733777]  [6:      swapper/0:    1] [c6] [] driver_probe_device+0xd4/0x244
[   14.742542]  [6:      swapper/0:    1] [c6] [] __driver_attach+0x60/0x90
[   14.750943]  [6:      swapper/0:    1] [c6] [] bus_for_each_dev+0x74/0x94
[   14.759429]  [6:      swapper/0:    1] [c6] [] driver_attach+0x1c/0x28
[   14.767656]  [6:      swapper/0:    1] [c6] [] bus_add_driver+0xec/0x208
[   14.775994]  [6:      swapper/0:    1] [c6] [] driver_register+0x94/0x110
[   14.784472]  [6:      swapper/0:    1] [c6] [] platform_driver_register+0x58/0x64
[   14.793655]  [6:      swapper/0:    1] [c6] [] dhd_wifi_platform_register_drv+0x158/0x1fc
[   14.803529]  [6:      swapper/0:    1] [c6] [] dhd_module_init+0xa4/0x178
[   14.811958]  [6:      swapper/0:    1] [c6] [] do_one_initcall+0x7c/0x118
[   14.820439]  [6:      swapper/0:    1] [c6] [] kernel_init_freeable+0x148/0x1ec
[   14.829442]  [6:      swapper/0:    1] [c6] [] kernel_init+0xc/0xd4
[   14.837404]  [6:      swapper/0:    1] [c6] [WLAN] Wifi Power Off.

在此文件的最前加上“#define DHD_DEBUG 1”,打印出此dhd_register_if()的调试信息如下:

[   14.800308]  [7:      swapper/0:    1] [c7] dhd_register_if: ifidx 0
[   14.806819]  [7:      swapper/0:    1] [c7] Dongle Host Driver, version 1.201.59.7 (r506368)
[   14.806819]  [7:      swapper/0:    1] Compiled in drivers/net/wireless/bcmdhd on Mar  9 2017 at 12:11:53
[   14.825308]  [7:      swapper/0:    1] [c7] dhd_get_stats: Enter
[   14.831398]  [7:      swapper/0:    1] [c7] Register interface [wlan0]  MAC: ac:83:f3:41:c9:a2
[   14.831398]  [7:      swapper/0:    1] 
[   14.843972]  [7:      swapper/0:    1] [c7] dhd_prot_ioctl : bus is down. we have nothing to do
[   14.852800]  [7:      swapper/0:    1] [c7] dhd_net_bus_devreset: wl down failed
[   14.860326]  [7:      swapper/0:    1] [c7] dhd_os_wd_timer: Enter
[   14.866579]  [7:      swapper/0:    1] [c7] dhd_txflowcontrol: Enter
[   14.873051]  [7:      swapper/0:    1] [c7] dhd_bus_stop: Enter
[   14.879146]  [7:      swapper/0:    1] [c7] bcmsdh_oob_intr_unregister: Enter
[   14.886432]  [7:      swapper/0:    1] [c7] bcmsdh_oob_intr_unregister: irq is not registered
[   14.895076]  [7:      swapper/0:    1] [c7] dhdsdio_release_dongle: Enter bus->dhd ffffffc09cb48000 bus->dhd->dongle_reset 0 
[   14.906521]  [7:      swapper/0:    1] [c7] dhdsdio_clkctl: Enter
[   14.912672]  [7:      swapper/0:    1] [c7] dhdsdio_sdclk: Enter
[   14.918809]  [7:      swapper/0:    1] [c7] dhd_os_wd_timer: Enter
[   14.925046]  [7:      swapper/0:    1] [c7] dhdsdio_clkctl: 1 -> 0
[   14.931359]  [7:      swapper/0:    1] [c7] dhdsdio_release_dongle: Disconnected
[   14.938827]  [7:      swapper/0:    1] [c7] dhd_txglom_enable: Enter
[   14.945311]  [7:      swapper/0:    1] [c7] dhd_txglom_enable: enable 0
[   14.952043]  [7:      swapper/0:    1] [c7] dhd_conf_set_txglom_params: swtxglom=0, txglom_ext=0
[   14.960894]  [7:      swapper/0:    1] [c7] dhd_conf_set_txglom_params: txglom_bucket_size=0
[   14.969461]  [7:      swapper/0:    1] [c7] dhd_conf_set_txglom_params: txglomsize=0, deferred_tx_len=0, bus_txglom=-1
[   14.980289]  [7:      swapper/0:    1] [c7] dhd_conf_set_txglom_params: tx_in_rx=1, tx_max_offset=0
[   14.989463]  [7:      swapper/0:    1] [c7] sdioh_set_mode: set txglom_mode to multi-desc
[   14.997773]  [7:      swapper/0:    1] [c7] dhd_bus_devreset:  WLAN OFF DONE
[   15.013292]  [7:      swapper/0:    1] [c7] wifi_platform_set_power = 0
int
dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
{
略

#if 1 && (defined(BCMPCIE) || (defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= \
	KERNEL_VERSION(2, 6, 27))))
	if (ifidx == 0) {
#ifdef BCMLXSDMMC
		up(&dhd_registration_sem);
#endif
		if (!dhd_download_fw_on_driverload) {    进入了这说明失败了
			dhd_net_bus_devreset(net, TRUE);  
#ifdef BCMLXSDMMC
			dhd_net_bus_suspend(net);
#endif /* BCMLXSDMMC */

			wifi_platform_set_power(dhdp->info->adapter, FALSE, WIFI_TURNOFF_DELAY);
		}
	}
#endif /* OEM_ANDROID && (BCMPCIE || (BCMLXSDMMC && KERNEL_VERSION >= 2.6.27)) */
	return 0;

dhd_download_fw_on_driverload从字面上可以看出是驱动固件是否加载的意思。

查找了了一下这个关键字,仅有两处有赋值:

dhd_linux.c:496:uint dhd_download_fw_on_driverload = TRUE;        //此处为初始化
wl_android.c:2867:	dhd_download_fw_on_driverload = FALSE;
找到wl_android.c中的相关代码:
int wl_android_init(void)
{
	int ret = 0;

#ifdef ENABLE_INSMOD_NO_FW_LOAD
	dhd_download_fw_on_driverload = FALSE;
#endif /* ENABLE_INSMOD_NO_FW_LOAD */

关键看宏ENABLE_INSMOD_NO_FW_LOAD是否定义,在Makefile中找到定义了此宏,难道AP6212不需要加载固件吗,但在defconfig中发现做了配置:

CONFIG_BCMDHD_FW_PATH="system/vendor/firmware/fw_bcmdhd.bin"

CONFIG_BCMDHD_NVRAM_PATH="system/etc/wifi/bcmdhd.cal"

在android中复制了相应芯片firmware并重新命名为以上文件。(参考下面的anroid部分)

在shell中运行netcfg,打印出:

1|root@avl7420:/ # netcfg                                                      
sit0     DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00
lo       UP                                   127.0.0.1/8   0x00000049 00:00:00:00:00:00
wlan0    DOWN                                   0.0.0.0/0   0x00001002 ac:83:f3:41:c9:a2
ip6tnl0  DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00

再执行netcfg –iwlan0 up,打印:

action 'up' failed (Operation not permitted)

此时串口会打印下载固件的信息,也会有错误信息。(此时固件是不正确的)

 

hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie下有netcfg, wl等文件。以下命令可用于调试:

netcfg, netcfg wlan0 up, wl scan, wl scanresults。

 

Kernel的改动:

Drivers/net/wireless/bcmdhd/dhd_config.h中注释掉“#define FW_PATH_AUTO_SELECT 1”。

Drivers/net/wireless/bcmdhd/Makefile中删除“ -DENABLE_INSMOD_NO_FW_LOAD \”。

Wifi log

函数dhd_wifi_platform_load_sdio()的log:

[   12.380428]  [6:      swapper/0:    1] [c6] ###############################dhd_wifi_platform_load.
[   12.389526]  [6:      swapper/0:    1] [c6] dhd_wifi_platform_load_sdio   //调用此函数
[   12.396274]  [6:      swapper/0:    1] [c6] Power-up adapter 'DHD generic adapter'
[   12.403912]  [6:      swapper/0:    1] [c6]  - irq 7 [flags 4], firmware: (null), nvram: (null)
[   12.412740]  [6:      swapper/0:    1] [c6]  - bus type -1, bus num -1, slot num -1
[   12.412740]  [6:      swapper/0:    1] 
[   12.424379]  [6:      swapper/0:    1] [c6] wifi_platform_set_power = 1   //调用wifi_platform_set_power
[   12.431130]  [6:      swapper/0:    1] [c6] [WLAN] Wifi Power On.  //dhd_exynos7420_platdev.c中函数espresso_wifi_power()
[   13.665543]  [4:      swapper/0:    1] [c4] wifi_platform_bus_enumerate device present 1 //调用wifi_platform_bus_enumerate device()

//函数wifi_platform_bus_enumerate()打印
[   13.673764]  [4:      swapper/0:    1] [c4] espresso_wifi_set_carddetect: 1 

[   13.680860]  [4:      swapper/0:    1] [c4] shaohua enter set_detect_flag, set detect flag = 1 
//退出了函数espresso_wifi_set_carddetect()
[   13.885601]  [7:  kworker/u16:2: 1063] [c7] shaohua enter check_detect_flag, check detect flag = 1 
[   13.894718]  [7:  kworker/u16:2: 1063] [c7] shaohua enable detect, continue
[   13.901822]  [7:  kworker/u16:2: 1063] [c7] shaohua enter clear_detect_flag, clear detect flag = 0 
[   13.940077]  [7:  kworker/u16:2: 1063] [c7] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
[   13.950065]  [7:  kworker/u16:2: 1063] [c7] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
[   13.960195]  [7:  kworker/u16:2: 1063] [c7] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
[   13.971638]  [7:  kworker/u16:2: 1063] [c7] mmc1: queuing unknown CIS tuple 0x80 (7 bytes)
[   13.983595]  [7:  kworker/u16:2: 1063] [c7] mmc1: queuing unknown CIS tuple 0x81 (9 bytes)
[   14.077787]  [7:  kworker/u16:2: 1063] [c7] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 400000Hz, actual 396825HZ div = 63)
[   14.090207]  [7:  kworker/u16:2: 1063] [c7] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 50000000Hz, actual 50000000HZ div = 0)
[   14.106961]  [7:  kworker/u16:2: 1063] [c7] mmc1: new high speed SDIO card at address 0001
[   14.131876]  [4:      swapper/0:    1] [c4] dhd_bus_register: Enter  //执行函数dhd_bus_register

//下面这行的打印在Bcmsdh_linux.c
[   14.138285]  [4:      swapper/0:    1] [c4] bcmsdh_register: register client driver
[   14.146399]  [4:      swapper/0:    1] [c4] bcmsdh_sdmmc: bcmsdh_sdmmc_probe Enter
[   14.154336]  [4:      swapper/0:    1] [c4] bcmsdh_sdmmc: bcmsdh_sdmmc_probe Enter
[   14.162059]  [4:      swapper/0:    1] [c4] bus num (host idx)=1, slot num (rca)=1
[   14.169766]  [4:      swapper/0:    1] [c4] found adapter info 'DHD generic adapter'
[   14.177580]  [4:      swapper/0:    1] [c4] found adapter info 'DHD generic adapter'
[   14.185642]  [4:      swapper/0:    1] [c4] sdioh_attach: set sd_f2_blocksize 128
[   14.194624]  [4:      swapper/0:    1] [c4] dhdsdio_probe: Enter
[   14.200734]  [4:      swapper/0:    1] [c4] dhdsdio_probe: venid 0x14e4 devid 0x0000
[   14.208615]  [4:      swapper/0:    1] [c4] dhdsdio_probe: allow device id 0, will check chip internals
[   14.218987]  [4:      swapper/0:    1] [c4] F1 signature read @0x18000000=0x1541a9a6
[   14.244207]  [4:      swapper/0:    1] [c4] Function 0 CIS:
[   14.249948]  [4:      swapper/0:    1] [c4]     20 04 d0 02 a6 a9 21 02 0c 00 22 04 00 20 00 58 
[   14.259979]  [4:      swapper/0:    1] [c4]     80 02 00 0b 80 03 02 01 11 80 03 1b 26 07 80 07 
[   14.270019]  [4:      swapper/0:    1] [c4]     19 ac 83 f3 41 c9 a2 81 09 19 0e ee c0 be 86 ac 
[   14.280110]  [4:      swapper/0:    1] [c4]     48 a7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.290211]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.300312]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.310343]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.320374]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.330474]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.340575]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.350667]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.360698]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.370799]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.380882]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.390983]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.401083]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.411123]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.421215]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.431316]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.441408]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.451448]  [4:      swapper/0:    1] [c4]     ff 
[   14.473756]  [4:      swapper/0:    1] [c4] Function 1 CIS:
[   14.479416]  [4:      swapper/0:    1] [c4]     20 04 d0 02 a6 a9 21 02 0c 00 22 2a 01 00 00 00 
[   14.489516]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 40 00 00 ff ff 80 00 00 
[   14.499616]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[   14.509717]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 ff 
[   14.533842]  [4:      swapper/0:    1] [c4] Function 2 CIS:
[   14.539561]  [4:      swapper/0:    1] [c4]     20 04 d0 02 a6 a9 21 02 0c 00 22 2a 01 01 00 00 
[   14.549599]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 00 02 00 ff ff 80 00 00 
[   14.559639]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 00 00 c8 00 00 00 00 00 00 00 
[   14.569739]  [4:      swapper/0:    1] [c4]     00 00 00 00 00 00 ff 
[   14.581734]  [4:      swapper/0:    1] [c4] F1 signature OK, socitype:0x1 chip:0xa9a6 rev:0x1 pkg:0x4
[   14.592748]  [4:      swapper/0:    1] [c4] DHD: dongle ram size is set to 524288(orig 524288) at 0x0
[   14.602252]  [4:      swapper/0:    1] [c4] dhd_attach: Enter
[   14.608151]  [4:      swapper/0:    1] [c4] found adapter info 'DHD generic adapter'
[   14.616049]  [4:      swapper/0:    1] [c4] dhd_conf_set_chiprev: chip=0xa9a6, chiprev=1
[   14.624234]  [4:      swapper/0:    1] [c4] dhd_conf_set_conf_path_by_nv_path: config_path=system/etc/wifi/config.txt
[   14.635353]  [5:      swapper/0:    1] [c5] wl_create_event_handler(): thread:wl_event_handler:53c started
[   14.635369]  [4:wl_event_handle: 1340] [c4] tsk Enter, tsk = 0xffffffc09c5819a0
[   14.652806]  [5:      swapper/0:    1] [c5] dhd_attach(): thread:dhd_watchdog_thread:53f started
[   14.661948]  [5:      swapper/0:    1] [c5] dhd_attach(): thread:dhd_dpc:540 started
[   14.669994]  [5:      swapper/0:    1] [c5] dhd_attach(): thread:dhd_rxf:541 started
[   14.677883]  [5:      swapper/0:    1] [c5] dhd_deferred_work_init: work queue initialized 
[   14.686372] I[5:      swapper/0:    1] [c5] dhd_tcpack_suppress_set: 0 -> 2
[   14.693396] I[5:      swapper/0:    1] [c5] _tdata_psh_info_pool_init 257: Enter
[   14.700920]  [5:      swapper/0:    1] [c5] dhdsdio_probe_malloc: Enter
[   14.707615]  [5:      swapper/0:    1] [c5] dhdsdio_probe_init: Enter
[   14.714563]  [5:      swapper/0:    1] [c5] dhdsdio_probe_init: Initial value for sd_divisor is 2
[   14.723589]  [5:      swapper/0:    1] [c5] dhdsdio_probe_init: Initial value for sd_mode is 2
[   14.732336]  [5:      swapper/0:    1] [c5] dhdsdio_probe_init: Initial value for sd_blocksize is 128
[   14.742785]  [5:      swapper/0:    1] [c5] Apply overflow WAR: 0x10 0x20 0xa0
[   14.750195]  [5:      swapper/0:    1] [c5] dhdsdio_probe_init: bus module (through bcmsdh API) does not support chaining
[   14.761281]  [5:      swapper/0:    1] [c5] dhdsdio_probe: disable SDIO interrupts (not interested yet)
[   14.771200]  [5:      swapper/0:    1] [c5] dhdsdio_probe: registered SDIO interrupt function ok
[   14.780166]  [5:      swapper/0:    1] [c5] dhdsdio_probe: completed!!
[   14.804081]  [5:      swapper/0:    1] [c5] dhd_register_if: ifidx 0
[   14.810592]  [5:      swapper/0:    1] [c5] Dongle Host Driver, version 1.201.59.7 (r506368)
[   14.810592]  [5:      swapper/0:    1] Compiled in drivers/net/wireless/bcmdhd on Mar  9 2017 at 08:32:18
[   14.829008]  [5:      swapper/0:    1] [c5] dhd_get_stats: Enter
[   14.835158]  [5:      swapper/0:    1] [c5] Register interface [wlan0]  MAC: ac:83:f3:41:c9:a2
[   14.835158]  [5:      swapper/0:    1] 
[   14.847733]  [5:      swapper/0:    1] [c5] dhd_prot_ioctl : bus is down. we have nothing to do
[   14.856569]  [5:      swapper/0:    1] [c5] dhd_net_bus_devreset: wl down failed
[   14.864022]  [5:      swapper/0:    1] [c5] dhd_os_wd_timer: Enter
[   14.870333]  [5:      swapper/0:    1] [c5] dhd_txflowcontrol: Enter
[   14.876823]  [5:      swapper/0:    1] [c5] dhd_bus_stop: Enter
[   14.882903]  [5:      swapper/0:    1] [c5] bcmsdh_oob_intr_unregister: Enter
[   14.890171]  [5:      swapper/0:    1] [c5] bcmsdh_oob_intr_unregister: irq is not registered
[   14.898836]  [5:      swapper/0:    1] [c5] dhdsdio_release_dongle: Enter bus->dhd ffffffc09c508000 bus->dhd->dongle_reset 0 
[   14.910271]  [5:      swapper/0:    1] [c5] dhdsdio_clkctl: Enter
[   14.916434]  [5:      swapper/0:    1] [c5] dhdsdio_sdclk: Enter
[   14.922560]  [5:      swapper/0:    1] [c5] dhd_os_wd_timer: Enter
[   14.928812]  [5:      swapper/0:    1] [c5] dhdsdio_clkctl: 1 -> 0
[   14.935117]  [5:      swapper/0:    1] [c5] dhdsdio_release_dongle: Disconnected
[   14.942578]  [5:      swapper/0:    1] [c5] dhd_txglom_enable: Enter
[   14.949063]  [5:      swapper/0:    1] [c5] dhd_txglom_enable: enable 0
[   14.955743]  [5:      swapper/0:    1] [c5] dhd_conf_set_txglom_params: swtxglom=0, txglom_ext=0
[   14.964653]  [5:      swapper/0:    1] [c5] dhd_conf_set_txglom_params: txglom_bucket_size=0
[   14.973222]  [5:      swapper/0:    1] [c5] dhd_conf_set_txglom_params: txglomsize=0, deferred_tx_len=0, bus_txglom=-1
[   14.984049]  [5:      swapper/0:    1] [c5] dhd_conf_set_txglom_params: tx_in_rx=1, tx_max_offset=0
[   14.993224]  [5:      swapper/0:    1] [c5] sdioh_set_mode: set txglom_mode to multi-desc
[   15.001473]  [5:      swapper/0:    1] [c5] dhd_bus_devreset:  WLAN OFF DONE
[   15.008781]  [5:      swapper/0:    1] [c5] wifi_platform_set_power = 0
[   15.015549]  [5:      swapper/0:    1] [c5] [WLAN] Wifi Power Off.
[   15.525586]  [5:      swapper/0:    1] [c5] 
[   15.534774]  [5:      swapper/0:    1] [c5] ###############################dhd_wifi_platform_load ok.
[   15.544151]  [5:      swapper/0:    1] [c5] dhd_module_init: Exit err=0

编译

首先看devices目录下BoardConfig.mk:

# Wifi related defines
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
WPA_SUPPLICANT_VERSION      := VER_0_8_X
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_bcmdhd
BOARD_HOSTAPD_DRIVER        := NL80211
BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_bcmdhd
BOARD_WLAN_DEVICE           := bcmdhd
WIFI_DRIVER_FW_PATH_PARAM   := "/sys/module/bcmdhd/parameters/firmware_path"
WIFI_DRIVER_FW_PATH_STA     := "/vendor/firmware/fw_bcmdhd.bin"
WIFI_DRIVER_FW_PATH_AP      := "/vendor/firmware/fw_bcmdhd_apsta.bin"

hardware/Broadcom/wlan/Android.mk:

ifeq ($(BOARD_WLAN_DEVICE),bcmdhd)   //由于在BoardConfig.mk中定义了这个宏等于bcmdhd
    include $(call all-subdir-makefiles)
endif

进入子目录

<1> config/Android.mk

LOCAL_PATH := $(call my-dir)

########################

include $(CLEAR_VARS)
LOCAL_MODULE := dhcpcd.conf
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/dhcpcd
LOCAL_SRC_FILES := android_dhcpcd.conf
include $(BUILD_PREBUILT)

#########################
BoardConfig.mk定义了宏WPA_SUPPLICANT_VERSION=VER_0_8_X

WIFI_DRIVER_SOCKET_IFACE := wlan0
ifeq ($(strip $(WPA_SUPPLICANT_VERSION)),VER_0_8_X)
  include external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_conf.mk
else
ifeq ($(strip $(WPA_SUPPLICANT_VERSION)),VER_0_6_X)
  include external/wpa_supplicant_6/wpa_supplicant/wpa_supplicant_conf.mk
else
  include external/wpa_supplicant/wpa_supplicant_conf.mk
endif
endif
#######################

它做了两件事:<1>复制当前目录下的dhcpcd.conf到/system/etc/dhcpcd/目录下;<2>包含对应版本的wpa_supplicant_conf.mk。

<2>dhdutil/Android.mk编译dhdutil

<3>wifi_hal/Android.mk编译libwifi-hal-bcm

<4> wpa_supplicant_8_lib/Android.mk

LOCAL_PATH := $(call my-dir)

BoardConfig.mk定义了宏WPA_SUPPLICANT_VERSION=VER_0_8_X
ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)

BoardConfig.mk定义了宏BOARD_WPA_SUPPLICANT_DRIVER=NL80211,这个决定了wpa_supplicant的-D参数为nl80211
ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
  CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
endif

WPA_SUPPL_DIR = external/wpa_supplicant_8
WPA_SRC_FILE :=

include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config

WPA_SUPPL_DIR_INCLUDE = $(WPA_SUPPL_DIR)/src \
	$(WPA_SUPPL_DIR)/src/common \
	$(WPA_SUPPL_DIR)/src/drivers \
	$(WPA_SUPPL_DIR)/src/l2_packet \
	$(WPA_SUPPL_DIR)/src/utils \
	$(WPA_SUPPL_DIR)/src/wps \
	$(WPA_SUPPL_DIR)/wpa_supplicant

ifdef CONFIG_DRIVER_NL80211                 有效
WPA_SUPPL_DIR_INCLUDE += external/libnl/include
WPA_SRC_FILE += driver_cmd_nl80211.c
endif

ifdef CONFIG_DRIVER_WEXT
WPA_SRC_FILE += driver_cmd_wext.c
endif

ifeq ($(TARGET_ARCH),arm)
# To force sizeof(enum) = 4
L_CFLAGS += -mabi=aapcs-linux
endif

ifdef CONFIG_ANDROID_LOG
L_CFLAGS += -DCONFIG_ANDROID_LOG
endif

ifdef CONFIG_P2P
L_CFLAGS += -DCONFIG_P2P
endif

ifeq ($(TARGET_USES_64_BIT_BCMDHD),true)
L_CFLAGS += -DBCMDHD_64_BIT_IPC
endif

########################

include $(CLEAR_VARS)
LOCAL_MODULE := lib_driver_cmd_bcmdhd
LOCAL_SHARED_LIBRARIES := libc libcutils
LOCAL_CFLAGS := $(L_CFLAGS)
LOCAL_SRC_FILES := $(WPA_SRC_FILE)
LOCAL_C_INCLUDES := $(WPA_SUPPL_DIR_INCLUDE)
include $(BUILD_STATIC_LIBRARY)

########################

endif

<5>firmware目录下是broadcom不同类型的wlan芯片的固件,但此目录下没有Android.mk,所以不会执行。但在device/Samsung/avl7420/device.mk中:

BOARD_HAVE_WIFIBT_FIRMWARE := true
# wifi/bt chipset name is bcm43241 or bcm43455pcie
BOARD_WIFIBT_CHIPSET := bcm43455pcie


#wifi firmware
ifeq ($(BOARD_HAVE_WIFIBT_FIRMWARE),true)
ifeq ($(BOARD_WIFIBT_CHIPSET),bcm43241)
$(call inherit-product-if-exists, hardware/broadcom/wlan/bcmdhd/firmware/bcm43241/device-bcm.mk)
endif
ifeq ($(BOARD_WIFIBT_CHIPSET),bcm43455pcie)
$(call inherit-product-if-exists, hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/device-bcm.mk)
endif
endif

此时,它会包含firmware目录下的bcm43455pcie/device-bcm.mk:

########################
-include hardware/broadcom/wlan/bcmdhd/config/config-bcm.mk 复制此目录下的两个文件
BCM_FW_SRC_FILE_STA := fw_bcmdhd.bin
BCM_FW_SRC_FILE_AP  := fw_bcmdhd_apsta.bin
BCM_NVRAM_SRC_FILE := bcmdhd.cal
BCM_WL_SRC_FILE := wl

PRODUCT_COPY_FILES += \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/iperf:system/bin/iperf \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/netcfg:system/bin/netcfg \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/wifi_rf_script:system/bin/wifi_rf_script \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/fw_bcmdhd_mfgtest.bin:system/vendor/firmware/fw_bcmdhd_mfgtest.bin \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/$(BCM_FW_SRC_FILE_STA):system/vendor/firmware/fw_bcmdhd.bin \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/$(BCM_FW_SRC_FILE_AP):system/vendor/firmware/fw_bcmdhd_apsta.bin \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/$(BCM_NVRAM_SRC_FILE):system/etc/wifi/bcmdhd.cal \
    hardware/broadcom/wlan/bcmdhd/firmware/bcm43455pcie/$(BCM_WL_SRC_FILE):system/bin/wl
########################

做的工作有:

  1. 复制bcmdhd/config目录下的两个文件;

  2. 复制另外的文件并重新命名。

 

你可能感兴趣的:([驱动开发])