TransWikia.com

How to set up the Edimax EW-7611ULB combo Bluetooth WIFI dongle

Raspberry Pi Asked by Ken H on December 14, 2021

Although, this dongle works (for awhile), there is a problem with the bluetooth driver. After streaming for about an hour, the driver eats up all the Pi memory and the Pi stops responding. Power cycling is the only fix. This may be related to the flood of messages it puts out on dmesg. I tried clearing dmesg, but that does not recover the lost memory. You can watch the memory slowly decrease by running htop while streaming to a bluetooth speaker. I think the memory problem is with the bluetooth driver, because the problem does not occur when using a different bluetooth dongle.

Maybe someone with driver coding experience could find a solution. Please post any ideas you might have regarding the memory problem.

#the bluetooth driver floods dmesg with about 10 messages per second...
dmesg|tail
[  329.685269] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  329.765265] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 37
[  330.725279] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  330.805278] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 38
[  331.765273] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  331.845278] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 37
[  332.805301] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  332.885305] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 38
[  333.845301] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  333.925309] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 37

Steps to compile the bluetooth and wifi drivers for EDIMAX EW-7611ULB on Raspberry Pi

The compile process:

First, install the headers for your OS

sudo apt-get install raspberrypi-kernel-headers

— the system is now ready to compile —

BLUETOOTH DRIVER

#get bluetooth driver from the Edimax site
wget http://www.edimax.us/download/drivers/EW-7611ULB/EW-7611ULB_Bluetooth_driver.zip
unzip EW-7611ULB_Bluetooth_driver.zip
cd EW-7611ULB_Bluetooth_driver
cd Linux_BT_USB_v3.1_20150526_8723BU_BTCOEX_20150119-5844_Edimax

Fix source file so will compile with >= 4.9.x kernels

In Section "(II.) Bluetooth Driver Installation", before running
"sudo make install -s", you need to edit the file
bluetooth_usb_driver/rtk_coex.c
At line 448, change:

#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
#if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
    bt_cb(skb)->req.start = true;
#else
    bt_cb(skb)->hci.req_start = true;
#endif
#endif

to:

#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
#if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
    bt_cb(skb)->req.start = true;
#elif HCI_VERSION_CODE >= KERNEL_VERSION(4,9,0)
    bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
#else
    bt_cb(skb)->hci.req_start = true;
#endif
#endif

Fix the Makefile

change depmod line to in TWO places, BOTH the install and uninstall sections:

depmod -a -v                                           

Compile and install the driver

sudo make install -s
sudo reboot

This completes the bluetooth driver install. If you want, you can test by connecting something using bluetoothctl. Read the Bluetooth driver info below to prevent your logfiles from filling up.

If you later want to use a different Bluetooth dongle, you’ll need to revert to the stock Bluetooth driver as follows:

cd EW-7611ULB_Bluetooth_driver
cd Linux_BT_USB_v3.1_20150526_8723BU_BTCOEX_20150119-5844_Edimax
sudo make uninstall -s
sudo reboot

WIFI DRIVER

sudo apt update
#get the wifi driver
sudo apt install git
git clone https://github.com/lwfinger/rtl8723bu.git

####   optional    ###################################################
#if you don't want TWO wlan devices (wlan0 and wlan1) in ifconfig    #
#disable concurrent mode, by commenting out the line in the Makefile #
#cd rtl8723bu                                                        #
#nano Makefile                                                       #
#(put # in front of this line):                                      #
#EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE                            #
######################################################################

#make the driver
sudo make
sudo make install
sudo modprobe -v 8723bu
#This driver cannot work with the standard driver rtl8xxxu
#so create 50-rtl8xxxu.conf with one line: 
blacklist rtl8xxxu
sudo nano /etc/modprobe.d/50-rtl8xxxu.conf 

This completes the WIFI driver install

Bluetooth Driver Info

The bluetooth driver floods the message log with some info,
so to prevent it overloading your logfile, edit /etc/rsyslog.conf
and add the following line to discard those messages:

:msg, contains, "rtk_btcoex"    ~

Log file example snip shown below:

…snip from /etc/rsyslog.conf…………………….

###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*         /var/log/auth.log
:msg, contains, "rtk_btcoex"    ~
*.*;auth,authpriv.none      -/var/log/syslog
#cron.*             /var/log/cron.log
daemon.*            -/var/log/daemon.log
kern.*              -/var/log/kern.log
lpr.*               -/var/log/lpr.log
mail.*              -/var/log/mail.log
user.*              -/var/log/user.log
#kern.info           -/var/log/kern.info

