A20 android 移植MT7601u

移植 MT7601Uwifi模块的过程,虽然没有成功,过程记录下来。
1.1修改 BoardConfig.mk
路径:/a20-jb/android4.2/device/softwinner/wing-m72cd2/BoardConfig.mk
 BoardConfig.mk修改如下:

 注释掉原来的: #BOARD_WIFI_VENDOR := realtek
        增加:	BOARD_WIFI_VENDOR := mtk
	增加: 
# 1.3 mediatek(mtk) wifi support
  ifeq ($(BOARD_WIFI_VENDOR), mtk)
     WPA_SUPPLICANT_VERSION := VER_0_8_X_7601
     BOARD_WPA_SUPPLICANT_DRIVER := NL80211
    # BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_rtl
     BOARD_HOSTAPD_DRIVER        := NL80211
     #BOARD_HOSTAPD_PRIVATE_LIB   := lib_driver_cmd_rtl
 
    SW_BOARD_USR_WIFI  := mt7610
    # BOARD_WLAN_DEVICE  := rtl8188e
 endif

说明:
1、“#”符号起注释作用;
2、“BOARD_WIFI_VENDOR := mtk”是 mtk 系列 wifi 配置的总开关;
3、 WPA_SUPPLICANT_VERSION := VER_0_8_X_7601”“宏指明使用 wpa_supplicant_8_7601,这是由 mtk 提供用于 mt7601 ics 的 wpa_supplicant,后期将加入到 wpa_supplicant_8 中;
4、“BOARD_WPA_SUPPLICANT_DRIVER := NL80211”宏指定 wpa_supplicant 接口类型;
5、“BOARD_HOSTAPD_DRIVER := NL80211”宏指定 hostapd 接口类型;
6、“SW_BOARD_USR_WIFI := mt7601”宏指定选用 mt7601wifi 模组;

注意:
1 、 若 在 BoardConfig.mk 文 件 有 多 处 BOARD_WPA_SUPPLICANT_DRIVER 、WPA_SUPPLICANT_VERSION、SW_BOARD_USR_WIFI、BOARD_WIFI_VENDOR 宏赋值,要确保其他宏赋值是用“#”符号注释的,否则可能会导致异常。

1.2 init.sun7i.rc 
路径:/a20-jb/android4.2/device/softwinner/wing-m72cd2/init.sun7i.rc 
init.sun4i.rc 是资源和服务配置相关的文件,使用 mt7601wifi 模组需要作如下修改(部分代码),指定使用 nl80211 接口。

# 1. realtek wifi service
# 1.1 realtek wifi sta service
#service wpa_supplicant /system/bin/wpa_supplicant -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin
#    class main
#    socket wpa_wlan0 dgram 660 wifi wifi
#    disabled
#    oneshot
  
# 1.2 realtek wifi sta p2p concurrent service
#service p2p_supplicant /system/bin/wpa_supplicant \
#    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf -e/data/misc/wifi/entropy.bin -N \
#    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.
#    class main
#    socket wpa_wlan0 dgram 660 wifi wifi
#    disabled
#    oneshot
 
# 2. mediatek wifi service
# 2.1 mediatek wifi sta service
 service wpa_supplicant /system/bin/wpa_supplicant -Dnl80211-iwlan0 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin
     socket wpa_wlan0 dgram 660 wifi wifi
     group wifi inet
     disabled
     oneshot
 
# 2.2 mediatek wifi sta p2p concurrent service
 service p2p_supplicant /system/bin/wpa_supplicant \
     -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf -e/data/misc/wifi/entropy.bin -N \
     -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf
     class main
     socket wpa_wlan0 dgram 660 wifi wifi
     disabled
     oneshot

注意:
1、若 init.sun4i.rc 文件无修改后代码,可手动添加;


1.3config.xml

config.xml 文件路径:
a20-jb/android4.2/device/softwinner/wing-m72cd2/overlay/frameworks/base/core/res/res/values/config.xml
mt7601 驱动代码是支持 softap 功能,需要作配置才能在设置界面显示 softap 功能,具体的配置是在 config.xml 中实现,修改的部分代码如下。
     <string-array translatable="false" name="config_tether_wifi_regexs">
          <item>"wlan\\d"</item>
      </string-array>

注:若相应平台该目录下没 config.xml 文件,可到其他相应平台相应目录下拷贝一份。


1.4 wing_m72cd2.mk 

wing_m72cd2.mk文件路径:a20-jb/android4.2/device/softwinner/wing-m72cd2\wing_m72cd2.mk
mt7601 驱动代码是支持 wifi direct 功能,需要作配置才能在设置界面显示 wifi direct 功能,
具体的配置是在 crane_evb.mk 中,为目标机器添加 android.hardware.wifi.direct.xml 文件,修
改部分的代码如下。
 # wifi & bt config file
  PRODUCT_COPY_FILES += \
      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 \

