Question about corss-compiling morse driver

Hi,

I was trying to cross compile the morse_driver with the OpenWrt kernel and toolchain. I first cloned the openwrt repo from github and checked out the mm/v23.05.3 branch. I was able to build the openwrt image, and I could see the kernel files and toolchain files created. I then cloned the morse_driver repo and tried to build it using the following commands:

cd morse_driver
export ARCH=mips
export CROSS_COMPILE=$HOME/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-12.3.0_musl/bin/mipsel-openwrt-linux-musl-
export KERNEL_SRC=$HOME/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-5.15.150
make MORSE_TRACE_PATH=$(pwd) \
     CONFIG_WLAN_VENDOR_MORSE=m \
     CONFIG_MORSE_SDIO=y \
     CONFIG_MORSE_USER_ACCESS=y

The problem was, I got the following error messages toward the end of the build:

mipsel-openwrt-linux-musl-gcc: warning: environment variable 'STAGING_DIR' not defined
  LD [M]  /home/uu/morse_driver/morse.o
  MODPOST /home/uu/morse_driver/Module.symvers
ERROR: modpost: "ieee80211_channel_to_freq_khz" [/home/uu/morse_driver/dot11ah/dot11ah.ko] undefined!
ERROR: modpost: "ieee80211_freq_khz_to_channel" [/home/uu/morse_driver/dot11ah/dot11ah.ko] undefined!
ERROR: modpost: "ieee80211_operating_class_to_band" [/home/uu/morse_driver/dot11ah/dot11ah.ko] undefined!
ERROR: modpost: "cfg80211_find_elem_match" [/home/uu/morse_driver/dot11ah/dot11ah.ko] undefined!
ERROR: modpost: "ieee80211_chandef_to_operating_class" [/home/uu/morse_driver/dot11ah/dot11ah.ko] undefined!
ERROR: modpost: "ieee80211_rx_irqsafe" [/home/uu/morse_driver/morse.ko] undefined!
ERROR: modpost: "ieee80211_csa_finish" [/home/uu/morse_driver/morse.ko] undefined!
ERROR: modpost: "regulatory_set_wiphy_regd" [/home/uu/morse_driver/morse.ko] undefined!
ERROR: modpost: "ieee80211_return_txq" [/home/uu/morse_driver/morse.ko] undefined!
ERROR: modpost: "ieee80211_hdrlen" [/home/uu/morse_driver/morse.ko] undefined!
WARNING: modpost: suppressed 47 unresolved symbol warnings because there were too many)
make[2]: *** [scripts/Makefile.modpost:133: /home/uu/morse_driver/Module.symvers] Error 1
make[2]: *** Deleting file '/home/uu/morse_driver/Module.symvers'
make[1]: *** [Makefile:1827: modules] Error 2
make[1]: Leaving directory '/home/uu/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-5.15.150'
make: *** [Makefile:151: all] Error 2

I am wondering if there is anything I did wrong?

1 Like

Hey @HaiSymxAI

What has likely happened here is the kernel you’re targeting hasn’t compiled mac80211.
This is expected, because the Linux kernel built by OpenWrt does exactly this! It disables mac80211 in the kernel, but compiles it out-of-tree from the backports package.

If you had encountered this whilst building Linux from scratch, then I would recommend you would resolve this by pointing the driver to the following include paths to correctly include the mac80211 symbols.

	-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
	-I$(STAGING_DIR)/usr/include/mac80211-backport \
	-I$(STAGING_DIR)/usr/include/mac80211/uapi \
	-I$(STAGING_DIR)/usr/include/mac80211 \
	-include backport/autoconf.h \
	-include backport/backport.h

However, as you are using the OpenWrt buildsystem you should instead be using the build system to compile the driver. The Morse OpenWrt distribution includes an additional feed to add a number of recipes to handle compiling other packages - like the Morse driver.

Which image did you compile? If it’s for one of our evaluation kits, it’s possible the morse driver has already been compiled! If it’s for a different board, you will be able to select the morse driver in make menuconfig before building your image.

Thank you for the reply! It is very helpful!

I was trying to compile the OpenWrt 23.05 to run on the Habanero DVK router board. The plan is to integrate the halow module to the Habanero through SPI. I did see the morse driver option in the menuconfig, and it is also possible to select the SPI option from there. My first question is, do we need to configure the SPI in the menuconfig as well? There are two SPI interfaces on the Habanero, and how does the driver know which SPI to use?

My second question is related to the recipes used by the Morse OpenWrt to compile the Morse driver. Is there a way to port this recipe to work on other OpenWrt distributions? I think it will be useful when we need to build the latest OpenWrt along with the Morse driver.

Thanks a lot!

No problem!

Unlike bus protocols like SDIO or USB, SPI devices don’t register device IDs to the subsystems to load device drivers on detection/hotplug etc.

Instead, you will need to define a child node under the SPI bus node in the relevant device tree file.

Not sure how much you know about device tree files. But for the benefit of others who may be reading this thread I’ll give some pointers in what you might need to do for this particular kit.


The habanero DVK dts file is located at target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-habanero-dvk.dts. This directly refers to a device tree include file located in the linux kernel source - arch/arm/boot/dts/qcom-ipq4019.dtsi. You can find the kernel source in the build directory.

From what I can see, you will need to make a few changes to the top level device tree file - qcom-ipq4019-habanero-dvk.dts:

  1. Add nodes to the pinctrl device to configure desired pins for the second SPI interface on the SoC. You’ll also want to configure gpios here relevant for the MM chip as well.
    Note that in this example, I am guessing the function and have made up pin numbers as I do not have a board available in front of me. If you have debugfs enabled, you can sometimes see this information in debugfs. It will be a path similar to cat /sys/kernel/debug/pinctrl/pinctrl-<driver>/pingroups
&tlmm {
	spi_1_pins: spi_1_pinmux {
		pinmux {
			function = "blsp_spi1";
			pins = "gpio41", "gpio42", "gpio43";
			drive-strength = <12>;
			bias-disable;
		};

		pinmux_cs {
			function = "gpio";
			pins = "gpio44";
			drive-strength = <2>;
			bias-disable;
			output-high;
		};
	};
	mm6108_pins: mm6108_pinmux {
		mux {
			function = "gpio";
			pins = "gpio45", "gpio46", "gpio47", "gpio48";
			bias-disable;
		};
	};

}
  1. Add a node for the second spi interface itself to enable it, and configure it to use the pins configured above.
  2. Add a child node for MM6108 to allow the driver to correctly probe and communicate with the chip. This will include some more gpio configuration for reset and powersave gpios.
&blsp1_spi2 {
   		 pinctrl-0 = <&spi1_pins &spi1_cs_pins>;
   		 pinctrl-names = "default";
   		 cs-gpios = <&gpio 44 1>;
   		 #address-cells = <1>;
   		 #size-cells = <0>;
   		 status = "okay";

   		 mm6108: mm6108@0 {
   			 pinctrl-0 = <&mm6108_pins>;
   			 pinctrl-names = "default";
   			 compatible = "morse,mm610x-spi";
   			 reg = <0>;    /* CE0 */
   			 reset-gpios = <&gpio 45 0>;
   			 power-gpios = <&gpio 46 0>,
   			           	<&gpio 47 0>;
   			 spi-irq-gpios = <&gpio 48 0>;
   			 spi-max-frequency = <50000000>;
   			 status = "okay";
   		 };
   	 };

There may be additional things to configure here which I have left out, as I don’t have familiarity with this chipset, and do not have a board available to test what I have given you! But happy to help you dig into it!

Let me know how you go!


In theory, you would be able to modify the feeds.conf.default file of an existing OpenWrt distribution to add the Morse Micro recipes to an existing distribution. Unfortunately there are a couple of instances where we have had to modify the core OpenWrt tree to add patches for development kits as there isn’t a clean way for us to add boards “out-of-tree”. This will include some kernel patches and patches to some core components.

As part of our Open Sourcing effort, we’ve intentionally released the commits of our OpenWrt tree with messages clearly explaining “why” a change was made. This should help serve as documentation so you can reflect similar changes to other trees if you require them. Most of the changes are to support custom board configuration management scripts - so shouldn’t be required to include in your own fork.

We’re actively working on cleaning up this integration experience!

1 Like

Thank you! Now I know where to start to modify the device tree for the Habanero. I also noticed from the form that the ekh01 can be configured to use either SPI or SDIO to communicate the HaLow module. Could you provide some examples of configuring ekh01 device tree to work with SPI?

OpenWrt creates device tree files in different places for different targets depending on how well supported that board is in the Linux kernel. In the case of the raspberry pis, the patches openwrt bring along for the kernel come from the raspberry pi linux tree.

This includes the RPi 4b device tree fragments. Instead of having a clear, modified dts file, there are simply patch files which apply device tree fragments to be compiled and loaded by the bootloader. For the SPI device node, see target/linux/bcm27xx/patches-5.15/991-0003-dt-overlays-morse-add-spi-overlay-fragment.patch

The bootloader is then configured (in /boot/config.txt) to load the fragment on kernel boot to enable the SPI device node.

I hope this made sense!