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

内核中去掉SDCard驱动后WiFi打不开


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

                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的驱动程序-rk3188mmc控制器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.mmc0mmc1分别为SDMMC0_RK29,SDMMC1_RK29。

1.Mmc controler0 接的是 SDCARD; 

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

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控制器而已。

 

写在最后:

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

 

更: 

        对比RKmainline上的3.0版本的内核,RK改了太多关于drivers/mmc/core/core.c这次遇到的重点就是mmc_rescan,它是来扫描和区分MMC设备的。在RK代码中将其拆分为了emmc_rescansdmmc_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被解决。花费了89天的时间。



参考文档:

1.Linux SD/MMC/SDIO驱动分析

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值