1.5wpa_supplicant_8_7601
路径:\android4.1\external\wpa_supplicant_8_7601
这个资料包由 mtk 提供,尚未合并到 wpa_supplicant_8 中。直接复制文件夹到external目录下即可。

1.6 wifi.c
路径:a20-jb/android4.2/hardware/libhardware_legacy/wifi/wifi.c
      a20-jb/android4.2/hardware/libhardware_legacy/wifi/Android.mk

Android.mk 中添加 mt7601 的定义
 # mediatek usb  wifi module
  ifeq ($(SW_BOARD_USR_WIFI), mt7601)
  LOCAL_CFLAGS += -DMTK_WIFI_VENDOR
  LOCAL_CFLAGS += -DMT7601_WIFI_USED
  endif


Wifi.c 定义了启动切换 sta, wifi direct , softap 功能的方法等。
添加模块路径和参数
#elif defined MT7601_WIFI_USED
    /*mediatek 7601 usb wifi*/
    #ifndef WIFI_DRIVER_MODULE_PATH
    #define WIFI_DRIVER_MODULE_PATH         "/system/vendor/modules/mt7601Usta.ko"
    #endif
    #ifndef WIFI_DRIVER_MODULE_NAME
    #define WIFI_DRIVER_MODULE_NAME         "mt7601Usta"
    #endif
    #ifndef WIFI_AP_DRIVER_MODULE_PATH  
    #define WIFI_AP_DRIVER_MODULE_PATH      "/system/vendor/modules/mt7601Uap.ko"   
    #endif
    #ifndef WIFI_AP_DRIVER_MODULE_NAME
    #define WIFI_AP_DRIVER_MODULE_NAME         "mt7601Uap"
    #endif

添加 firmware path
#if defined(RTL_WIFI_VENDOR)||defined(MT7601_WIFI_USED)
#undef WIFI_DRIVER_FW_PATH_STA
#define WIFI_DRIVER_FW_PATH_STA         "STA"
#undef WIFI_DRIVER_FW_PATH_AP
#define WIFI_DRIVER_FW_PATH_AP          "AP"
#undef WIFI_DRIVER_FW_PATH_P2P
#define WIFI_DRIVER_FW_PATH_P2P         "P2P"
#endif


添加启动 softap 所需的参数
#ifdef  WIFI_AP_DRIVER_MODULE_PATH
        static const char AP_DRIVER_MODULE_NAME[] = WIFI_AP_DRIVER_MODULE_NAME;
        static const char AP_DRIVER_MODULE_TAG[]= WIFI_AP_DRIVER_MODULE_NAME " ";
        static const char AP_DRIVER_MODULE_PATH[] = WIFI_AP_DRIVER_MODULE_PATH;
#endif



添加启动 softap 的函数。
int is_wifi_ap_driver_loaded() 
{
	char driver_status[PROPERTY_VALUE_MAX];
	#ifdef WIFI_AP_DRIVER_MODULE_PATH
	FILE *proc;
	char line[sizeof(AP_DRIVER_MODULE_TAG)+10];
	#endif
	if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)
		             || strcmp(driver_status, "ok") != 0) 
	{

		 return 0;  /* driver not loaded */
	 }
	#ifdef WIFI_AP_DRIVER_MODULE_PATH
	 /*
	  * If the property says the driver is loaded, check to
	  * make sure that the property setting isn't just left
	  * over from a previous manual shutdown or a runtime
	  * crash.
	  */
	  if ((proc = fopen(MODULE_FILE, "r")) == NULL) 
	  {
			 ALOGW("Could not open %s: %s", MODULE_FILE, strerror(errno));
			 property_set(DRIVER_PROP_NAME, "unloaded");
	         return 0;
	  }
	  while ((fgets(line, sizeof(line), proc)) != NULL) 
	  {

			if (strncmp(line, AP_DRIVER_MODULE_TAG, strlen(AP_DRIVER_MODULE_TAG)) == 0) 
			{
				fclose(proc);
				 return 1;
		    }
	  }
     fclose(proc);
	 property_set(DRIVER_PROP_NAME, "unloaded");
	 return 0;
	 #else
	 return 1;
	 #endif
 }
int wifi_load_ap_driver()
{
#ifdef WIFI_AP_DRIVER_MODULE_PATH
    char driver_status[PROPERTY_VALUE_MAX];
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 100; /* wait at most 20 seconds for completion */

    if (property_get(SUPP_PROP_NAME, supp_status, NULL)
            && strcmp(supp_status, "stopping") == 0) {
        ALOGD("supplicant status is stopping, try to stop supplicant...");    	
        wifi_stop_supplicant();// wifi on/off test will lead to unblocking problem
        property_get(SUPP_PROP_NAME, supp_status, NULL);
        ALOGD("supplicant status = %s", supp_status);    	
    } 

    if (is_wifi_ap_driver_loaded()) {
        return 0;
    }
    
	ALOGE("begin to insmod %s %s firmware!", AP_DRIVER_MODULE_PATH, "");
    if (insmod(AP_DRIVER_MODULE_PATH, "") < 0) {
        ALOGE("insmod %s %s firmware failed!", AP_DRIVER_MODULE_PATH, "");
        rmmod(AP_DRIVER_MODULE_NAME);//it may be load driver already,try remove it.
        return -1;
    }

	if (strcmp(FIRMWARE_LOADER,"") == 0) {
		property_set(DRIVER_PROP_NAME, "ok");
    }
    else {
        property_set("ctl.start", FIRMWARE_LOADER);
    }

    sched_yield();
    while (count-- > 0) {
        if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
            if (strcmp(driver_status, "ok") == 0)
                return 0;
            else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) {
                wifi_unload_driver();
                return -1;
            }
        }
        usleep(200000);
    }
    property_set(DRIVER_PROP_NAME, "timeout");
    wifi_unload_driver();
    return -1;
#else
    property_set(DRIVER_PROP_NAME, "ok");
    return 0;
#endif
}

int wifi_unload_ap_driver()
{
	ALOGD("wifi unload driver.\n");
    usleep(200000); /* allow to finish interface down */
#ifdef WIFI_AP_DRIVER_MODULE_PATH
    if (rmmod(AP_DRIVER_MODULE_NAME) == 0) 
	{    	
        int count = 20; /* wait at most 10 seconds for completion */
        while (count-- > 0) {
            if (!is_wifi_ap_driver_loaded())
                break;
            usleep(500000);
        }
        usleep(500000); /* allow card removal */
        if (count) {
            return 0;
        }
        return -1;
    } else
        return -1;
#else
    property_set(DRIVER_PROP_NAME, "unloaded");
    return 0;
#endif
}


添加切换 sta、 wifi direct 、sotfap 的步骤。