…snip………………………………………..

One Answer

i bought the EW-7611ULB wifi & bluetooth dongle. but bluetooth fails to work on my Ubuntu 16.04. i just modified the "EW-7611ULB_Linux_Bluetooth_Driver_1.0.0.9" bluetooth driver to work on my Ubuntu 16.04.02 LTS with the following kernel version -

Linux xxx 4.16.0 #1 SMP Wed Sep 5 18:09:34 CST 2018 x86_64 x86_64 x86_64 GNU/Linux

I did not do any fine tune, just make it functional on my system. use at your risk.

EW-7611ULB_Linux_Bluetooth_Driver_1.0.0.9.patch

diff -Naur bluetooth_usb_driver/rtk_bt.c bluetooth_usb_driver_new/rtk_bt.c
--- bluetooth_usb_driver/rtk_bt.c   2018-09-04 17:51:50.000000000 +0800
+++ bluetooth_usb_driver_new/rtk_bt.c   2019-10-27 10:49:47.840823000 +0800
@@ -2093,7 +2093,7 @@

    if (config_len != filelen - BT_CONFIG_HDRLEN) {
        RTKBT_ERR("config length %d is not right %d", config_len,
-             filelen - BT_CONFIG_HDRLEN);
+             filelen - (int)BT_CONFIG_HDRLEN);
        return 0;
    }

