Hi Sheldon, Everyone,
I got the Intel 7260 wifi card working on Android Lollipop 5.1 and I thought I'd document how I got it working here as there is a lot of information out there and no complete solution really exists.
I'll start from the kernel level and move up the stack.
1. Kernel Modules.
- You must build the kernel modules cfg80211.ko mac80211.ko iwlwifi.ko and iwlmvm.ko
- In menuconfig:
- Drivers -> Network Device Support -> Wireless LAN -> Intel Wireless WiFi Next Gen AGN [M]
- -- Wireless LAN -> Intel Wireless Wifi MVM Firmware support [M]
- Network Support -> Wireless -> cfg80211 - wireless configuration API [M]
- -- -> Generic IEEE 802.11 Networking Stack (mac80211) [M]
- (Note. These must be kernel modules and not built-in or firmware loading will not work).
- Edit BoardConfig.mk file to ensure kernel modules are copied:
TARGET_KERNEL_MODULES := \
kernel_imx/drivers/net/wireless/iwlwifi/iwlwifi.ko:system/lib/modules/iwlwifi.ko \
kernel_imx/drivers/net/wireless/iwlwifi/mvm/iwlmvm.ko:system/lib/modules/iwlmvm.ko \
kernel_imx/drivers/net/wireless/iwlwifi/dvm/iwldvm.ko:system/lib/modules/iwldvm.ko \
kernel_imx/net/mac80211/mac80211.ko:system/lib/modules/mac80211.ko \
kernel_imx/net/wireless/cfg80211.ko:system/lib/modules/cfg80211.ko
- From android root, rebuild your kernel modules and sync the filesystem.
~/myandroid $ make kernelmodules # Build the kernel modules and copy to product out dir.
~/myandroid $ make snod # Optionally rebuild the system.img (use simg2img to make a raw image).
~/myandroid/out/target/product/my_imx_product $ adb remount; adb -p $(pwd) sync # Simply sync with device connected via adb.
2. Test Loading Of Kernel Modules
adb shell insmod /system/lib/modules/cfg80211.ko
adb shell insmod /system/lib/modules/mac80211.ko
adb shell insmod /system/lib/modules/iwlwifi.ko
adb shell insmod /system/lib/modules/iwlmvm.ko
You should see the folloiwing on your root kernel console (debug serial port).
Intel(R) Wireless WiFi driver for Linux, in-tree:d
Copyright(c) 2003- 2014 Intel Corporation
PCI: enabling device 0000:01:00.0 (0140 -> 0142)
iwlwifi 0000:01:00.0: Direct firmware load failed with error -2
iwlwifi 0000:01:00.0: Falling back to user helper
imx-sgtl5000 sound.27: ASoC: CODEC (null) not registered
imx-sgtl5000 sound.27: snd_soc_register_card failed (-517)
platform sound.27: Driver imx-sgtl5000 requests probe deferral
iwlwifi 0000:01:00.0: Direct firmware load failed with error -2
iwlwifi 0000:01:00.0: Falling back to user helper
iwlwifi 0000:01:00.0: Direct firmware load failed with error -2
iwlwifi 0000:01:00.0: Falling back to user helper
iwlwifi 0000:01:00.0: loaded firmware version 22.1.7.0 op_mode iwlmvm
iwlwifi 0000:01:00.0: failed to load module iwlmvm (error -2), is dynamic loading enabled?
iwlwifi 0000:01:00.0: Detected Intel(R) Dual Band Wireless AC 7260, REV=0x144
iwlwifi 0000:01:00.0: L1 Disabled - LTR Disabled
iwlwifi 0000:01:00.0: L1 Disabled - LTR Disabled
There should be a wlan0 network interface, (see ifconfig wlan0, or if you install busybox busybox ifconfig wlan0).
At this point in time you can probably use the wpa_supplicant and wpa_cli tools to connect to a wifi network to test (a quick example).
wpa_supplicant -iwlan0 -Dnl80211 -dd -c/data/misc/wifi/wpa_supplicant.conf -O/data/misc/wifi/sockets -B
wpa_cli -p /data/misc/wifi/sockets
> scan
OK
<3>CTRL-EVENT-SCAN-STARTED
<3>CTRL-EVENT-SCAN-RESULTS
> scan_results
bssid / frequency / signal level / flags / ssid
00:13:46:a3:67:a0 2412 -34 [ESS] dlink
> add_network
1
> set_network 1 ssid "dlink"
OK
> set_network 1 key_mgmt NONE
OK
> enable_network 1
OK
> select_network 1
OK
<3>CTRL-EVENT-DISCONNECTED bssid=00:13:46:a3:67:a0 reason=3 locally_generated=1
<3>CTRL-EVENT-STATE-CHANGE id=0 state=0 BSSID=00:13:46:a3:67:a0 SSID=dlink
<3>CTRL-EVENT-STATE-CHANGE id=1 state=3 BSSID=00:00:00:00:00:00 SSID=dlink
<3>CTRL-EVENT-SCAN-STARTED
> wlan0: authenticate with 00:13:46:a3:67:a0
<3>CTRL-EVENT-SCAN-RESULTS wlan0: send auth to 00:13:46:a3:67:a0 (try 1/3)
<3>SME: Trying to authenwlan0: authenticated
ticate with 00:13:46:a3:67:a0 (SSiwlwifi 0000:01:00.0 wlan0: disabling HT as WMM/QoS is not supported by the AP
ID='dlink' freq=2412 MHz)
iwlwifi 0000:01:00.0 wlan0: disabling VHT as WMM/QoS is not supported by the AP
<3>CTRL-EVENT-STATE-CHANGE id=1 state=4 BSSID=00:00:00:00:00:00 SSID=dlink
<3>Trying to associate with 00:13:46:a3:67:a0wlan0: associate with 00:13:46:a3:67:a0 (try 1/3)
(SSID='dlink' freq=2412 MHz)
>wlan0: RX AssocResp from 00:13:46:a3:67:a0 (capab=0x421 status=0 aid=1)
<3>CTRL-EVENT-STATE-CHANGE iwlan0: associated
d=1 state=5 BSSID=00:00:00:00:00:00 SSID=dlink
<3>CTRL-EVENT-STATE-CHANGE id=1 state=6 BSSID=00:00:00:00:00:00 SSID=dlink
<3>Associated with 00:13:46:a3:67:a0
<3>CTRL-EVENT-CONNECTED - Connection to 00:13:46:a3:67:a0 completed [id=1 id_str=]
<3>CTRL-EVENT-STATE-CHANGE id=1 state=9 BSSID=00:13:46:a3:67:a0 SSID=dlink
Now the link should be active and you can create a dhcp request:
netcfg wlan0 dhcp
ping 192.168.0.1
ping 8.8.8.8
You will see the debug information on the logcat:
adb logcat | grep -E "Wifi|wifi|wpa"
If you have got this far, then you know you hardware is working and its just a case of getting Android to communicate with the Wifi card and wpa_supplicant.
3. Android Configuration and update wpa_supplicant.
For making the new intel wifi cards work, the bsp provided by freescale seems to be quite difficult to configure correctly. I found code in an Android port for the Tegra Jetson board to support iwlwifi based cards.
1. Clone the iwlwifi private command driver into android/hardware/iwlwifi
git clone git://github.com/jameswalmsley/androoid_hardware_iwlwifi hardware/iwlwifi
2. Apply the following patch (if not already patched in my git repo).
diff --git a/wpa_supplicant_8_lib/Android.mk b/wpa_supplicant_8_lib/Android.mk
index ad146b9..a636ac8 100644
--- a/wpa_supplicant_8_lib/Android.mk
+++ b/wpa_supplicant_8_lib/Android.mk
@@ -35,7 +35,7 @@ WPA_SUPPL_DIR_INCLUDE = $(WPA_SUPPL_DIR)/src \
$(WPA_SUPPL_DIR)/wpa_supplicant
ifdef CONFIG_DRIVER_NL80211
-WPA_SUPPL_DIR_INCLUDE += external/libnl-headers
+WPA_SUPPL_DIR_INCLUDE += external/libnl/include
WPA_SRC_FILE += driver_cmd_nl80211.c
endif
3. Update BoardConfig to use the correct wifi drivers. (This is my entire wifi config, just delete the stuff from freescale).
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_WLAN_VENDOR := INTEL
WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_iwlwifi
BOARD_WLAN_DEVICE := iwlwifi
BOARD_HOSTAPD_DRIVER := NL80211
BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_iwlwifi
4. Build the wifi private command library:
mmm hardware/iwlwifi
5. Move back to an unmodified lollipop supplicant.
cd external/wpa_supplicant_8
git checkout -b android-5.1.1_r37 android-5.1.1_r37
6. Re-build the updated supplicant
mmm -B external/wpa_supplicant_8
7. Check init.rc file for your board (usually output as init.product_name.rc, or init.freescale.rc)
service wpa_supplicant /system/bin/wpa_supplicant -iwlan0 -d -d -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -I/system/etc/wifi/wpa_supplicant_overlay.conf -O/data/misc/wifi/sockets -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0
socket wpa_wlan0 dgram 660 wifi wifi
class late_start
disabled
oneshot
I had to ensure the command line parameters for the supplicant were all on a single line for it to work.
8. Update the ram-disk
make ramdisk
make bootimage
Now sync or update your android filesystem and boot image. Ensure wifi is diabled and restart your system, then re-load your wifi kernel modules.
Hopefully if everything worked out you should see that your wifi now works.
You can enable wifi from adb like so:
adb wifi enable
adb wifi disable
Caveats
Currently this solution does not describe how to make the kernel modules automatically load. That magic happens inside hardware/libhardware_legacy/wifi.
You'll have to ensure that the build is configured so that libhardware_legacy is built with wifi_unite.c or wifi_intel.c correctly patched to load your kernel modules and start the correct supplicant. (wpa_supplicant and not rtl_wpa_supplicant or bcm_wpa_supplicant).
I'll update this thread later with this information when I have formed a complete working solution.