int wifi_change_fw_path(const char *fwpath)
{
..............
#if defined(RTL_WIFI_VENDOR)
..............
..............
#elif defined(MT7601_WIFI_USED)
ALOGE("%s: %s\n", __FUNCTION__, fwpath);
if(strncmp("AP", fwpath, 2) != 0) {
ret = wifi_unload_ap_driver();
ret = wifi_load_driver();
} else {
ret = wifi_unload_driver();
ret = wifi_load_ap_driver();
}
return ret;
#else
...........

1.7 \android4.1\system\netd
路径:\android4.1\system\netd\ Android.mk
\android4.1\system\netd\ SoftapController-iwpriv.cpp
Android.mk 添加编译定义:
ifeq ($(SW_BOARD_USR_WIFI), mt7601)
LOCAL_SRC_FILES += SoftapController-iwpriv.cpp
else
LOCAL_SRC_FILES += SoftapController.cpp
endif
注:需要在 LOCAL_SRC_FILES 列表中先去掉 SoftapController.cpp。



1.8 Linux 3.4 部分文件移植
编译脚本文件
路径:linux3.4\build.sh
此文件是 linux 的编译脚本。
添加拷贝 mt7601 所需文件的动作,并屏蔽同名文件的拷贝
build_kernel()
{
..............
#
cp modules/wifi/mt7601/RT2870STA.dat ${LICHEE_MOD_DIR}
cp modules/wifi/mt7601/RT2870STACard.dat ${LICHEE_MOD_DIR}
cp modules/wifi/mt7601_ap/RT2870AP.dat ${LICHEE_MOD_DIR}
cp modules/wifi/mt7601_ap/RT2870APCard.dat ${LICHEE_MOD_DIR}


在 build_modules()中添加驱动编译动作和拷贝 Ko 文件的动作。
build_modules()
{
.................
#build mt7601 usb wifi module
make -C modules/wifi/mt7601 \
ARCM=arm
make -C modules/wifi/mt7601_ap \
ARCM=arm
cp modules/wifi/mt7601/os/linux/mt7601Usta.ko $LICHEE_MOD_DIR
cp modules/wifi/mt7601_ap/os/linux/mt7601Uap.ko $LICHEE_MOD_DIR

1.9 添加 MT7601 驱动源码
路径:\linux3.4\modules\wifi\mt7601
\linux3.4\modules\wifi\mt7601_ap
直接添加即可。


1.10 sys_config1.fex
sys_config1.fex 配置文件涉及 3 个 usb 控制器配置信息和 1 个 usb wifi 配置信息,
其中 USB1和 USB2 具有 host 功能,可用于连接 USB 类型 wifi。把 mt7601 配置成接连到 USB2 控制器的修改如下(部分代码)。
;--------------------------------
;---
USB2 控制标志
;--------------------------------
[usbc2]
usb_used=1
usb_port_type=1
usb_detect_type=0
usb_id_gpio=
usb_det_vbus_gpio=
usb_drv_vbus_gpio= port:PH3<1><0><default><0>
usb_host_init_state=0
;--------------------------------------------------------------------------------
;usb wifi configuration
;usb_wifi_id
--- 0- USB0, 1- USB1, 2- USB2
;--------------------------------------------------------------------------------
[usb_wifi_para]
usb_wifi_used=0
usb_wifi_usbc_num=2

说明:
1、 ”符号起注释作用;“;
2、“usb_drv_vbus_gpio”宏指定控制 USB 开关的 pin 脚;
3、“usb_host_init_state”宏必须设为 0,告诉 USB 开关电,设为 1 时 USB 不会开关电;
4、“usb_wifi_used”宏暂时不起作用;
5、“usb_wifi_usbc_num”宏表示使用的 USB 控制器号码;
\


2.1 makefile 修改
路径:/a20-jb/linux3.4/modules/wifi/mt7601/Makefile
修改代码:
 ifeq ($(PLATFORM),ALLWINNER)
 LINUX_SRC = /home/zl/android/a20-jb/linux3.4
 CROSS_COMPILE = arm-linux-gnueabi-
 endif

2.2 ARM平台移植问题:
../os/linux/sta_ioctl.c:2227: error: unknown field 'private' specified in initializer
../os/linux/sta_ioctl.c:2227: warning: initialization from incompatible pointer type
../os/linux/sta_ioctl.c:2228: error: unknown field 'num_private' specified in initializer
../os/linux/sta_ioctl.c:2228: warning: excess elements in struct initializer
../os/linux/sta_ioctl.c:2228: warning: (near initialization for 'rt28xx_iw_handler_def')
../os/linux/sta_ioctl.c:2229: error: unknown field 'private_args' specified in initializer
../os/linux/sta_ioctl.c:2229: warning: excess elements in struct initializer
../os/linux/sta_ioctl.c:2229: warning: (near initialization for 'rt28xx_iw_handler_def')
../os/linux/sta_ioctl.c:2230: error: unknown field 'num_private_args' specified in initializer
../os/linux/sta_ioctl.c:2230: warning: excess elements in struct initializer
../os/linux/sta_ioctl.c:2230: warning: (near initialization for 'rt28xx_iw_handler_def')
make[2]: *** [/home/littlemo/iData/lierda/EA/USB2WiFi/USB-WIFI-RT3070-WPA-V1.0/src/2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux/../../os/linux/sta_ioctl.o] ?? 1
make[1]: *** [_module_/home/littlemo/iData/lierda/EA/USB2WiFi/USB-WIFI-RT3070-WPA-V1.0/src/2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO/os/linux] 错误 2
make[1]:正在离开目录 `/home/littlemo/iData/kernelLinux/arm-linux-2.6.33'
make: *** [LINUX] 错误 2                                      

Platform:Ubuntu 12.04
ARM Kernel:3.4

问题原因:是因为在配置Makefile时,我们指定的内核在配置时不支持802.11的无线设备驱动。
解决办法:
	2.2.1 修改congfigs文件
	路径:a20-jb/linux3.4/arch/arm/configs/vim sun7ismp_android_defconfig
		 
	2.2.2 重新配置编译指定的Linux Kernel,将Device Drivers==>Network deivce support==>Wireless LAN==><*> USB ZD1201 based Wireless device support,编译即可

2.3 A13上面的 script_parser_fetch函数是用来读取config.fex文件的配置用的,在A20上面没法用了,
	修改文件路径:
		a20-jb/linux3.4/modules/wifi/mt7601/os/linux/usb_main_dev.c 
		a20-jb/linux3.4/modules/wifi/mt7601_ap/os/linux/usb_main_dev.c 
	修改代码:
	 INT  rtusb_init(void)
	{
		…………
		/*  int ret;
         ret = script_parser_fetch("usb_wifi_para", "usb_wifi_usbc_num", (int *)&usb_wifi_host, 64);
         if(ret != 0){
                 printk("ERR: script_parser_fetch usb_wifi_usbc_num failed\n");
                 ret = -ENOMEM;
                 return ret;
         }
		*/
         usb_wifi_host =2;
			……


2.4 参考资料:
http://blog.csdn.net/kangear/article/details/17582575
http://blog.csdn.net/ic_soc_arm_robin/article/details/7265640
http://blog.chinaunix.net/uid-28572323-id-3482376.html
http://blog.csdn.net/eastmoon502136/article/details/7850157


猜你喜欢

转载自blog.csdn.net/zhenglie110/article/details/41309175