@@ -2287,6 +2287,7 @@
 static int request_bdaddr(u8 *buf)
 {
    int size;
+   loff_t pos=0;
    int rc;
    struct file *file;
    u8 tbuf[BDADDR_STRING_LEN + 1];
@@ -2310,7 +2311,11 @@
        size = BDADDR_STRING_LEN;

    memset(tbuf, 0, sizeof(tbuf));
+#if 0
    rc = kernel_read(file, 0, tbuf, size);
+#else
+   rc = kernel_read(file, tbuf, size, &pos);
+#endif
    fput(file);
    if (rc != size) {
        if (rc >= 0)
diff -Naur bluetooth_usb_driver/rtk_bt.h bluetooth_usb_driver_new/rtk_bt.h
--- bluetooth_usb_driver/rtk_bt.h   2017-12-28 21:22:28.000000000 +0800
+++ bluetooth_usb_driver_new/rtk_bt.h   2019-10-27 10:53:06.151664000 +0800
@@ -43,12 +43,14 @@

 #define BTCOEX

-#if 1
+#if 0
 #define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "n" , ## arg)
 #define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "n" , ## arg)
 #define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btusb: " fmt "n", ## arg)
 #else
 #define RTKBT_DBG(fmt, arg...)
+#define RTKBT_INFO(fmt, arg...)
+#define RTKBT_WARN(fmt, arg...)
 #endif

 #if 1
diff -Naur bluetooth_usb_driver/rtk_coex.c bluetooth_usb_driver_new/rtk_coex.c
--- bluetooth_usb_driver/rtk_coex.c 2017-12-28 21:22:28.000000000 +0800
+++ bluetooth_usb_driver_new/rtk_coex.c 2019-10-27 10:52:46.379780000 +0800
@@ -33,10 +33,21 @@

 #define RTK_VERSION "1.2"

+#if 0
 #define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "n" , ## arg)
 #define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "n" , ## arg)
 #define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "n", ## arg)
+#else
+#define RTKBT_DBG(fmt, arg...)
+#define RTKBT_INFO(fmt, arg...)
+#define RTKBT_WARN(fmt, arg...)
+#endif
+
+#if 1
 #define RTKBT_ERR(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "n", ## arg)
+#else
+#define RTKBT_ERR(fmt, arg...)
+#endif

 static struct rtl_coex_struct btrtl_coex;

@@ -44,9 +55,16 @@
 #define is_profile_busy(profile)        ((btrtl_coex.profile_status & BIT(profile)) > 0)

 static void rtk_handle_event_from_wifi(uint8_t * msg);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_a2dp_packet_timeout(unsigned long data);
 static void count_pan_packet_timeout(unsigned long data);
 static void count_hogp_packet_timeout(unsigned long data);
+#else
+static void count_a2dp_packet_timeout(struct timer_list *t);
+static void count_pan_packet_timeout(struct timer_list *t);
+static void count_hogp_packet_timeout(struct timer_list *t);
+#endif

 static int rtl_alloc_buff(struct rtl_coex_struct *coex)
 {
@@ -541,8 +559,12 @@
 {
    if (profile_index == profile_a2dp) {
        btrtl_coex.a2dp_packet_count = 0;
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
        setup_timer(&(btrtl_coex.a2dp_count_timer),
                count_a2dp_packet_timeout, 0);
+   #else
+       timer_setup(&(btrtl_coex.a2dp_count_timer), count_a2dp_packet_timeout, 0);
+   #endif 
        btrtl_coex.a2dp_count_timer.expires =
            jiffies + msecs_to_jiffies(1000);
        add_timer(&(btrtl_coex.a2dp_count_timer));
@@ -550,8 +572,12 @@

    if (profile_index == profile_pan) {
        btrtl_coex.pan_packet_count = 0;
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
        setup_timer(&(btrtl_coex.pan_count_timer),
                count_pan_packet_timeout, 0);
+   #else
+       timer_setup(&(btrtl_coex.pan_count_timer), count_pan_packet_timeout, 0);
+   #endif
        btrtl_coex.pan_count_timer.expires =
            jiffies + msecs_to_jiffies(1000);
        add_timer(&(btrtl_coex.pan_count_timer));
@@ -563,8 +589,13 @@
            && (0 == btrtl_coex.profile_refcount[profile_voice])) {
            btrtl_coex.hogp_packet_count = 0;
            btrtl_coex.voice_packet_count = 0;
+       #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
            setup_timer(&(btrtl_coex.hogp_count_timer),
                    count_hogp_packet_timeout, 0);
+       #else
+           timer_setup(&(btrtl_coex.hogp_count_timer),
+                   count_hogp_packet_timeout, 0);
+       #endif 
            btrtl_coex.hogp_count_timer.expires =
                jiffies + msecs_to_jiffies(1000);
            add_timer(&(btrtl_coex.hogp_count_timer));
@@ -954,7 +985,11 @@
    }
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_a2dp_packet_timeout(unsigned long data)
+#else
+static void count_a2dp_packet_timeout(struct timer_list *t)
+#endif
 {
    RTKBT_DBG("%s: a2dp_packet_count %d", __func__,
            btrtl_coex.a2dp_packet_count);
@@ -971,7 +1006,11 @@
          jiffies + msecs_to_jiffies(1000));
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_pan_packet_timeout(unsigned long data)
+#else
+static void count_pan_packet_timeout(struct timer_list *t)
+#endif
 {
    RTKBT_DBG("%s: pan_packet_count %d", __func__,
            btrtl_coex.pan_packet_count);
@@ -991,7 +1030,11 @@
          jiffies + msecs_to_jiffies(1000));
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_hogp_packet_timeout(unsigned long data)
+#else
+static void count_hogp_packet_timeout(struct timer_list *t)
+#endif
 {
    RTKBT_DBG("%s: hogp_packet_count %d", __func__,
            btrtl_coex.hogp_packet_count);
@@ -2299,7 +2342,11 @@
    //}
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void polling_bt_info(unsigned long data)
+#else
+static void polling_bt_info(struct timer_list *data)
+#endif
 {
    uint8_t temp_cmd[1];
    RTKBT_DBG("polling timer");
@@ -2325,7 +2372,11 @@

    if (ctl->polling_enable && !btrtl_coex.polling_enable) {
        /* setup polling timer for getting bt info from firmware */
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
        setup_timer(&(btrtl_coex.polling_timer), polling_bt_info, 0);
+   #else
+       timer_setup(&(btrtl_coex.polling_timer), polling_bt_info, 0);       
+   #endif
        btrtl_coex.polling_timer.expires =
            jiffies + msecs_to_jiffies(ctl->polling_time * 1000);
        add_timer(&(btrtl_coex.polling_timer));
@@ -2541,11 +2592,12 @@
              (void *)udpsocket_recv_data);
    INIT_DELAYED_WORK(&btrtl_coex.l2_work, (void *)rtl_l2_work);

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
    init_timer(&btrtl_coex.polling_timer);
    init_timer(&btrtl_coex.a2dp_count_timer);
    init_timer(&btrtl_coex.pan_count_timer);
    init_timer(&btrtl_coex.hogp_count_timer);
-
+#endif
    btrtl_coex.hdev = hdev;
    btrtl_coex.wifi_on = 0;

=======================================

Answered by Eric Wu on December 14, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP