Android6.0 Qualcomm Atheros QCA6174A WiFi Model Support

本文主要记录给Baytrail 平台 Android6.0系统移植EWM-W163M201E WiFi的过程和中间遇到的问题。Android版本是6.0,Kernel版本是3.14.64,CPU是 Bay Trail平台Vallyview-D/M系列,WiFi是研华的EWM-W163M201E模块。

  • 驱动下载

WiFi驱动一般都是wifi 厂商提供的,一般情况下厂商会提供wifi驱动,wifi firmware和wifi potting guide等资料给软件工程师 。本次使用的EWM-W163M201E wifi模块的Main Chipset是 QCA6174A 它需要的驱动是ath10k。厂商说这个驱动是包含在Linux源码中的,但是通过查看源码发现我们的3.14.64 kernel里面的ath10k驱动由于版本较低的缘故还没有添加QCA6174A 的支持。那么就遇到一个比较尴尬的事情,没有任何驱动也没有任何资料可以使用参考。没办法我就查找各种资料幸好功夫不负有心人我找到了compat-wireless驱动源码,发现里面有我们需要的驱动。我们就从下面路径下载了comat-wireless驱动compat-wireless-2017-09-25.tar.xz,然后单独编译移植到我们的系统。

compat-wireless驱动下载地址:http://mirror2.openwrt.org/sources/

  • 驱动编译
  1. 修改顶层Makefile
    下载到驱动源码后首先需要通过修改顶层Makefile中的KMODDIR,KLIB,KMODPATH_ARG,KLIB_BUILD等变量来设置kernel路径和驱动安装路径(这里和后面说的安装路径都是指编译后的驱动存放路径,编译Android的时候会把这个安装路径下的驱动和lib库等文件打包到相关Image中),以确保驱动可以正常编译和安装到你的Android系统中。如下是我的修改可做参考
    --- a/compat-wireless-2017-09-25/Makefile	2017-09-29 04:51:19.000000000 +0800
    +++ b/compat-wireless-2017-09-25/Makefile	2019-01-15 17:29:54.336700189 +0800
    @@ -8,14 +8,18 @@ MAKEFLAGS += --no-print-directory
     SHELL := /bin/bash
     BACKPORT_DIR := $(shell pwd)
     
    -KMODDIR ?= updates
    +KMODDIR = kernel
     ifneq ($(origin KLIB), undefined)
     KMODPATH_ARG := "INSTALL_MOD_PATH=$(KLIB)"
     else
    -KLIB := /lib/modules/$(shell uname -r)/
    +KLIB := "/home/work/Android_BSP/byt_mr_2016ww32/device/advantech/upos-kernel/x86_64/"
    -KMODPATH_ARG :=
    +KMODPATH_ARG := "INSTALL_MOD_PATH=$(KLIB)"
     endif
    -KLIB_BUILD ?= $(KLIB)/build/
    +KLIB_BUILD = "/home/work/Android_BSP/byt_mr_2016ww32/device/advantech/upos-kernel/linux"
     KERNEL_CONFIG := $(KLIB_BUILD)/.config
     KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile
     CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
    
  2. 配置编译选项 
    通过make menuconfig来配置我们需要的编译选项。我需要编译cfg80211,mac80211,ath10,ath10_core,ath10_pci等驱动。如下是我的操作可供参考
    Android6.0 Qualcomm Atheros QCA6174A WiFi Model Support_第1张图片
    Android6.0 Qualcomm Atheros QCA6174A WiFi Model Support_第2张图片
  3. 编译和安装
    上面配置好后就可以分别执行make和make install命令编译和安装驱动了。我设置的驱动放置路径为x86_64,那么如下是我编译安装后看到的驱动
    Android6.0 Qualcomm Atheros QCA6174A WiFi Model Support_第3张图片
  • Android相关修改

Android相关修改主要包括添加wifi firmware,hardware层修改,framwork层修改,wpa_supplicant服务添加等。下面我们逐一来介绍。

  1. wifi firmware
    wifi驱动加载的时候一般都需要添加firmware的,而firmware一般也是由厂商提供的。奇葩的是PM也没有问厂商要到firmware。那怎么办呢?那我就各种的找,真是柳暗花明又一村我发现安装Ubuntu系统后该模块是可以使用的。所以我就查看Ubuntu系统的dmesg,终于找到了ubuntu系统中使用的QCA6174A相关firmware,然后把他拷贝了出来。有了firmware只需要将它拷贝到系统指定的路径即可,加载驱动的时候就会自动在相关路径寻找并加载。下面是我的添加可供参考
    --- a/device/advantech/upos/upos.mk
    +++ b/device/advantech/upos/upos.mk
    @@ -68,6 +68,18 @@ PRODUCT_COPY_FILES += \
     	$(LOCAL_PATH)/third_party/busybox-x86_64:system/bin/busybox-x86_64 \
     	$(LOCAL_PATH)/third_party/busybox-x86_64:system/bin/busybox
     
    +PRODUCT_COPY_FILES += \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/board.bin:system/vendor/firmware/ath10k/QCA6174/hw3.0/board.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/board-2.bin:system/vendor/firmware/ath10k/QCA6174/hw3.0/board-2.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/firmware-4.bin:system/vendor/firmware/ath10k/QCA6174/hw3.0/firmware-4.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/notice_ath10k_firmware-4.txt:system/vendor/firmware/ath10k/QCA6174/hw3.0/notice_ath10k_firmware-4.txt \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/board.bin:system/vendor/firmware/ath10k/QCA6174/hw2.1/board.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/board-2.bin:system/vendor/firmware/ath10k/QCA6174/hw2.1/board-2.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/firmware-5.bin:system/vendor/firmware/ath10k/QCA6174/hw2.1/firmware-5.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/notice_ath10k_firmware-5.txt:system/vendor/firmware/ath10k/QCA6174/hw2.1/notice_ath10k_firmware-5.txt \
    +	$(LOCAL_PATH)/third_party/ath10k/ath10k.conf:system/etc/modprobe.d/ath10k.conf 
    +
    +
     PRODUCT_PACKAGES += \
         AndroidTerm \
         libjackpal-androidterm4 \
    需要注意的是给系统的system/etc/modprobe.d/路径下还拷贝了ath10k.conf文件,该文件只有一条命令,但是是必须添加的因为发现如果不添加驱动加载的时候会报错
    options ath10k_core skip_otp=y
  2. hardware层修改
    WiFi相关代码在hardware层的分为两部分。一部分是/libhardware_legacy/wifi.c。这部分代码是wifi驱动加载卸载,firmware存放路径和加载,wifi socket通信等相关处理的关键。另一部分是/hardware/qcom/wlan/qcwcn/wpa_supplicant_8_lib。它里面的driver_cmd_nl80211.c是驱动和wpa_supplicant通信的关键。kernel和wpa_supplicant之间的交互一般都有固定的驱动接口如WEXT、NL80211。QCA6174A的驱动接口是NL80211,而/hardware/qcom/wlan/qcwcn/wpa_supplicant_8_lib正是QCA6174A需要的NL80211代码。需要在BoardConfig.mk中配置一下才可以编译和使用指定的wpa_supplicant_8_lib。如下是我的配置
    --- a/device/advantech/upos/BoardConfig.mk
    +++ b/device/advantech/upos/BoardConfig.mk
    @@ -207,6 +207,19 @@ BOARD_HAVE_BLUETOOTH_LINUX := false
     
     BOARD_KERNEL_CMDLINE += acpi_backlight=video
     
    +##############################################################
    +# Source: device/intel/mixins/groups/wlan/autodetect/BoardConfig.mk
    +##############################################################
    +ADDITIONAL_DEFAULT_PROPERTIES += wifi.interface=wlan0
    +#WPA_SUPPLICANT_VERSION := VER_2_1_DEVEL
    +WPA_SUPPLICANT_VERSION := VER_0_8_X
    +BOARD_WPA_SUPPLICANT_DRIVER := NL80211
    +#WIFI_DRIVER_MODULE_PATH ?= auto
    +#BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_rtl
    +BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_qcwcn
    +BOARD_WLAN_DEVICE := qcwcn
    +DEVICE_PACKAGE_OVERLAYS += device/intel/common/wlan/overlay-wifi-display
    +
     DEVICE_PACKAGE_OVERLAYS += device/intel/common/audio/overlay
     DEVICE_PACKAGE_OVERLAYS += device/intel/common/audio/overlay-no-ultrasound
     
  3. framwork层修改
    系统网络选项配置和优先级的配置实在/frameworks/base/core/res/res/values/config.xml文件中的,不过我们通常的做法是不直接修改frameworks中的该文件,而是在平台代码中添加相关文件然后编译系统的时候以overlay的方式来修改它,那么下面是我们的修改
    --- a/device/intel/common/wlan/overlay-wifi-display/frameworks/base/core/res/res/values/config.xml
    +++ b/device/intel/common/wlan/overlay-wifi-display/frameworks/base/core/res/res/values/config.xml
    @@ -14,4 +14,50 @@
         -->
         true
     
    +    
    +    
    +    
    +    
    +    
    +        "wifi,1,1,1,-1,true"
    +        "mobile,0,0,0,-1,true"
    +        "mobile_mms,2,0,2,60000,true"
    +        "mobile_supl,3,0,2,60000,true"
    +        "mobile_hipri,5,0,3,60000,true"
    +        "ethernet,9,9,1,-1,true"
    +        "mobile_fota,10,0,2,60000,true"
    +        "mobile_ims,11,0,2,60000,true"
    +        "mobile_cbs,12,0,2,60000,true"
    +        "wifi_p2p,13,1,0,-1,true"
    +    
    +    
    +    
    +    
    +        "1,1"
    +        "0,1"
    +        "9,1"
    +    
    +
    +    
    +    
    +        0 
    +        2 
    +        3 
    +        4 
    +        5 
    +        9 
    +        10 
    +        11 
    +        12 
    +    
    +
    +
     
  4. wpa_supplicant服务添加
    wpa_suppulicant服务是wifi模块在HAL层和framework层通信的关键,它是一个后台运行的服务。源码在/external/wpa_supplicant_8/wpa_supplicant/目录下,我们需要在device目录的平台代码的makefile中添加编译选项,如下是我们添加的
    --- a/device/advantech/upos/device.mk
    +++ b/device/advantech/upos/device.mk
    @@ -303,6 +303,19 @@ PRODUCT_COPY_FILES += \
     PRODUCT_PACKAGES += \
         audio.a2dp.default
     
    +##############################################################
    +# Source: device/intel/mixins/groups/wlan/autodetect/product.mk
    +##############################################################
    +PRODUCT_COPY_FILES += \
    +    device/intel/common/wlan/wpa_supplicant-common.conf:system/etc/wifi/wpa_supplicant.conf \
    +    device/intel/common/wlan/wpa_supplicant_overlay.conf:system/etc/wifi/wpa_supplicant_overlay.conf \
    +	frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml
    +	#frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml
    +
    +PRODUCT_PACKAGES += \
    +		wpa_supplicant 
    +
    +
     # Tinyalsa
     PRODUCT_PACKAGES_DEBUG += \
             tinymix \
    上面出来添加wpa_supplicant的编译外还将需要的wpa_cupplicant.conf配置文件也拷贝到了系统指定目录,另外frameworks/native/data/etc/android.hardware.wifi.xml和frameworks/native/data/etc/android.hardware.wifi.direct.xml分别代表的是设备是否支持wifi功能和wifi直连功能,如果不添加android.hardware.wifi.xml的话在Setting中就无法看到WIFI选项。
    编译了wpa_supplicant后,就需要添加一个后台服务来运行它,并且需要添加获取IP的服务。如下是我的添加:
    --- a/device/advantech/upos/init.rc
    +++ b/device/advantech/upos/init.rc
    @@ -14,6 +14,12 @@ on post-fs-data
     on post-fs-data
         setprop persist.sys.root_access 3
     
    +on post-fs-data
    +	mkdir /data/misc/wifi 0770 wifi wifi
    +	mkdir /data/misc/wifi/sockets 0770 wifi wifi
    +	mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi
    +	mkdir /data/misc/dhcp 0770 dhcp dhcp
    +
     on boot
         setprop service.adb.tcp.port 5555
     
    @@ -214,6 +220,42 @@ on post-fs-data
     
     import /init.debug-charging.rc
     
    +
    +service wpa_supplicant /system/bin/wpa_supplicant -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    +	-O/data/misc/wifi/sockets -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0
    +	class main
    +	socket wpa_wlan0 dgram 660 wifi wifi
    +	disabled
    +
    +
    +#setprop wifi.supplicant wpa_supplicant
    +
    +
    +service dhcpcd_wlan0 /system/bin/dhcpcd -aABDKL
    +	class main
    +	disabled
    +	oneshot
    +
    +service iprenew_wlan0 /system/bin/dhcpcd -n
    +	class main
    +	disabled
    +	oneshot
    +
    +on property:init.svc.wpa_supplicant=stopped
    +    stop dhcpcd
    +
     on fs
         mkdir /dev/pstore 0755 root system
         mount pstore pstore /dev/pstore

 

  • 其他修改

我们在移植的时候发现系统状态栏的网络状态显示不正常,老是存在一个感叹号,但是网络却是可以使用的。经过追踪代码发现是Android网络的验证机制导致的。Android系统可以通过Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED全局变量来控制网络连接以后是否需要进行网络可用性检查。如果该值被设置为1或者没有设置该值则系统会通过访问Settings.Global.CAPTIVE_PORTAL_SERVER全局变量指定的网址来判断网络是否可用。如果全局变量Settings.Global.CAPTIVE_PORTAL_SERVER没有被设置系统则会使用默认的DEFAULT_SERVER="connectivitycheck.gstatic.com"网址测试。那么问题就出在这里,国内由于某种原因这个网址有时可用连接上有时连接不上,所以当连接不上的时候无论是Ethernet网络、WiFi网络还是3G/4G网络,它的状态栏图标都会有感叹号。想了解这部分可以参考/frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java代码。那么问题找到了该怎么解决呢?一般有下面两种方法可以解决:

  1. 方法一
    通过设置Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED为0将网络检查取消掉,但是这样会存在一个问题。当我们连接的Ethernet网络或者网络需要网络认证才可以使用的话,我们就无法进入到这个网络认证界面了,也就是说无法认证连接网络了。
  2. 方法二:
    设置Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED为1,并将Settings.Global.CAPTIVE_PORTAL_SERVER设置为一个国内可用的网络地址即可。这里需要注意的是Settings.Global.CAPTIVE_PORTAL_SERVER不是随便设置个网址就可以的,它必须是一个可以返回204状态码的网址。

那么我们就是使用第二种方法解决了这个问题的。做法如下:

--- a/device/advantech/upos/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
+++ b/device/advantech/upos/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
@@ -22,6 +22,12 @@
     false
 
     
    true
+
+	
+	1
+	
+	
+    204.gentool.top
         
 
--- a/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2576,6 +2576,12 @@ class DatabaseHelper extends SQLiteOpenHelper {
             loadBooleanSetting(stmt, Settings.Global.ASSISTED_GPS_ENABLED,
                     R.bool.assisted_gps_enabled);
 
+			loadIntegerSetting(stmt, Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED,
+                    R.integer.def_captive_portal_detection_enable);
+
+			loadStringSetting(stmt, Settings.Global.CAPTIVE_PORTAL_SERVER,
+                    R.string.def_captive_portal_server);
+
             loadBooleanSetting(stmt, Settings.Global.AUTO_TIME,
                     R.bool.def_auto_time); // Sync time to NITZ
 

 

 

你可能感兴趣的:(Android)