AM335x基于Linux增加RTL8189 WIFI驱动方法


1. RTL8189设计概述 

1.1 RTL8189简介

RTL8189是专门为实现嵌入式系统的无线局域网通信应用而设计的一款高性能、低成本802.11b/g/n 的SDIO 接口(SDIO 1.1 / 2.0 / 3.0 兼容)无线模块,使用该模块能够使用户通过嵌入式硬件SDIO接口高效快捷的扩展出无线局域网通信功能。模块核心高度集成了MAC、无线基带和2.4G 射频,支持HPY 速率高达150Mbps,完全符合IEEE802.11n 草案3.0 和IEEE802.11 b/g 标准,优化的射频架构和基带算法提供了卓越性能与低功耗。


RTL8189从硬件上来说,此款模块为SDIO接口的硬件设计,驱动通过申请MMC接口来完成和主机之间的数据通信和控制,从软件上来说,其驱动可支持WINCE、LINUX、ANDROID的操作系统,并且同样支持丰富的网络协议和上层的应用工具。


1.2 RTL8189硬件设计

如图为RTL8189与主机之间的硬件连接:

 

图一  RTL8189硬件连接图-宽770.png

图一  RTL8189硬件连接图


从上图可以看出,RTL8189使用AM335x的MMC2接口的SDIO模式:SDIO_D0到SDIO_D3为四根数据线,数据位配置为4位传输模式,这四根线为一个双向线路;SDIO_CMD是命令线,主机和RTL8189通过CMD线发送命令和响应这些命令;SDIO_CLK是时钟线,是主机产生的时钟驱动RTL8189的模块,为单向线路。


2. RTL8189驱动概述


2.1 软件设计简介

RTL8189软体部分需要内核配合完成相关的驱动模块,因为硬件上走的SDIO模式,所以首先要确保主处理器上能够申请一路MMC接口设备来供RTL8189使用,这里使用AM335x的MMC2接口,MMC0作为SD卡用。


2.2 内核的软体

这里只需要配置内核源码里的主BOARD文档即可,以AM335x为例,主配置启动文档为:board-am335xevm.c。


2.2.1 初始化MMC2引脚功能供RTL8189使用,代码如下

