您的位置:首页 > 移动开发 > Android开发

Android底层开发之-内核中去掉SDCard驱动后WiFi打不开

2014-10-29 21:12 519 查看
内核中去掉SDCard驱动后WiFi打不开

再描述一下问题:内核中去掉mmc0驱动配置后 使用mmc1的WiFi打不开了。

1.内核中去掉mmc0驱动配置的原因是:需要***「SD启动」的内核(sdcard运行)

根据《SD Card Boot User Guide》上介绍是需要将sdcard启动配置去掉,即mmc0控制器驱动。



2.WiFi IC使用的是AP6330,是sdio接口,使用的mmc1控制器。我觉得它们两个除了都是使用的mmc控制器,

没有其它共同点了。但是问题是现在我将mmc0控制器的驱动去掉后,使用mmc1的 WiFi不能打开了.



3.发现上述情况后,测试在正常启动模式下(从主存emmc flash启动),单独去掉mmc0控制器驱动,

也同样会出现WiFi打不开的情况。附件是Log信息。



开发的时候不以松耦合开发,后续稍微变动就会引起意想不到的附带问题。比如这次,内核中去掉了Sdcard的驱动程序-rk3188的mmc控制器0,结果WiFi不能打开了。

先把问题重现了,使能MMC0时:

shell@android:/ # busybox ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:E0:4C:36:07:E8
inet6 addr: fe80::2e0:4cff:fe36:7e8/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:90 (90.0 B)

ip6tnl0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:1452 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

p2p0 Link encap:Ethernet HWaddr 9A:3B:16:5F:26:16
inet6 addr: fe80::983b:16ff:fe5f:2616/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

wlan0 Link encap:Ethernet HWaddr 98:3B:16:5F:26:16
inet6 addr: fe80::9a3b:16ff:fe5f:2616/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:374 errors:0 dropped:374 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:159439 (155.7 KiB) TX bytes:540 (540.0 B)

shell@android:/ #
禁用MMC0时:

shell@android:/ # busybox ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:E0:4C:36:07:E8
inet6 addr: fe80::2e0:4cff:fe36:7e8/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

ip6tnl0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:1452 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

shell@android:/ #


为什么没有了wlan0?分析硬件信息:

0.mmc0和mmc1分别为SDMMC0_RK29,SDMMC1_RK29。

1.Mmc controler0 接的是 SDCARD;

2.Mmc controler1 接的SDIO接口的WiFi(AP6330)。WiFi是sdio接口的。似乎有点关联了。

3.Emmc使用的时专门的emmc控制器。



[ 8791.469587] Current WiFi chip is AP6330.
[ 8791.507772] =======================================================
[ 8791.507825] ==== Launching Wi-Fi driver! (Powered by Rockchip) ====
[ 8791.507880] =======================================================
[ 8791.507924] RKWIFI WiFi driver (Powered by Rockchip,Ver 4.53.WFD) init.
[ 8791.508106] =========== WLAN placed in POWER ON ========
[ 8791.508202] ANDROID-ERROR) wifi_set_power = 1
[ 8791.508238] rk29sdk_wifi_power: 1
[ 8791.761800] wifi turn on power
[ 8791.761829] ANDROID-ERROR) wifi_set_carddetect = 1
[ 8791.761871] rk29sdk_wifi_set_carddetect:1
[ 8791.761897] mmc0: slot status change detected(0-1)
[ 8791.958838]
[ 8791.958849] drivers/mmc/core/core.c...2010.. ===== mmc_rescan Begin....[mmc0]
[ 8792.003028] rk29_sdmmc_command_complete..2958...CMD55(arg=0x0), hoststate=1, errorTimes=1, errorStep=0x1e ! [sdio]
[ 8792.003652] rk29_sdmmc_command_complete..2958...CMD55(arg=0x0), hoststate=1, errorTimes=1, errorStep=0x1e ! [sdio]
[ 8792.004296] rk29_sdmmc_command_complete..2958...CMD55(arg=0x0), hoststate=1, errorTimes=1, errorStep=0x1e ! [sdio]
[ 8792.004805] rk29_sdmmc_command_complete..2958...CMD55(arg=0x0), hoststate=1, errorTimes=1, errorStep=0x1e ! [sdio]
[ 8792.005318] rk29_sdmmc_command_complete..2958...CMD1(arg=0x0), hoststate=1, errorTimes=1, errorStep=0x1e ! [sdio]
[ 8793.758830]


以上是错误信息。

