Skip navigation
Home > All Places > Software Forums > Wi-Fi/Bluetooth for Linux > Blog > Authors VinayakS_26



This Blog gives an insight into compilation of Fmac source for an android platform.




Cross-compilation tool for building the fmac source for android is obtained by fetching the Android NDK package. The Native Development Kit (NDK) along with the Android studio is a set of tools that allow you to leverage C and C++ code in your Android apps. You can use it either to build from your own source code, or to take advantage of existing prebuilt libraries.

However the toolchain provided in the package can be used independently for compiling the FMAC source.


Download the NDK package for your machine type from the following link:


Following table is for selecting the toolchain for the architecture of host machine on which cross compilation is being done:




Toolchain name














The NDK provides the shell script to allow you to perform a customized toolchain installation from the command line.

The script is located in the $NDK/build/tools/ directory, where $NDK is the installation root for the NDK. An example of the use of this script appears below, where toolchain for arm64 is built.


$NDK/build/tools/ --toolchain=aarch64-linux-android-4.9  --platform=android-21 --install-dir=/tmp/my-android-toolchain

--platform à is to provide the android API level.

For more information on Android API level check the following link:



Download  and unzip the latest FMAC release(at the time of writing the blog) from the following link:



Configuring the Package


  1. tar -xzf cypress-backports-v4.14.34-mothra-auto-rc54-module-src.tar.gz
  2. cd v4.14.34-backports
  4. export ANDROID_HOME=<your_path>/android-10.0.0_r2
  5. cd defconfigs/
  6. add the below configs in brcmfmac


Compiling the FMAC driver


Once the FMAC driver source is configure and patched, compile can be done using the make utility with appropriate cross-compiler toolchain.

make   KLIB=$KERNEL_HOME   KLIB_BUILD=$KERNEL_HOME   CROSS_COMPILE=$COMPILER_DIR/aarch64-linux-android-4.9/bin/aarch64-linux-android-   ARCH=arm64 KCFLAGS=-mno-android   defconfig-brcmfmac

$ make   KLIB=$KERNEL_HOME   KLIB_BUILD=$KERNEL_HOME   CROSS_COMPILE=$ COMPILER_DIR/aarch64-linux-android-4.9/bin/aarch64-linux-android-   ARCH=arm64 KCFLAGS=-mno-android   modules -j4

Locations of the compiled  LKMs.


$cp /v4.14.34-backports/compat/compat.ko

$cp /v4.14.34-backports/net/wireless/cfg80211.ko       

$cp /v4.14.34-backports/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko       

$cp /v4.14.34-backports/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko                                


FMAC Debugging

Posted by VinayakS_26 Moderator Feb 4, 2020



The following blog post discusses on the procedure of enabling Debug flag in FMAC driver.




1. If you are building against the running kernel , then enable the following flags in the .config file while preparing the brcmfmac module.







else if you are building with the kernel source, then modify the .config of the kernel source with the following





2. Compile the brcmfmac driver source  for the kernel for which it is being used.


#apply the required patch from the latest release.

#patch -p1<diff_fix_linux-v4.12_kernel_for_brcmfmac_build.patch

$make -C <path_to_kernel_src> M=<fmac_source_dir>

To build against the running kernel use:

$ make -C /lib/modules/`uname -r`/build M=$PWD


3. Enable brcmfmac debug log


$echo 8 > /proc/sys/kernel/printk


4. Insert the driver module with the required message level as module parameter.

list out the parameters accepted by the brcmfmac driver that is inserted in the kernel.


$ls /sys/module/brcmfmac/parameters/

$insmod brcmfmac.ko debug=${BRCMF_Message_Level}


Following are a list of Message levels defined in the debug.h(/v4.14.52-backports/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h)


#define BRCMF_TRACE_VAL 0x00000002

#define BRCMF_INFO_VAL 0x00000004

#define BRCMF_DATA_VAL 0x00000008

#define BRCMF_CTL_VAL 0x00000010

#define BRCMF_TIMER_VAL 0x00000020

#define BRCMF_HDRS_VAL 0x00000040

