First, credit to John Wood who figured out how to get this working on the MicroZed:
http://picozed.org/content/steps-get-wlink-using-petalinux-microzed
I adapted his procedure to work with the PicoZed.
My system:
- PicoZed Rev C02
- PicoZed FMC Carrier Board
- TI WiLink8 WL1837
- Petalinux 2014.4 (kernel 3.17)
- Release 8.6 of the TI drivers
Step 1: Make a custom cable
Let's get the hard part out of the way. Make yourself a custom cable to connect the WiLink adapter to the J7 P-mod on the PicoZed carrier board. For some reason, Avnet changed the pinout on the PicoZed P-mod to be different than that of the MicroZed, so you can't simply plug it in directly.
WiLink adaptor J3 --> PMOD J7
Pin1 Pin2
Pin2 Pin1
Pin3 Pin8
Pin4 Pin7
Pin5 Pin5
Pin6 Pin6
Pin7 Pin9
Pin8 Pin10
Pin9 Pin3
Pin10 Pin4
Pin11 Pin11
Pin12 Pin12
NOTE: make the cable AS SHORT AS POSSIBLE. I initially made mine about a finger's length and it proved to be too long to meet the high speed timing requirements of the SDIO interface.
Step 2: Download the TI driver using the build-utilites script.
git://git.ti.com/wilink8-wlan/build-utilites.git
Step 3: Apply patch to kernel
This patch is included in the above build utilites in
build-utilites/patches/kernel_patches/imx-3.14.28/0010-mmc-Add-SDIO-function-devicetree-subnode-parsing.patch
Note: it will not be applied automatically since the xlnx-3.17 kernel does not have patches associated with it.
Copy the file to the petalinux installation folder:
/opt/PetaLinux/petalinux-v2014.4-final/components/linux-kernel/xlnx-3.17
cd into that folder and type:
patch -p1 < 0010-mmc-Add-SDIO-function-devicetree-subnode-parsing.patch
Step 4: Enable the necessary settings.
In the build-utilites folder you got from git take a look at the 'base_config=' section. These settings need to be enabled. I was able to find all but one setting in the petalinux configuration this was CONFIG_
WIRELESS_EXT. In petalinux this appears to be private. To make this visible I modified the Kconfig in /opt/PetaLinux/petalinux-2014.4-final/components/linux-kernel/xlnx-3.17/net/wireless/ as shown:
config WIRELESS_EXT
bool "Enable Wireless Extensions"
default n
Then run petalinux-config -c kernel, each line shows the text menu items:
Cryptographic API -->
tu2022 CCM Support
tu2022 GCM Support
tu2022 EC8 Support
tu2022 Michael Mic keyed digest algorithm
tu2022 Arc4 cipher algorithm
Library Functions -->
tu2022 CRC 7 Functions
Device Drivers -->
tu2022 Input Device Support
tu2022 Misc...Devices
tu2022 User Level Driver Support
Networking -->
tu2022 RF Switch subsystem support
Security Options -->
tu2022 Enable Access Key Retention Support
tu2022 Enable Different Security Modules
These should be all the kernel config changes you need to make.
Step 5: Build Petalinux with these settings
type 'petalinux-build' from the command line in your project directory
Step 6: Modify setup-env
I took John's advice and created a petalinux app that will copy the fs directory to the TARGET ROOT, which allows you to make updates to the configuration without wiping out files I put directly into target root. My setup-env is shown below. I will cover the app for copying later.
//
# -(o o)-
#========================oOO==(_)==OOo=======================
# This file contains the exports needed for automating the
# build process of WLAN components.
# Place this file in the same directory with wl18xx_build.sh
# build scripts. No need to run 'source setup-env', the build
# scripts will perform it internally.
#===========================================================
# User specific environment settings - use full PATH
# if DEFAULT toolchain path is set toolchain will be downloaded to ./toolchain.
export TOOLCHAIN_PATH=/opt/PetaLinux/petalinux-v2014.4-final/tools/linux-i386/arm-xilinx-linux-gnueabi/bin
# if DEFAULT path to root filesystem is set ./fs folder will be used.
export ROOTFS=~/Embedded/wlink_test/software/wlink/components/apps/wireless/fs/components/apps/wireless/fs
#export ROOTFS=DEFAULT
#if DEFAULT kernel path is set - kernel will be downloaded (set branch to match kernel version)
export KERNEL_PATH=~/Embedded/wlink_test/software/wlink/build/linux/kernel/xlnx-3.17
# if KERNEL_VARIANT below is set the build script will look for kernel specific
# patches under the patches directory:
# - patches under the patches/driver_patches/$KERNEL_VARIANT directory would be
# applied during "modules" build.
# - patches under the patches/kernel_patches/$/$KERNEL_VARIANT directory would
# be applied to the kernel pointed by KERNEL_PATH in case the "patch_kernel"
# command is used.
# Note: the kernel is not built automatically after the patches are applied
export KERNEL_VARIANT=xlnx-3.17
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
export ARCH=arm
[ "$TOOLCHAIN_PATH" != "DEFAULT" ] && export PATH=$TOOLCHAIN_PATH:$PATH
Step 7: Create Petalinux App
a. I created a petalinux app called wireless, deleted the C file, and modified the make file as shown
b. create fs subdriectory for copying files in
ifndef PETALINUX
$(error "Error: PETALINUX environment variable not set. Change to the root of your PetaLinux install, and source the settings.sh file")
endif
include apps.common.mk
APP = settings
all: build install
.PHONY: build
build:
install:
t# Copy settings files to the rootfs.
tcp -r ./fs/* $(TARGETDIR)
clean:
Step 8: Add startup of modules to /etc/modules in /wireless/fs directory
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.
wlcore_sdio
Wl18xx
Step 9: Add wl18xx-conf.bin to fs directory in the project you made
You need to generate this using the configureation.sh script in build-utilites
Then copy the file to:
/fs/lib/firmware/ti-connectivity/wl18xx-conf.bin
Step 10: Run the build script using update R8.6
./sudo_build_wl18xx.sh update R8.6
Step 11: Fix issue with Precistion Timing GPIO
When going to 8.6 there is a new requirement for a GPIO which is not on the picozed for a precision timing output. This will preclude the driver from loading. Comment out the request for this line in the following file.
src/driver//drivers/net/wireless/ti/wlcore/main.c (approx line 6450)
#if 0 <--- do this
/* time sync */
wl->time_sync.gpio = 66;
ret = gpio_request_one(wl->time_sync.gpio, GPIOF_DIR_OUT, "time_sync");
if (ret < 0) {
wl1271_error("error requesting time_sync gpio");
goto err_buffer_32;
}
wl1271_info("Time Sync: gpio requested");
#endif <--- and this
Step 12: Rebuild the TI drivers
Do not use update or your change will be lost.
./sudo_build_wl18xx.sh
Step 13: Update device tree.
Assuming you are using the petalinux structure for a picozed, you should only need to change which SDIO you are using and which gpio pin is used for enable and which is used for the interrupt for a custom board...
/dts-v1/;
/include/ "system-conf.dtsi"
/ {
twlan_en: fixedregulator@2 {
tcompatible = "regulator-fixed";
tregulator-name = "wlan-en-regulator";
tregulator-min-microvolt = <0x325aa0>;
tregulator-max-microvolt = <0x325aa0>;
tgpio = <&gpio0 0x9 0x4>; <<<<<<<<< gpio 9
tstartup-delay-us = <0x11170>;
tenable-active-high;
t};
};
&gem0 {
tphy-handle = <&phy0>;
tphy-mode = "rgmii-id";
tmdio {
tt#address-cells = <1>;
tt#size-cells = <0>;
ttphy0: phy@0 {
tttcompatible = "marvell,88e1510";
tttdevice_type = "ethernet-phy";
tttreg = <0x0>;
tttmarvell,reg-init = <3 16 0xff00 0x1e 3 17 0xfff0 0x00>;
tt};
t};
};
&qspi {
tflash0: flash@0 {
tcompatible = "micron,n25q128a13";
t};
};
&gpio0 { <<<<< make gpio an int controller for gpio ints
tinterrupt-controller;
t#interrupt-cells = <2>;
};
&sdhci1{ <<<<<<< SDIO 1
tvmmc-supply = <&wlan_en>;
tbus-width = <4>;
tti,non-removable;
tti,needs-special-hs-handling;
tcap-power-off-card;
tkeep-power-in-suspend;
t#address-cells = <1>;
t#size-cells = <0>;
twlcore: wlcore@0 {
ttcompatible = "ti,wl1837";
ttinterrupt-parent = <&gpio0>;
ttinterrupts = <0 4>; <<<<<<GPIO pin 0, note GPIO is used as int parent
ttreg = <2>;
ttplatform-quirks = <0x1>;
ttboard-ref-clock = <0x4>;
t};
};
Step 13: Image will be too big
You need to increase the mem offset in two places:
1. petalinux-config --> uboot configuration - netboot offset change from hex 0x1000000 to desired value - my image.ub ~20M, but I set it to 0x3000000.
2. In your ./subsystems/linux/configs/u-boot/platform-top.h change CONFIG_SYS_BOOTM_LEN from 0x1000000 to same value 0x3000000.
u00A0
*** Must rebuild the whole project in order for this to take effect (includes new BOOT.bin and image.ub) ***
You should now be able to see the wlan0 interface when you boot up and type ifconfig -a
Below are some of the messages displayed during boot that indicate a correct initialization of the WiLink module:
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
sdhci-arasan e0101000.sdhci: No vqmmc regulator found
mmc1: SDHCI controller on e0101000.sdhci [e0101000.sdhci] using ADMA
sdhci-arasan e0101000.sdhci: card claims to support voltages below defined range
mmc1: queuing unknown CIS tuple 0x91 (3 bytes)
mmc1: new high speed SDIO card at address 0001
Loading modules backported from Linux version R8.6-0-g3f5b34f
Backport generated by backports.git ol_r8.a9.28-0-g4677dc3
cfg80211: Calling CRDA to update world regulatory domain
wlcore: wl18xx HW: 183x or 180x, PG 2.2 (ROM 0x11)
wlcore: loaded
wlcore: driver version: R8.6-dirty
wlcore: compilation time: Tue Jan 19 16:03:08 2016
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: Exceeded CRDA call max attempts. Not calling CRDA
The CRDA timeout I haven't figured out yet, but the wlan0 interface is detected and can connect to wireless networks successfully. The timeout, from what I've read, may have something to do with busybox mdev not detecting a kernel event.