首先第一步分析关于WiFi相关的电源驱动,基于rfkill的。硬件上是通过一个GPIO管脚连接到了WL_REG_ON,使用万用表测试使能时电压正常,基本确认WiFi电源驱动没有问题。问题出在了SDIO驱动上。



4.反验证,enable mmc0 & disable mmc1。结果:mmc1(sdio WiFi)不可用,mmc0(SDCARD)可用。

5.推测:MMC0包含了MMC1。



重新查看dmsg信息,通过反复配置mmc0/mmc1发现dmsg信息中的

[ 8791.958849] drivers/mmc/core/core.c...2010.. ===== mmc_rescan Begin....[mmc0]
无论禁用哪个mmc控制器,mmc代码中rescan到的永远都是mmc0。怀疑是平台设备中配置有误,查看了板级配置文件arch/arm/mach-rk30/devices.c后,发现没有交叉的部分。



原来,内核中的mmcNum中的Num是仅仅从识别的设备上来计数的,比如我禁用了SDMMC0_RK29,那么内核中会以“mmc0”命名硬件上的「mmc1 controler」。Naobsb真是一个对内核了解的相当深入的人。所以就目前来看关于MMC控制器在内核中的名字来说逻辑并没有错,只是难以理解。那么说明问题出在了sdmmc_rescan_try_freq以下。分析之,RK在判断SDIO/SD/MMC中做了一些改动。会配MMC控制器(内核中)名字不为“mmc0”才进行判断。否则不进行判断。



首先将这个逻辑反转,那么一切正常。如下:

diff --git a/kernel/drivers/mmc/core/core.c b/kernel/drivers/mmc/core/core.c
index cd85f9a..860ee00 100755
--- a/kernel/drivers/mmc/core/core.c
+++ b/kernel/drivers/mmc/core/core.c
@@ -1848,10 +1848,11 @@ static int sdmmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
//the process is default for rockchip SDK. noted by xbw at 2011-11-17

/* Order's important: probe SDIO, then SD, then MMC */
-
+ printk("hi kangear into, %s\n", __func__);
#if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD)
- if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) )
+ if(!strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) )
{
+ printk("hi kangear, hostname == mmc0\n");
//sdio_reset(host);//make no sense; noteed by xbw at 2011-12-14
mmc_go_idle(host);
内核中的MMC0既然不一定代表是硬件上的MMC0,那么在这里做这样的判断就是不正常的。毕竟在内核中的“mmc0”仅仅只是它第一个识别的MMC控制器而已。



写在最后:

总之,问题是解决了。和以前一样,问题刚开始的时候,我就是喜欢胡思乱想。MMC0和MMC1不能单独使用?现在可以给自己一个答案:凡事皆有因的。另外一点关于不可移除的设备如CPU上的MMC控制器我认为名字以hardcode的方式要比目前这种类似可以移除设备的命名规则要好很多。分析思路要比具体问题的解决方法重要。



更:

对比RK和mainline上的3.0版本的内核,RK改了太多关于drivers/mmc/core/core.c这次遇到的重点就是mmc_rescan,它是来扫描和区分MMC设备的。在RK代码中将其拆分为了emmc_rescan和sdmmc_rescan两个函数,sdmmc_rescan中调用的sdmmc_rescan_try_freq完全是RK添加的,在mainline中根本就不存在。这里边有一个错误的逻辑就是它会去检测控制器的名字“mmc0”,如果是则不进行判断,而这个名字其实仅仅是标注内核检测到的第一个物理MMC控制器,并不一定就是物理上的MMC0,所以以至于当仅仅使用一个MMC1控制器的时候,那么物理上的MMC1就是内核中的“MMC0”,说起来有点绕,但事实就是这样的。这里有图示:




就目前来看,我觉得把那个判断条件去掉是最好的解决方法。

而另外一个判断条件USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD,它的存在更是可笑了。不过在drivers/mmc/host/Kconfig中已经被屏蔽掉了。或许是一个历史遗留问题。使用最少修改且不影响原来功能来解决问题,我最终选择切换USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD宏的逻辑。不使用这个宏时,逻辑中并没有进行「控制器名字」的判断。



修改过后,完全不影响SDCARD/SDIO WIFI的使用,它们也不再相互干扰了。从SDCARD启动也没有任何问题了。

这个问题是在10.22号被发现的,在10.30被解决。花费了8,9天的时间。

参考文档:

1.Linux SD/MMC/SDIO驱动分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