#define BRCMF_BYTES_VAL 0x00000080

#define BRCMF_INTR_VAL 0x00000100

#define BRCMF_GLOM_VAL 0x00000200

#define BRCMF_EVENT_VAL 0x00000400

#define BRCMF_BTA_VAL 0x00000800

#define BRCMF_FIL_VAL 0x00001000

#define BRCMF_USB_VAL 0x00002000

#define BRCMF_SCAN_VAL 0x00004000

#define BRCMF_CONN_VAL 0x00008000

#define BRCMF_BCDC_VAL 0x00010000

#define BRCMF_SDIO_VAL 0x00020000

#define BRCMF_MSGBUF_VAL 0x00040000

#define BRCMF_PCIE_VAL 0x00080000

#define BRCMF_FWCON_VAL 0x00100000

#define BRCMF_ULP_VAL 0x00200000


eg: To enable wifi fw console log

$ insmod brcmfmac.ko debug=0x00100006 (TRACE, INFO and WIFI_FW_LOG)

eg: To enable Trace

$ insmod brcmfmac.ko debug=0x6 (TRACE and INFO )


For further details on the functions associatied with fmac debug, please look into the source code  @



Wake-on-WLAN with 43455

Posted by VinayakS_26 Moderator Nov 27, 2019



The WOWL(Wake-On-Wlan) is a networking standard wherein a host computer/system can be turned on/awakened by a WLAN networking message. The following blog discusses on the steps to enable the WOWL feature for the WLAN chip.




WOWL feature is currently supported in CYW43455, CYW4356, CYW4354, CYW4373. Although the validation is currently done only for CYW43455, the other chips do have the support in their firmware. Any updates on the WOWL feature support will be listed in the README of each FMAC release in the community.