在mmc0_pin_mux[]增加MMC2的引脚初始化,增加红色部分:

    /* Module pin mux for mmc0 */

    static struct pinmux_config mmc0_pin_mux[] = {

    {"mmc0_dat3.mmc0_dat3", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

    {"mmc0_dat2.mmc0_dat2", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

    {"mmc0_dat1.mmc0_dat1", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

    {"mmc0_dat0.mmc0_dat0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

    {"mmc0_clk.mmc0_clk", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

    {"mmc0_cmd.mmc0_cmd", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

    {"mcasp0_aclkr.mmc0_sdwp", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP},

    {"spi0_cs1.mmc0_sdcd",  OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP},


    {"gpmc_a1.mmc2_dat0", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},

    {"gpmc_a2.mmc2_dat1", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},

    {"gpmc_a3.mmc2_dat2", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},

    {"gpmc_ben1.mmc2_dat3", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},

    {"gpmc_csn3.mmc2_cmd", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},

    {"gpmc_clk.mmc2_clk", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLUP},

    {NULL, 0},

    };


2.2.2 增加mmc设备接口

在am335x_mmc[]增加红色部分,

    static struct omap2_hsmmc_info am335x_mmc[] __initdata = {

    {

    .mmc            = 1,

    .caps           = MMC_CAP_4_BIT_DATA,

    .gpio_cd        = GPIO_TO_PIN(0, 6),

    .gpio_wp        = GPIO_TO_PIN(3, 18),

    .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3V3 */

    },

    {

    .mmc            = 3,

        .caps           = MMC_CAP_4_BIT_DATA,

        .gpio_cd        = -EINVAL,

        .gpio_wp        = -EINVAL,

        .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3V3 */

    // .mmc            = 0, /* will be set at runtime */

    },

    {

                .mmc            = 0,    /* will be set at runtime */

    },

    {}      /* Terminator */

    };


以上两步内容在以下函数中被调用,

    static void mmc0_init(int evm_id, int profile)

    {

        setup_pin_mux(mmc0_pin_mux);


        omap2_hsmmc_init(am335x_mmc);

        return;

    }


mmc0_init在以下函数中初始化:

    /* Beaglebone Rev A3 and after */

    static struct evm_dev_cfg beaglebone_dev_cfg[] = {

    ......

    //{mmc0_no_cd_init,DEV_ON_BASEBOARD, PROFILE_NONE},

    // {mmc2_wl12xx_init,DEV_ON_BASEBOARD, PROFILE_NONE},

    {mmc0_init, DEV_ON_BASEBOARD, PROFILE_NONE},

    //{mmc0_no_cd_init,DEV_ON_BASEBOARD, PROFILE_NONE},

    {lcdc_init, DEV_ON_BASEBOARD, PROFILE_NONE},

    ......

    }

注意:以上操作只支持上电初始化RTL8189模块,不支持热插拔模式,若想支持参考mmc0热插拔SD卡处理方式。


2.3 驱动的编译

本sdio wifi模块采用的核心为rtl8189es,平台为TI的AM335x。

根据提供的驱动00001311-RTL8188EUS_RTL8189ES_linux_v4.1.2_4787.20120803.zip,也可以到Realtek官网下载最新的rtl8189es驱动包,该驱动不需要外部固件。


2.3.1 配置内核

首先需要配置内核,支持SDIO设备,支持wifi设备,支持 IEEE 802.11 等。

2.3.1.1 支持SDIO设备:

Device Drivers  --->                                                 

  <*> MMC/SD/SDIO card support  --->                                 

    --- MMC/SD/SDIO card support                                     

    [ ]   MMC debugging                                              

    [*]   Assume MMC/SD cards are non-removable (DANGEROUS)          

    [ ]   MMC host clock gating (EXPERIMENTAL)                       

          *** MMC/SD/SDIO Card Drivers ***                           

    <*>   MMC block device driver                                    

    [*]     Use bounce buffer for simple hosts                       

    < >   SDIO UART/GPS class support                                

    <*>   MMC host test driver                                       

          *** MMC/SD/SDIO Host Controller Drivers ***                

    <*>   Secure Digital Host Controller Interface support           

    <*>   SDHCI support on the platform specific bus                 

    < >   Atmel SD/MMC Driver                                        

    <*>   TI OMAP Multimedia Card Interface support                  

    <*>   TI OMAP High Speed Multimedia Card Interface support       

    <*>   MMC/SD/SDIO over SPI                                       

    配置完成后,可以插入SD卡或其他SDIO设备,查看日志信息,看内核是否已支持SDIO驱动,最终效果为MMC驱动可以检测到SDIO设备。


2.3.1.2 支持wifi设备:

Device Drivers  --->                                                  

  [*] Network device support  --->                                    

    --- Network device support                                        

    [*]   Wireless LAN  --->                                          

      *** Enable WiMAX (Networking options) to see the WiMAX drivers * 

      --- Wireless LAN                                                

      <*>   IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)  

      [*]   Support downloading firmware images with Host AP driver   

      [*]   Support for non-volatile firmware download      

          

2.3.1.3 支持IEEE 802.11:

[*] Networking support  --->                                          

  --- Networking support                                              

  -*-   Wireless  --->                                                

    -- Wireless                                                       

    <*>   cfg80211 - wireless configuration API                       

    [ ]     nl80211 testmode command                                  

    [ ]     enable developer warnings                                 

    [ ]     cfg80211 regulatory debugging                             

    [ ]     enable powersave by default                               

    [ ]     cfg80211 DebugFS entries                                  

    [ ]     Old wireless static regulatory definitions                

    [ ]     cfg80211 wireless extensions compatibility                

    [ ]   Wireless extensions sysfs files                             

    -*-   Common routines for IEEE802.11 drivers                      

    [ ]   lib80211 debugging messages                                 

    <*>   Generic IEEE 802.11 Networking Stack (mac80211)             

    ......                                                            

重新编译内核。


2.3.2 编译驱动

2.3.2.1 拷贝我们提供的驱动包的/driver/rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803.tar.gz驱动源码到工作目录,解压源码;

    ***@driver$ tar zxvf rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803 

    ***@driver$ cd rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803/      


2.3.2.2 选择芯片类型;

执行./make_drv:

    ***@rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803$ ./make_drv      

    Please select card type(1/2):                                        

    1) RTL8188eus                                                        

    2) RTL8189es                                                         

    #? 2                                                                 

    You have selected RTL8189es                                          

    rtw_version.h has existed!           

                                

2.3.2.3 修改Makefile;

***@rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803$ vim Makefile    

选择主芯片型号和模块接口:

    CONFIG_RTL8192C = n                                                  

    CONFIG_RTL8192D = n                                                  

    CONFIG_RTL8723A = n                                                  

    CONFIG_RTL8188E = y                                                  

                                                                         

    CONFIG_USB_HCI = n                                                   

    CONFIG_PCI_HCI = n                                                   

    CONFIG_SDIO_HCI = y                                                  


    增加平台类型,默认为I386_PC,这里增加CONFIG_PLATFORM_TI_AM335X = y,并将其他所有都配置为n:

    CONFIG_PLATFORM_I386_PC = n                                          

    CONFIG_PLATFORM_TI_AM335X = y                                        

    CONFIG_PLATFORM_ANDROID_X86 = n                                      

    CONFIG_PLATFORM_ARM_S3C2K4 = n                                       

    CONFIG_PLATFORM_ARM_PXA2XX = n                                       

    CONFIG_PLATFORM_ARM_S3C6K4 = n                                       

    CONFIG_PLATFORM_MIPS_RMI = n                                         

    CONFIG_PLATFORM_RTD2880B = n                                         

    CONFIG_PLATFORM_MIPS_AR9132 = n                                      

    CONFIG_PLATFORM_RTK_DMP = n                                          

    CONFIG_PLATFORM_MIPS_PLM = n                                         

    CONFIG_PLATFORM_MSTAR389 = n                                         

    CONFIG_PLATFORM_MT53XX = n                                           

    CONFIG_PLATFORM_ARM_MX51_241H = n                                    

    CONFIG_PLATFORM_ACTIONS_ATJ227X = n                                  

    CONFIG_PLATFORM_ARM_TEGRA3 = n                                       

    CONFIG_PLATFORM_ARM_TCC8900 = n                                      

    CONFIG_PLATFORM_ARM_TCC8920 = n                                      

    CONFIG_PLATFORM_ARM_RK2818 = n                                       

    CONFIG_PLATFORM_ARM_URBETTER = n                                     

    CONFIG_PLATFORM_ARM_TI_PANDA = n                                     

    CONFIG_PLATFORM_MIPS_JZ4760 = n                                      

    CONFIG_PLATFORM_DMP_PHILIPS = n                                      

    CONFIG_PLATFORM_TI_DM365 = n                                         

    CONFIG_PLATFORM_MSTAR_TITANIA12 = n                                  

    CONFIG_PLATFORM_SZEBOOK = n                                          

    CONFIG_PLATFORM_ARM_SUN4I = n                                        

增加CONFIG_PLATFORM_TI_AM1808相关配置(在ifeq ($(CONFIG_PLATFORM_I386_PC), y) 之后添加):

    ifeq ($(CONFIG_PLATFORM_TI_AM1808), y)                               

    EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN                               

    ARCH := arm                                                          

    CROSS_COMPILE := arm-arago-linux-gnueabi-                            

    KVER  := 3.2.0                                                       

    KSRC := /home/***/linux/ti-a8-linux-04.06.00.07                      

    Endif                                                                

    其中,

    EXTRA_CFLAGS:小端模式;

    ARCH:arm平台;

    CROSS_COMPILE:交叉编译器;

    KVER:内核版本号;

    KSRC:内核所在目录;

Vim命令模式“wq”保存Makefile,并退出;


2.3.2.4  make

***@rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803$ make            

Make成功后,会在目录下生成8189es.ko,即为我们所需要的驱动。否则如果编译失败,需要重新查看配置内核中是否错误。


2.3.3 加载驱动

将驱动文件8189es.ko拷贝到开发板中,可以通过多种方式(ftp/tftp/usb等)。通过insmode加载驱动;

    root@***:~# insmod 8189es.ko                                         

    rtl8189es driver version=v4.1.2_4787.20120803                        

    build time: Apr 11 2013 18:10:15                                     

驱动加载成功,重新热插拔SDIO WIFI模块(不支持热插拔的上电前需正常接入),出现设备信息:

    root@lierda:~# mmc0: new high speed SDIO card at address 0001        

    register rtw_netdev_ops to netdev_ops                                

    Chip Version Info: CHIP_8188E_Normal_Chip_TSMC_A_CUT_1T1R_RomVer(0)  

    ......                                                               

    SetHwReg8188ES: bMacPwrCtrlOn=0                                      

    <=CardDisableRTL8188ESdio                                            

    <=rtl8188es_hal_deinit                                               

    <=== rtw_ips_pwr_down..................... in 40ms       

                              

2.3.4 工具移植

通过ifconfig查看网络设备,可以看到其中有wlan0设备(可能为wlan1、wlan2等),

    root@***:~# ifconfig                                                 

    lo        Link encap:Local Loopback                                  

              inet addr:127.0.0.1  Mask:255.0.0.0                        

              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)                     

                                                                         

    wlan0     Link encap:Ethernet  HWaddr 00:E0:4C:87:00:00              

              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1         

              RX packets:0 errors:0 dropped:1 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)                     

到此,驱动移植完成,之后需要移植iwlist、wpa_supplicant等工具进行测试。


3. RTL8189应用测试

因为现在的无线wifi网络大多是wpa加密。所以需要移植wpa_supplicant工具。


3.1 下载源码

    http://hostap.epitest.fi/wpa_supplicant/

 下载wpa_supplicant-0.7.3.tar.gz (openssl用到0.7.3提供的补丁)

    $tar zxvf wpa_supplicant-0.7.3.tar.gz

 下载www.openssl.org/source/openssl-0.9.8e.tar.gz

    $tar zxvf openssl-0.9.8e.tar.gz


3.2 编译openssl库 

这里有两种编译方法,一是静态编译,最终编译出的wpa_supplicant有2.6M左右,其不需要动态库;二是动态编译,最终编译出来的wpa_supplicant有1.4M左右,运行需要动态库。


a、补丁安装

首先,部分编译还需要打补丁,我们选择的openssl版本为openssl-0.9.8e所以我们需要将wpa_supplicant-0.7.3/patches/openssl-0.9.8e-tls-extensions.patch拷贝到openssl源码下;

    $ cp wpa_supplicant-0.7.3/patches/openssl-0.9.8e-tls-extensions.patch openssl-0.9.8e/

    $ cd openssl-0.9.8e               

    $ patch -p1 < openssl-0.9.8e-tls-extensions.patch

注意:-p1,这里是数字“1”.


3.2.1 动态编译

3.2.1.1 首先进入openssl-0.9.8e目录;

    cd openssl-0.9.8e/

3.2.1.2 通过config配置文件;

./config shared --prefix=/home/***/openssl no-asm

3.2.1.3 修改Makefile (-为去掉设置, +为新加的设置);

       $ vi Makefile

 - CC= cc

 + CC= arm-none-linux-gnueabi-gcc

 - AR= ar $(ARFLAGS) r

 + AR= arm-none-linux-gnueabi-ar $(ARFLAGS) r

 - RANLIB= /usr/bin/ranlib

 + RANLIB= arm-none-linux-gnueabi-ranlib  


    注意:我的CPU为奔腾系列,这样我通过config生成的Makefile中出现3处“-march=pentium”,编译会出错,故这里需将3处全部删除:

 

3.2.1.4 make并make install;

        $ make 

        $ make install

    这样在/home/***/openssl/下就安装了ssl库;

3.2.1.5 拷贝下面库文件到开发板中的/usr/lib中;

    libssl.so.0.9.8

    libcrypto.so.0.9.8


3.2.2 静态编译


3.2.2.1 首先进入openssl-0.9.8e目录;

    cd openssl-0.9.8e/


3.2.2.2 同动态编译,但这里通过Configure来配置编译选项;

    $./Configure linux-elf-arm -DL_ENDIAN       

    linux:'arm-none-linux-gnueabi-gcc' shared 

    --prefix=/home/***/openss


3.2.2.3 修改Makefile (-为去掉设置, +为新加的设置);

    $ vi Makefile

    - CC= cc

    + CC= arm-none-linux-gnueabi-gcc

    - AR= ar $(ARFLAGS) r

    + AR= arm-none-linux-gnueabi-ar $(ARFLAGS) r

    - RANLIB= /usr/bin/ranlib

    + RANLIB= arm-none-linux-gnueabi-ranlib 


3.2.2.4 make并make install;

    $ make 

    $ make install

    这样在/home***/openssl/下就安装了ssl库;


3.2 编译wpa_supplicant

    进入wpa_supplicant-0.7.3.tar.gz解压生成的wpa_supplicant-0.7.3/wpa_supplicant目录中:

    $cp defconfig .config

    $vim .config        

    # Uncomment following two lines and fix the paths if 

      you have installed OpenSSL

    # or GnuTLS in non-default location

    #CFLAGS += -I/usr/local/openssl/include

    #LIBS += -L/usr/local/openssl/lib

    CC=arm-arago-linux-gnueabi-gcc  -L 

      /home/***/openssl/lib/

    CFLAGS += -I/home/***/openssl/include

    LIBS += -L/home/***/openssl/lib        

    $make


编译成功后,在wpa_supplicant 目录下会出现3个可执行工具:

wpa_supplicant、wpa_passphrase、wpa_cli,拷贝到开发板。

把wpa_supplicant.conf文件拷贝到开发板的/etc下:

    ctrl_interface=/var/run/wpa_supplicant

    network={

        ssid="ARM-TEST"

        scan_ssid=1

        key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE

        pairwise=TKIP CCMP

        group=CCMP TKIP WEP104 WEP40

        psk="********"

    }



4. 测试wpa_supplicant

首先,开启一个无线路由器,设置名称“ARM-TEST”/密码“********”,同配置文件wpa_supplicant.conf中一致;

在开发板中执行wpa_supplicant;

    wpa_supplicant v0.7.3

    Copyright (c) 2003-2010, Jouni Malinenand contributors

    usage:

      wpa_supplicant [-BddhKLqqstuvW] [-P] [-g] \

         -i-c[-C] [-D] [-p] \

         [-b] [-f] \

         [-o] [-O] \

         [-N -i-c[-C] [-D] \

         [-p] [-b] ...]

    ...

    example:

      wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf

最后会出现使用例子,在开发板上输入命令:

    wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf &

&表示后台运行。

连接成功后,可在路由器界面查看,即可看到连接成功,静态配置ip,如:

    $ ifconfig wlan0 192.168.1.10

    $ ping 192.168.1.1

Ping结果成功返回,测试完成。

增加路由表信息;

    $ route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1 dev wlan0

    $ route add default gw 192.168.1.1

增加DNS,在/etc/resolv.conf中增加,需根据实际网络设置:

    $ vi /etc/resolv.conf 

         nameserver 202.101.172.46

         nameserver 8.8.8.8

配置成功后,ping百度测试:

    $ ping www.baidu.com

    PING www.baidu.com (115.239.210.26): 56 data bytes

    64 bytes from 115.239.210.26: seq=0 ttl=55 time=17.672 ms

    64 bytes from 115.239.210.26: seq=1 ttl=55 time=27.143 ms


    --- www.baidu.com ping statistics ---

    2 packets transmitted, 2 packets received, 0% packet loss

    round-trip min/avg/max = 17.672/22.407/27.143 ms


wpa_supplicant无线测试成功。



维芯科作为TI的官方合作伙伴,专业于TI MPU处理器多年,我司的AM335x核心板,基于TI AM335x处理器设计的工业级核心板,广泛用于各种工业场景,能够适配多少wifi模块,有需要欢迎来询。


Tags: Array