WiFi - Atheros ath10k driver support?

Recently I will get a wifi adapter and its chipset is qca9882, based on ath10k driver.
I wanna check something that linux kernel 3.11 default include atk10k driver,
current version is 3.10, is there schedule to update linux kernel probably?

I don’t know which drivers were added to the Grinch kernel, but this is typically what Grinch adds compared to the default kernel source…it has added many drivers, especially wireless. See the sticky thread on Grinch kernel, it may already be there.

The Grinch Kernel 21.3.1 added Atheros, Intel, Ralink, Realtek, Broadcom devices, but haven’t more detail.
I will check the update detail of Grinch Kernel in the sticky thread, thank you!

Hi yumeng,

I’m also want to port ath10k on tegra k1, do you finish it ? If yes, could you please share your steps with me.
Thank you so much.

This thread may be of interest:

Hi linuxdev,

Thanks for providing information, I had installed the Grinch kernel, but it has ath9k driver instead of ath10k. So I think I need to find the way to port it on tegra k1.
Thank you.

You might want to ask that same question under the Grinch kernel thread, as it is sticky topic and back porting wireless drivers is one of the things it excels at.


I have a Atheros qca9880 wifi card and would like to make it work with the Jetson TK1.
I already have the 21.3.4 Grinch kernel installed:

ubuntu@tegra-ubuntu:~$ uname -a
Linux tegra-ubuntu 3.10.40-grinch-21.3.4 #1 SMP PREEMPT Fri May 1 10:41:09 UTC 2015 armv7l armv7l armv7l GNU/Linux

And that seems to have some driver in for this card:

ubuntu@tegra-ubuntu:~$ ll -h /lib/firmware/ath10k/QCA988X/hw2.0/
total 264K
drwxr-xr-x 2 root root 4.0K Mar  6 09:23 ./
drwxr-xr-x 3 root root 4.0K Apr  3  2015 ../
-rwxr-xr-x 1 root root 2.1K Jan  6 16:53 board.bin*
-rwxr-xr-x 1 root root 244K Jan  6 16:53 firmware.bin*
-rwxr-xr-x 1 root root 5.3K Jan  6 16:53 otp.bin*

And the lspci also shows the card:

ubuntu@tegra-ubuntu:~$ sudo lspci -v
01:00.0 Network controller: Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter
	Flags: bus master, fast devsel, latency 0, IRQ 130
	Memory at 32200000 (64-bit, non-prefetchable) 
	[virtual] Expansion ROM at 12200000 [disabled] 
	Capabilities: [40] Power Management version 2
	Capabilities: [50] MSI: Enable- Count=1/8 Maskable+ 64bit-
	Capabilities: [70] Express Endpoint, MSI 00
	Capabilities: [100] Advanced Error Reporting
	Capabilities: [140] Virtual Channel
	Capabilities: [160] Device Serial Number 00-00-00-00-00-00-00-00

But the kernel driver in use is missing from the lspci output from above, and the wifi interface does not come up either. So probably the ath10k_pci (I think that’s the one I need) driver is still missing.

So then I went ahead and wanted to download/install the ath10k driver from https://wireless.wiki.kernel.org/en/users/drivers/ath10k/backports.
As the kernel version is still 3.10.40 I downloaded this backprot http://www.kernel.org/pub/linux/kernel/projects/backports/stable/v3.10.19/backports-3.10.19-1.tar.xz

Then I installed it with these steps:
Firstly downloaded Grinch kernel source and extracted to /usr/src/linux-grinch-21.3.4

ubuntu@tegra-ubuntu:~/backports-ath10k-install/backports-3.10.19-1$ make defconfig-ath10k KLIB=/usr/src/linux-grinch-21.3.4 KLIB_BUILD=/usr/src/linux-grinch-21.3.4
ubuntu@tegra-ubuntu:~/backports-ath10k-install/backports-3.10.19-1$ make
ubuntu@tegra-ubuntu:~/backports-ath10k-install/backports-3.10.19-1$ sudo make install
ubuntu@tegra-ubuntu:~/backports-ath10k-install/backports-3.10.19-1$ sudo reboot

Then, the ath10k driver was still not loaded.
Lastly I tried regenerating the initramfs with: update-initramfs -u and rebooted but the driver is still missing.

Has anybody made this driver to work? Any suggestions what should I do to install the driver?

Sorry, but I am pretty new to such things. Why is the kernel so old by the way? I am even less familiar with the ARM front but on x64 there is kernel 4.4 already. It is only that specific 3.10 L4T kernel that has the necessary drivers to make the TK1 work?
Thanks for any help in advance!
log-install.txt (8.52 KB)

I’m really not a “WiFi guy”, but did you also “make modules” and “make modules_install” (FYI, I have not used those backports, not familiar with how that changes things)? Was the CONFIG_LOCALVERSION set to the suffix of uname -r? If not, you may be missing module format driver updates. Also, you may need firmware additions.

Hi lazmol,

I had integrated ath10k driver into TK1, the way I used is re-build kernel.
The way is download kernel source and copy ath10k driver to right place (it should be /kernel/drivers/net/wireless/ath ), and you also need to modify Makefile and Kconfig files to add ath10k in it.
Please remember to enable it when you make menuconfig, then start to build kernel and update kernel.

Hi WesleyLIN and linuxdev,

so thanks for the hints but I am stuck at editing the Kconfig and Makefile. These are what I did so far:
1 downloaded the Grinch 21.3.4 kernel sources from (https://devtalk.nvidia.com/default/topic/906018/jetson-tk1/-customkernel-the-grinch-21-3-4-for-jetson-tk1-developed/1)
2 edited .config so that CONFIG_LOCALVERSION="-grinch-21.3.4_1"
3 downloaded ath10k QCA988X firmware from https://github.com/kvalo/ath10k-firmware
4 copied over the from the ath10k-driver/QCA988X/10.2.4/firmware-5.bin_10. to QCA988X/firmware-5.bin
5 then copied the firmware-5.bin and board.bin files to the /drivers/net/wireless/ath/ath10k/QCA988X so the driver should be in the correct place right?
6 then how can I edit Makefile and Kconfig to add athk to it? This is just to make athk show up in the make menuconfig?

I would appreciate if you could describe how to edit those files with a bit more details! Thanks in advance!

I have not worked with the Atheros, and I do not have any hardware to do any testing with.

If there is a back port then the Kconfig itself should already be partially updated, or else an explicit make command for the ath10k defconfig may work for compiling just this module and not requiring menuconfig in that single module case.

I’m looking at the R21.4 3.10.40-gdacac96 kernel source (which should be a subset of Grinch), and inside of “drivers/net/wireless/ath/” I see subdirectory “ath9k/”, which should work as an example. If “drivers/net/wireless/ath/Kconfig” is visible via other prerequisite selections, then the “source” lines listed in this Kconfig should become available for selection. Assuming the ath10k driver code is added as subdirectory “drivers/net/wireless/ath/ath10k/” you could try adding to “drivers/net/wireless/Kconfig” this line:

source "drivers/net/wireless/ath/ath10k/Kconfig

I assume the patch for ath10k already has its own Kconfig, resulting in this file existing after populating the ath10k subdirectory with the driver source:


Ahh ok I think I realized that I completely missed the driver. :) I only downloaded the firmware previously.
So I downloaded the ath10k driver from here (https://github.com/kvalo/ath/tree/master/drivers/net/wireless/ath/ath10k) and placed the ath10k dir to here: drivers/net/wireless/ath/. So then, in the linux-grinch-21.3.4/drivers/net/wireless/ath/Kconfig I added what you suggested:

source "drivers/net/wireless/ath/ath10k/Kconfig"

while in the linux-grinch-21.3.4/drivers/net/wireless/ath/Makefile I added this to the top:

obj-$(CONFIG_ATH10K)            += ath10k/

Is this latter necessary?
So then I ran “make menuconfig” but it reported this warning:

In file included from scripts/kconfig/zconf.tab.c:2503:0:
scripts/kconfig/menu.c: In function ‘get_symbol_str’:
scripts/kconfig/menu.c:567:18: warning: ‘jump’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     jump->offset = r->len - 1;
scripts/kconfig/menu.c:528:19: note: ‘jump’ was declared here
  struct jump_key *jump;

So then I modified the scripts/kconfig/menu.c file based on this source (https://gitlab.com/veo-labs/linux/commit/85851bcf17e17743c3207d1f839e2b3a154bdbee)
After this the warning did not appear again.
So in the menuconfg the ath10k appeared (so the Kconfig file was properly read) and I made the selections in:
-> Device Drivers
-> Network device support
-> Wireless LAN
Atheros Wireless Cards —>

<M>   Atheros 802.11ac wireless cards support
<M>     Atheros ath10k PCI support
 *     Atheros ath10k debugging
 *     Atheros ath10k debugfs support
 *     Atheros ath10k tracing support

Then, saved the config upon exiting the menuconfig.
So then I issued “make zImage” but got this error:

include/linux/compiler-gcc.h:103:30: fatal error: linux/compiler-gcc5.h: No such file or directory
compilation terminated.
/home/laco/GRINCHcompile/linux-grinch-21.3.4/./Kbuild:35: recipe for target 'kernel/bounds.s' failed
make[1]: *** [kernel/bounds.s] Error 1
Makefile:840: recipe for target 'prepare0' failed
make: *** [prepare0] Error 2

I am trying to compile the kernel right on the jetson itself so I don’t have to export any env vars like: export ARCH=arm or export CROSS_COMPILE=arm-linux-gnueabi-, do I?
I suspect the reason is that I tried to compile with gcc version 5.3 because I installed arch linux on the jetson tk1 using the official guide (http://elinux.org/Jetson/Porting_Arch) and so it can not include ./include/linux/compiler-gcc5.h bacause only these ones are there:
Could you please send me the output of this “gcc --version”?
On my arch install I have gcc 5.3 and I guess I will have to roll back the gcc install to some version 4 (or I flash back the official ubuntu L4T for the kernel compilation).
Thanks for any comment in advance and sorry for the lengthy post but I am new to these things.

Warnings are fairly typical, and whether or not the warning is an issue can depend upon which compiler you are using. Some of the uninitialized jump warnings can be ignored…basically try it out and see. The compiler is basically telling you it can’t verify if the logic is correct or not, it is dependent upon the author’s intent leading up to the use of the code (not a good thing, but in this particular case I believe the warning is not an issue).

I’d be surprised if you had to back port to Grinch, Grinch is actually the most complete kernel you’ll find so far as driver back ports go. For those back ported drivers to work you do of course have to also install that pesky firmware in “/lib/firmware” (not part of the kernel build, this particular firmware is downloaded to the WiFi device).

FYI, the 5.x Linaro compilers are the wrong thing to use on a JTK1; 5.x is used with the JTX1 which has ARMv8a and ARMv8…some of what is produced by 32-bit ARMv8 is compatible with ARMv7, but it is a subset. The linker and compiler used directly on a JTK1 is the 4.8 series. You could probably get away with a 4.9 version series of Linaro, but when compatibility matters in a cross-compile, I use gcc-linaro-4.8-2015.06-x86_64_arm-linux-gnueabihf. From an updated JTK1 using L4T R21.4:

ubuntu@tk1:~$ gcc --version
gcc (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04.1) 4.8.4

You’ll see the same compiler version on a JTX1 for L4T R23.1 or R23.2, but this is because it is the user space side…the kernel space side of things is 64-bit, and the 4.x Linaro series did not have 64-bit within those releases. Once the purely 64-bit JTX1 L4T is released I suspect the native compiler will be a Linaro 5.2 (or at least 5.x) version.

Hi again,

so I tried to cross-compile the kernel which seemed to work but I had some problems. I downloaded the L4T 21.4 kernel sources from here https://developer.nvidia.com/linux-tegra-r214. But then I think the .config was not the correct one which I extracted with “zcat /proc/config.gz > .config” as the localversion was empty although it should be “-gdacac96” I think. So can someone send me a corerct .config? Or how to get one?

What I did:
export ARCH=arm
export CROSS_COMPILE=~/tegra-nouveau-rootfs/out/host/gcc-linaro-4.8-2015.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
make -j4
make modules
make modules_install
The last step failed due to insufficient permissions as it would have put the modules to /lib/modules on the host. So then I reran it wit sudo but then it asked about confuguration details like “64-bit kernel (64BIT) [Y/n/?] (NEW) n”. So how can I point make to put the modules to a different directory?

Thanks for any comments in advance!

Localversion is never in the “/proc/config.gz” file, you always have to add this in manually.

You have to remember that if the kernel were compiled without taking steps for the “install” location to be modified, then install thinks you are installing to the default location for the running machine, not for a cross compile location. The location for install and intermediate files as well can be set to an alternate location…“make install” of a cross compile without those location customizing steps will mistakenly attempt to install to your desktop machine as if it were the Jetson.

For a cross compile, or even for a regular compile, you can set an alternate location for intermediate files…the original source tree would remain pristine with no generated files going there. This is the “make O=/some/where …” option.

For a cross compile, you can also set custom module install location: “make INSTALL_MOD_PATH=/some/where/modules”.

For a cross compile, if building firmware, you can have alternate firmware location via: “make INSTALL_FW_PATH=/some/where/firmware”.

Example where I already have these directories created:


…I can then set these environment variables for convenience:

export TEGRA_KERNEL_OUT=~/kernel_tmp
export TEGRA_MODULES_OUT=~/modules_out
export TEGRA_FIRMWARE_OUT=~/firmware_out

…just for convenience, if actual kernel source is at “~/R21.4/src/kernel”:

export TEGRA_KERNEL_SRC=~/R21.4/src/kernel

Consider this an example of an excessively complete cleanly separated compile source, compile temp files, and compile outputs, doing more than you would normally do:

# Source tree should start pristine...
make mrproper
# If output is not in the source tree, then this too should start pristine...
make <b>O=$TEGRA_KERNEL_OUT</b> mrproper
# Target "tegra12_defconfig" is what "/proc/config.gz" is on a freshly shipped Jetson.
# You could also gunzip the "/proc/config.gz" and name it ".config", placing it
# in <b>$TEGRA_KERNEL_OUT</b> to do the equivalent. config.gz is actually a better way to go
# if your current Jetson kernel has ever been custom configured.
make <b>O=$TEGRA_KERNEL_OUT</b> tegra12_defconfig
# If you don't use "O=" in menuconfig, it'll apply to the source tree, not the alternate location.
make <b>O=$TEGRA_KERNEL_OUT</b> menuconfig
# ...edit the localversion to add the missing "-gdacac96"...
# Target could be just "make", zImage is the target used for a JTK1, and is more specific.
make -j4 <b>O=$TEGRA_KERNEL_OUT</b> zImage
# Not normally needed, this is for firmware dtb files.
make -j4 <b>O=$TEGRA_KERNEL_OUT</b> dtbs
# make O=$TEGRA_KERNEL_OUT modules_prepare could be performed.
make -j4 <b>O=$TEGRA_KERNEL_OUT</b> modules
# This is where modules get installed to a custom location instead of the running machine.
make <b>O=$TEGRA_KERNEL_OUT</b> modules_install <b>INSTALL_MOD_PATH=$TEGRA_MODULES_OUT</b>
# Normally not performed, you could install what would otherwise be a "/lib/firmware"
# install to this alternate location instead. Installing Jetson firmware doesn't do much
# for an x86_64 machine doing the cross compile.
make <b>O=$TEGRA_KERNEL_OUT</b> firmware_install <b>INSTALL_FW_PATH=$TEGRA_FIRMWARE_OUT</b>

After finishing, a number of useful files (such as zImage, System.map, so on) are in a subdirectory of $TEGRA_KERNEL_OUT (~/kernel_tmp). Modules would be in $TEGRA_MODULES_OUT (~/modules_out), and any “/lib/firmware” would instead be in $TEGRA_FIRMWARE_OUT (~/firmware_out).