WoWL feature awakens the host from one of the sleep states of the host ( as mentioned  in the following link: by a network message from a  wireless Access Point (AP).Once the predefined wake condition is met at the Station(STA) side, a GPIO(configured at the sta side) is triggered by the WLAN chip and awaken the host.


Wake conditions


Following are the WoWL wake conditions that needs to be pre-configured in the wireless  Station(STA) device.

  • wake up on disconnect
  • wake up on magic packet
  • wake up on pattern match, up to 8 patterns of 1-128 bytes, maximum packet offset 1500 bytes
  • wake up on GTK rekey failure
  • wake up on network detection, up to 16 match sets

To check the list of supported wowl conditions in your wlan chip, issue for the following command

iw phy <phyname> info

eg : iw phy phy0 info

To see only the wowlan capabilities, issue the following command.

iw phy <phyname> wowlan show

eg: iw phy phy0 wowlan show

  • wake up on disconnect
  • wake up on GTK rekeying failure
  • wake up on EAP identity request
  • wake up on 4-way handshake


GPIO registration


To register the GPIOs that trigger the wakeup of the host, modify the following parameters in the nvram file.

wowl_gpio(Gets triggered on all wakeup events)

wowl_extgpio(Gets triggered with abnormal wakeup cases such as beacon loss/TCPKA failure/disassociation)

wowl_gpiopol(Sets GPIO polarity)




wowl_pol=0 # active low


Configure wowl mode & Packet Filter


Finally a wowl packer filter needs to be configured at the STA side in order to identify the wakeup network message(or packet).

Following wl command is used for wowl wake mode at STA side.

wl wowl <mode>

eg : wl wowl 1 # for magic packet

eg: wl wowl 2 # netpattern

Current bitmap for wowl

#define WL_WOWL_MAGIC (1 << 0)                     /* Wakeup on Magic packet */

#define WL_WOWL_NET (1 << 1)                          /* Wakeup on Netpattern */

#define WL_WOWL_DIS (1 << 2)                           /* Wakeup on loss-of-link due to Disassoc/Deauth */

#define WL_WOWL_BCN (1 << 4)                        /* Wakeup on loss of beacon */

#define WL_WOWL_GTK_FAILURE (1 << 10)      /* enable wakeup if GTK fails */


Following wl command is used to configure the network message pattern.

wl wowl_pattern <add / del / clr> <offset> <mask> <pattern>

each bit in the mask indicate to match one bype of data

eg: wl wowl_pattern add 12 0x3004FF 0x08004500003C1E780000800198E9C0A80105C0A8010A


Command to activate the wowl mode

wl wowl_activate


Example scenario:

FOR Broadcast Magic-Packet:

- STA> wl wowl 1

- STA> wl wowl_activate 1

- AP> wl -i ethx wowl_pkt 102 bcast magic

- STA> wl wowl_wakeind # will show "MAGIC packet received and Broadcast/Mcast frame received"

- STA> wl wowl_wakeind clear

- FOR Broadcast Net-pattern:

- STA> wl wowl 2

- STA> wl wowl_pattern add 12 0x3004FF 0x08004500003C1E780000800198E9C0A80105C0A8010A

- STA> wl wowl_activate 1

- AP> wl -i eth1 wowl_pkt 102 FF:FF:FF:FF:FF:FF net 12 0x08004500003C1E780000800198E9C0A80105C0A8010A

- STA> wl wowl_wakeind. # will show "Packet received with Netpattern and Broadcast/Mcast frame received"

- STA> wl wowl_wakeind clear



Concurrent AP and STA

Posted by VinayakS_26 Moderator Sep 30, 2019



This blog is to demonstrate the setup of Concurrent AP and STA in a linux host(i.MX6 was used for this purpose).



The host should have the following utilities/daemons running:

1. iw (en:users:documentation:iw [Linux Wireless] )

2. wpa_supplicant and wpa_cli (check out this link for more details:Supplicant in Linux )

3. hostapd ( HostApd setup in Linux  )


The wpa_supplicant is used to setup the STA and hostapd is used for setting up the AP.




Steps/ Description
Command /FormatExample /Outputs

To configure the STA:

Configure the wpa_supplicant daemon with the credentials/details of the AP to which your  STA has to connect. For this modify the wpa_suplicant.conf config file.

>>>vi  /etc/wpa_supplicant.conf






ssid=<YourSSID>  #ssid of your AP to which the device has to connect.

psk=<YourPassphrase>  #Password








ssid="yyyyyyyy" #ssid of your AP to which the device has to connect.

psk="xxxxxxxx">  #Password


To configure the AP:

Configure the hostapd daemon with credential/detail of the AP that you want to setup.

>>> vi /etc/hostapd.conf







#above are the major changes to made in the hostapd.conf

#following is a sample hostapd.conf














Kill the wpa_supplicant daemon that is already runnnig

>>>grep -aux | grep wpa_supplicant

>>>killall wpa_supplicant

3092  1.0  0.0   1872   364 pts/2    S+   07:49   0:00 grep wpa_supplicant
Remove the existing interface of supplicant>>>rm -rf /var/run/wpa_supplicant/wlan0
Add a virtual interface to setup the AP>>>iw dev wlan0 interface add wlan1 type __ap
Setup the IP address of the AP>>>ifconfig wlan0

#Sample output

IPv6: ADDRCONF(NETDEV_UP): wlan1: link is not ready

Start the wpa_supplicant with the nl80211 driver>>>wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B &

#Sample output

root@imx6ulevk:/usr/sbin# Successfully initialized wpa_supplicant

rfkill: Cannot open RFKILL control device

rfkill: Cannot get wiphy information

[1]+  Done                 

root@imx6ulevk:/usr/sbin# IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
Enable network and check the status of the connection

>>>wpa_cli -p /var/run/wpa_supplicant -i wlan0 enable_network 0

>>>wpa_cli -p /var/run/wpa_supplicant -i wlan0 status













Start dhcp client to leased out an IP from your dhcp server. If your AP/router supports static, you could setup a static IP as well using ifconfig.>>>udhcpc -i wlan0 up

#Sample  output

root@imx6ulevk:/usr/sbin# udhcpc -i wlan0 up

udhcpc (v1.24.1) started

Sending discover...

Sending select for

Lease of obtained, lease time 86400

/etc/udhcpc.d/50default: Adding DNS

Setup the host AP by calling the hostapd daemon.>>>./hostapd /etc/hostapd.conf -B &

#Sample  output

wlan1: interface state UNINITIALIZED->ENABLED


Running  BlueZ on CY Part

Posted by VinayakS_26 Moderator Jun 30, 2019



The blog is to run BlueZ stack on a linux  host machine to initialize Cypress Bluetooth Controller, which is connected to Ubuntu machine through UART transport. The blog contains the necessary packages to install, the commands to be send to configure the Ubuntu Host




-- CYW920706WCDEVAL Board (recommended to download an empty Application)

-- Linux System/  Linux Machine (preferably Ubuntu)



Setting up the Host Machine


1. Plugging in the board


Plug in the CYW920706WCDEVAL board to the Host Linux Machine(in my case i used a Ubuntu Laptop). Check the dmesg logs to see the device files generated to which the UART transport has bound. In my case, the CYW920706WCDEVAL board had a PUART and HCI UART. Hence, the dmesg displayed two device files.

Eg: dmesg log for enumeration



If the dmesg logs didn't display the device files to which the board had bound, then it could be because the fdti LKM(loadable Kernel Module) was not loaded in the kernel during boot. You could manually add it using the following command.

>>> modprobe ftdi_sio

Check whether the VID and PID parameters of the USB device is getting added to the following file


else add the PID and VID to the file the following location.

>>>echo <vid> <pid>  > /sys/bus/usb-serial/drivers/ftdi_sio/new_id


Replug the device back to the host machine and check the dmesg logs to see bonded device files.

After a reboot, the ftdio_sio LKM might get unloaded. To make the LKM load after every reboot, you could define a rule in the rules.d list.

To find about more about adding rules in the rules.d list , check the following page


2. Setting up BlueZ


Download the necessary packages for Bluez from the link given below and run the following commands. Additional packages  contains utilities to check the status of Bluez Daemon.

BlueZ » Download

>>>tar -xvf bluez-5.??.tar.xz
>>>cd bluez-5.??.tar.xz
>>>make install

Additional packages to download are given here.(if they are missing in your system).

>>>sudo apt-get install libdbus-1-dev libudev-dev libical-dev libreadline-dev bluetooth bluez-tools rfkill rfcomm

Once done with the download, check whether the Bluetooth adapter is unblocked.

>>> rfkill list all
>>> rfkill unblock all

Check the status of the corresponding systemd(system daemon) service:

>>>systemctl status bluetooth.service

The daemon can be reloaded with the following commands:

>>>systemctl daemon-reload
>>>systemctl restart bluetooth

3. HCI UART bring-up


Use hciattach command to attach the serial device via HCI UART to the BlueZ stack.


>>>sudo hciattach  /dev/ttyUSB0 -t 10 any 115200 noflow nosleep


The hciattach utility tries to send a HCI reset to the device via the HCI UART. Check the dmesg logs to see the status of HCI reset. If a reset timeout is happening, do a manual reset of the device while the reset commands are being send to the device by the host machine.

Once successful, you are ready to send the hci command using the hcitool utility.

The following picture shows dmesg logs for hciattach. Here, timeout is happening when host tries to send a HCI reset. This can be resolved by manually resetting the device.


Use the following command to check the hci devices


>>>hcitool dev 


          hci0      5C:AC:4C:F8:1F:80

          hci1      20:70:6A:20:f4:9B

The following diagram shows the commands to send to determine whether the device has been attached to the hci interface generated in the host.

It also gives further details like the BD address and the traffic the is going in the BT device.


For scanning LE devices:

>>> hcitool -i hci1 lescan


LE SCAN initiated in the interface hci1 created for the new device.



HCI command Injection


For sending specific HCI commands, use the following format:

>>>hcitool cmd <ogf> <ocf> [parameters]


eg: Write Local Name Command (ocf :HCI_Write_Local_Name -- 0x0013  & ogf: 0x03 )

For HCI Control and Baseband commands <ogf> is 0x03

(ABCD -- 0x41 0x42 0x43 0x44 )

The following picture show the usage of the hcitool cmd


Filter Blog

By date:
By tag: