Support for WAVE 300 Wi-Fi chip

Thank you. Regarding missing cal_wlan1.bin. I've missed your comment regarding this. But you had exactly same problem and @pc2005 response was it's fine. So I don't worry about it for now.

AFAIK the OpenWrt SDK won't let make any changes to kernel but I think you may get to the point where loading the driver in the router always resulted in a crash (at least for me). The only way to make it work was to enable the Debugging symbols as explained above and for that you'll need to configure the source and checkout the v18.06.4 and flash a firmware built from the custom compiled kernel.

1 Like

Yeah, it just crashed :slight_smile: or rather :(. Going to compile kernel now.

You need to also include libnl within the source although there is no need to include it within the firmware. Just do scripts/feeds update -a ; scripts/feeds install libnl in the source directory before executing make. Not sure if this is still needed but @Mandrake-Lee has this in the Github repo.

This also includes more repositories. Does this mean Intel is finally supporting the drivers?

new ax driver has supported wave500/wave600 and kernel3.10/4.9 and ar9/ar10/grx350/grx550/grx750/puma
and uclibc/musl,luci too(15.05)
new sdk can build openwrt firmware(cc or lede) with close source bins(dirvers and tools)

Hello,

I finally could compile openwrt with those intel source codes, for the moment it works with 18.06.5. I compiled an image for Orange Livebox 2.1 (Lantiq x200) with the following packages:

iwlwav-base-files
kmod-iwlwav-driver-uci
iwlwav-driver-uci
iwlwav-tools
iwlwav-iw
iwlwav-hostap-uci

For the moment the driver is not working.

Regards,

1 Like

iwlwav,i think it is open source and only supports wave500/600

To @Mandrake-Lee and owners of the Orange Livebox 2.1, follow these instructions to get the driver working on your device.

  1. you need to build openwrt from source to enable PCIE MSI which isn't enabled by default in the kernel config. In order to do this add these two lines to the file target/linux/lantiq/xrx200/config-4.14.
CONFIG_PCI_MSI=y
CONFIG_PCIE_LANTIQ_MSI=y

the kernel still would fail to compile untill you apply the next patch.

  1. create the file target/linux/lantiq/patches-4.14/1000-xrx200-pcie-msi-fix.patch and paste the following code in it.
--- a/arch/mips/pci/ifxmips_pcie_msi.c
+++ b/arch/mips/pci/ifxmips_pcie_msi.c
@@ -31,29 +31,17 @@
  \brief PCIe MSI OS interface file
 */
 
-#ifndef AUTOCONF_INCLUDED
-#include <linux/config.h>
-#endif /* AUTOCONF_INCLUDED */
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
 #include <linux/pci.h>
 #include <linux/msi.h>
 #include <linux/module.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/traps.h>
-
-#include <asm/ifx/ifx_types.h>
-#include <asm/ifx/ifx_regs.h>
-#include <asm/ifx/common_routines.h>
-#include <asm/ifx/irq.h>
 
 #include "ifxmips_pcie_reg.h"
 #include "ifxmips_pcie.h"
 
+#include <lantiq_irq.h>
+
 #define IFX_MSI_IRQ_NUM    16
 
 enum {
@@ -176,7 +164,7 @@ arch_setup_msi_irq(struct pci_dev *pdev,
     IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s %s enter\n", __func__, pci_name(pdev));
 
     /* XXX, skip RC MSI itself */
-    if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
+    if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) {
         IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s RC itself doesn't use MSI interrupt\n", __func__);
         return -EINVAL;
     }
@@ -186,7 +174,7 @@ arch_setup_msi_irq(struct pci_dev *pdev,
      * wants.  Most devices only want 1, which will give 
      * configured_private_bits and request_private_bits equal 0. 
      */
-    pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &control);
+    pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &control);
 
     /*
      * If the number of private bits has been configured then use 
@@ -277,9 +265,9 @@ again:
     /* Update the number of IRQs the device has available to it */
     control &= ~PCI_MSI_FLAGS_QSIZE;
     control |= (request_private_bits << 4);
-    pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control);
+    pci_write_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, control);
 
-    set_irq_msi(irq, desc);
+    irq_set_msi_desc(irq, desc);
     msg.address_hi = 0x0;
     msg.address_lo = msi_irqs[pcie_port].msi_phy_base;
     msg.data = SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -50,7 +50,7 @@ obj-$(CONFIG_SOC_MT7620)	+= pci-mt7620.o
 obj-$(CONFIG_SOC_RT288X)	+= pci-rt2880.o
 obj-$(CONFIG_SOC_RT3883)	+= pci-rt3883.o
 obj-$(CONFIG_PCIE_LANTIQ)	+= ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-obj-$(CONFIG_PCIE_LANTIQ_MSI)	+= pcie-lantiq-msi.o
+obj-$(CONFIG_PCIE_LANTIQ_MSI)	+= ifxmips_pcie_msi.o
 obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
 obj-$(CONFIG_TANBAC_TB0226)	+= fixup-tb0226.o
 obj-$(CONFIG_TANBAC_TB0287)	+= fixup-tb0287.o
--- a/arch/mips/pci/ifxmips_pcie_reg.h
+++ b/arch/mips/pci/ifxmips_pcie_reg.h
@@ -989,6 +989,63 @@ enum {
 #define PCIE_PHY_RX1_EI(X)          (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
 #define PCIE_PHY_RX1_A_CTRL(X)      (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
 
+/* MSI PIC */
+#define IFX_MSI_PIC_REG_BASE       (KSEG1 | 0x1F700000)
+#define IFX_MSI1_PIC_REG_BASE      (KSEG1 | 0x1F500000)
+#define IFX_MSI2_PIC_REG_BASE      (KSEG1 | 0x1F700600)
+
+#define IFX_MSI_PIC_BIG_ENDIAN     1
+#define IFX_MSI_PIC_LITTLE_ENDIAN  0
+
+#define IFX_MSI_PCI_INT_DISABLE    0x80000000
+#define IFX_MSI_PIC_INT_LINE       0x30000000
+#define IFX_MSI_PIC_INT_LINE_S     28
+#define IFX_MSI_PIC_MSG_ADDR       0x0FFF0000
+#define IFX_MSI_PIC_MSG_ADDR_S     16
+#define IFX_MSI_PIC_MSG_DATA       0x0000FFFF
+#define IFX_MSI_PIC_MSG_DATA_S     0x0
+
+#define IFX_PCIE_INTA          (INT_NUM_IM4_IRL0 + 8)
+#define IFX_PCIE_INTB          (INT_NUM_IM4_IRL0 + 9)
+#define IFX_PCIE_INTC          (INT_NUM_IM4_IRL0 + 10)
+#define IFX_PCIE_INTD          (INT_NUM_IM4_IRL0 + 11)
+#define IFX_PCIE_IR            (INT_NUM_IM4_IRL0 + 25)
+#define IFX_PCIE_WAKE          (INT_NUM_IM4_IRL0 + 26)
+#define IFX_PCIE_MSI_IR0       (INT_NUM_IM4_IRL0 + 27)
+#define IFX_PCIE_MSI_IR1       (INT_NUM_IM4_IRL0 + 28)
+#define IFX_PCIE_MSI_IR2       (INT_NUM_IM4_IRL0 + 29)
+#define IFX_PCIE_MSI_IR3       (INT_NUM_IM0_IRL0 + 30)
+#define IFX_PCIE_L3_INT        (INT_NUM_IM3_IRL0 + 16)
+
+#define IFX_PCIE1_INTA         (INT_NUM_IM0_IRL0 + 9)
+#define IFX_PCIE1_INTB         (INT_NUM_IM0_IRL0 + 10)
+#define IFX_PCIE1_INTC         (INT_NUM_IM0_IRL0 + 11)
+#define IFX_PCIE1_INTD         (INT_NUM_IM0_IRL0 + 12)
+#define IFX_PCIE1_IR           (INT_NUM_IM1_IRL0 + 17)
+#define IFX_PCIE1_WAKE         (INT_NUM_IM1_IRL0 + 18)
+#define IFX_PCIE1_MSI_IR0      (INT_NUM_IM1_IRL0 + 9)
+#define IFX_PCIE1_MSI_IR1      (INT_NUM_IM1_IRL0 + 10)
+#define IFX_PCIE1_MSI_IR2      (INT_NUM_IM1_IRL0 + 11)
+#define IFX_PCIE1_MSI_IR3      (INT_NUM_IM1_IRL0 + 12)
+#define IFX_PCIE1_L3_INT       (INT_NUM_IM1_IRL0 + 13)
+
+#define IFX_PCIE2_INTA         (INT_NUM_IM0_IRL0 + 19)
+#define IFX_PCIE2_INTB         (INT_NUM_IM1_IRL0 + 31)
+#define IFX_PCIE2_INTC         (INT_NUM_IM2_IRL0 + 17)
+#define IFX_PCIE2_INTD         (INT_NUM_IM2_IRL0 + 18)
+#define IFX_PCIE2_IR           (INT_NUM_IM1_IRL0 + 21)
+#define IFX_PCIE2_WAKE         (INT_NUM_IM1_IRL0 + 23)
+#define IFX_PCIE2_MSI_IR0      (INT_NUM_IM2_IRL0 + 12)
+#define IFX_PCIE2_MSI_IR1      (INT_NUM_IM2_IRL0 + 13)
+#define IFX_PCIE2_MSI_IR2      (INT_NUM_IM2_IRL0 + 14)
+#define IFX_PCIE2_MSI_IR3      (INT_NUM_IM2_IRL0 + 15)
+#define IFX_PCIE2_L3_INT       (INT_NUM_IM2_IRL0 + 30)
+
+#define INT_NUM_IM4_IRL31      (INT_NUM_IM4_IRL0 + 31)
+
+#define MS(_v, _f)  (((_v) & (_f)) >> _f##_S)
+#define SM(_v, _f)  (((_v) << _f##_S) & (_f))
+
 /* Interrupt related stuff */
 #define PCIE_LEGACY_DISABLE 0
 #define PCIE_LEGACY_INTA  1
  1. you also need to set pcie-reset = <&gpio 21 GPIO_ACTIVE_HIGH>; in the dts file target/linux/lantiq/files-4.14/arch/mips/boot/dts/ARV7519RW22.dts under the &pcie0 block. it should look like
&pcie0 {
        status = "okay";
        gpio-reset = <&gpio 21 GPIO_ACTIVE_HIGH>;
        pcie-reset = <&gpio 21 GPIO_ACTIVE_HIGH>;
};
  1. compile openwrt and flash it to your device.

  2. compile the wave300 driver with these options enabled.

    • PCI Express bus
    • Use interrupt polling
  3. insert the driver with insmod and your wifi card should appear as wlan0.

Peace.

Could you explain this point a bit more? I don't know how to compile this driver, where are the sources?

Thank you so much!

ahmar20/wave300-dev: Does not compile because drv_shared.h is missed.

vittorio88/wave300:
After some changes timer_setup() etc it will compile, but it ends up with:

make[8]: Leaving directory `/opt/build/openwrt-sdk-lantiq-xrx200_gcc-7.4.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-lantiq_xrx200/linux-4.14.128'
#/opt/build/openwrt-sdk-lantiq-xrx200_gcc-7.4.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/bin/mips-openwrt-linux-strip: illegal pathname found in archive member: /opt/build/openwrt-sdk-lantiq-xrx200_gcc-7.4.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-lantiq_xrx200/wave300-83a915e/driver/builds/ugw5.1-vrx288/wireless/driver/rflib/linux/tools/rtlogger/shared/logmacro_database.o
#make[7]: *** [mtlk_rflib.a] Error 11

What is the right/best way to compile and use the driver ?

There have been some changes to the linux kernel in the meanwhile since I successfully built the driver from @pc2005 sources. I remember building it with v18.06.2 so maybe you can try that. It took him a great deal of time to make the driver useable at some level but still the driver needs a lot of work to be able to integrate properly with OpenWrt.

Hello Suleiman,

Is this patch needed for the 4.9.xxx kernel version also? I suppose that your instructions are for the latest openwrt version V19.07.1, does it mean the driver works fine for this version?

Thanks,

Hello ahmar16,

I have read the whole topic, thanks for the great work done along with others. Just to confirm the driver works but no encryption right?

Thanks,

Yes the driver works without any encryption. This is because the WiFi is visible in LuCI after it gets initiated and you can only assign it to a network such as LAN but there is no entry for the WiFi in Wireless config so that is why no changes can be done after initialization and hence no encryption.

did you try to manually write a /etc/config/wireless file? From my understanding this file is automatically generated by the driver which for now is still not properly integrated with OpenWrt

Yes I tried editing the wireless config but it didn't help because it needs some specific parameters that I don't know. So if someone would need to implement the config, they need to know those parameters to configure it.

Could you share speed of upload/download on 19.07.1?

I remember that there was an option, to allow wifi interface to be bridged to br-lan:
iwpriv wlan0 sBridgeMode=1

@ahmar16 a script is needed to link /etc/config/wireless with wave300 driver, example can be found here: https://sourceforge.net/p/netiaspotwrt/trunk/38541/tree//branches/attitude_adjustment/target/linux/lantiq/base-files/lib/wifi/mtlk.sh , but it worked on OpenWRT 12.09 - not sure if any modifications are needed to 19.07.

To be clear I'm not using WAVE300 driver at the moment. To compile the driver I'll need OpenWrt source and atm my laptop is not in a good shape to go for that.

I'll need a couple of weeks to get a new HDD for my laptop and then I'll possibly check the script myself. If I remember correctly, the WiFi speeds may have been provided above in the topic somewhere but they also were implemented with another set of patches from @pc2005.