Bluetooth/3G problems on the Thinkpad X121e

I just recently bought a lenovo X121e laptop. Its a small laptop, but the battery life is great!

I installed Ubuntu Gnome 16.10 on it, and didn’t really notice anything wrong for awhile, because I rarely use bluetooth on my laptop. But I wanted to test the 3G capabilities of the machine, and that is when I fell down the rabbit hole 🙂Mobile Broadband Disabled Ubuntu Gnome

So even though I tried enabling the mobile broadband, wwan, 3g, (call it what you like) it just didn’t work.

First thing I tried:

rfkill unblock all

rfkill list

but still I got this:

Reading up on this, it seems others have encountered this problem. The “fix” is upgrading the BIOS to the latest version, then resetting to default values, which will clear the wwan and bluetooth on/off state. Unfortunately if you are using UEFI like me, this will also wipe your boot entries 🙂 While this can be fixed quite easily, the problem is this fix is only temporal. Reboot with low battery and in will get hard-locked again.

This whole problem seems to come from the hotkey utility which is implemented on windows, and controls the state of the “hard locks”. Now these seem to default to locked or something.

Installing windows, and booting into it to “enabled WWAN” all the time, is not a solution for me. Resetting the BIOS and re-enabling my EFI bootloader every few reboots also does not cut it.

I’ve used up all my google skills, and it seems like there is no proper solution. So this means its time to start reverse engineering the hotkey tool, and trying to write something which will implement this functionality on linux. 🙂

There is a long road ahead, but I will keep updating this post as I make progress.


Day 1. Searching far and wide:

Source 1:

Lenovo Hotkey tool on Windows ——– Technical information

The command line control for Wireless switching hot key (Fn+F5) feature. It is available to control the wireless radio using the following command;     C:\Program Files\Lenovo\HOTKEY\TpFnF5.exe [PARAMETER]
The following parameters are defined;
/WLON, /WLOFF Turn on/off internal 802.11.
/BTON, /BTOFF Turn on/off internal bluetooth.
/WANON, /WANOFF Turn on/off internal WAN.
/UWBON, /UWBOFF Turn on/off internal UWB.
/ALLON, /ALLOFF Turn on/off any radio at once.


Day 2. Switching from Ubuntu Gnome to default Ubuntu setup:

So this day 2 is actually quite a few days later, I removed the Ubuntu Gnome from my system because it was too buggy for me to use, even though I love the design. Installing in on my system, I reset my bios, and tested out the 3G which did not work on Ubuntu Gnome, and what a suprise! It worked on Ubuntu, because they use a different network manager. So with this happy news, and some freetime on my hands having finished with my exams, I decided to take the plunge and do some more work finding out the source of this problem. So again, every time the bios gets reset things start working again, but then if you remove the battery or the battery level drops down to 0% the 3G and bluetooth will get hardblocked. So with this info I got to work and starting looking into the ACPI modules on the system. I had a thought that the state of these switches must be stored in the BIOS, and might just be exported to the user via UEFI variables. I took a “snapshot” of all the UEFI variables when bluetooth was working, I then removed my battery and took another “snapshot” of the variables to see what had changed. Two entries were different. I had my hopes up, thinking these must hold the values, but then I reset the bios, took another snapshot, and along with lots of other values, these had changed again, and not back to the same values as the first snapshot, but again something completely different. 🙁 So too bad, this will not solve my problems.


At this point I got quite disappointed as I had spent quite a bit of time fixing my system as it would not start after I took my battery out, had to do an fsck -y on it, to fix the system, as it kept complaining about not being able to connect to lvmtad (I use lvm). But, no time to stop, so I took a look at the thinkpad_acpi kernel module in the linux kernel source (drivers/platform/x86/thinkpad_acpi.c) From this, and also later using modinfo thinkpad_acpi command I got some usefull info about the kernel module. It gives you a list of all the parameters you can specify to customise the way that the kernel module works. Now the cool thing is that this kernel module has a switch emulation, which basically doesn’t really care what the bios says, it will emulate the switch to whatever you specify. If we tell it to be on, it will be on. So if we go to /etc/modprobe.d/folder, where the conf files are located for the various kernel modules that our system uses, we can add a file called thinkpad_acpi.confand inside it, we add the following command:

options thinkpad_acpi dbg_bluetoothemul=1 bluetooth_state=1

And here if we reboot our system, when the kernel module gets loaded it will use these parameters.

After booting up the system try doing this: dmesg | grep thinkpad_acpiwe can see the debug output of the kernel module when it is loaded. Mine says: ThinkPad ACPI Extras v0.25 and then some model info etc. And if you followed the instructions correctly you will see a line saying: bluetooth switch emulation enabled Try running rfkill listyou will now actually see 2 bluetooth devices, one by the name of hci0 and another one called tpacpi_bluetooth_sw. Try turning on your system bluetooth 🙂 Magic…

The sad part though, is even though the module has switch emulation for not just bluetooth, but WWAN, WLAN, UWB, etc. It won’t work on the 3G modem (WWAN). Even if you enable the switch, it won’t connect to my mobile network 🙁 So I still have not found a perfect fix, but atleast now bluetooth is working.

What I do now, is carry a usb drive around with my with Refind Linux. This way, if the 3G / Bluetooth stops working, I just reset the BIOS, and boot up from the USB drive, which will find my ubuntu installed on my laptop. Then all I have to type is apt install --reinstall grub-efi-amd64and the uefi boot option is back in place. The whole process takes less than a minute, so its not a huge deal, and much better than having a windows installed just for doing this.

But, this is still not the best solution, so if I have some more time, I’ll try to look more into the source of the kernel module, and see if I can debug why the switch emulation is not working. But for now, this is the best I can do, hope it helps you guys!

  7 comments for “Bluetooth/3G problems on the Thinkpad X121e

  1. Felix Lohmeier
    December 12, 2016 at 23:50

    It’s time for Day 2! 🙂 Any progess?

    I have switched from dual boot to linux-only half a year ago and today it happened again… and no windows left to solve the hard-blocked bluetooth.

    [23:41 felix ~]$ rfkill list
    0: tpacpi_bluetooth_sw: Bluetooth
    Soft blocked: no
    Hard blocked: yes

    • halftome
      December 12, 2016 at 23:52

      Yes, Day 2 has a solution for bluetooth, but not for WWAN unfortunately.

  2. Felix Lohmeier
    December 13, 2016 at 01:25

    Thanks a lot for the fast reply! Sadly, the modprobe.d solution does not work on my machine (4.8.12-200.fc24.x86_64 on x121e).

    [01:21 felix ~]$ dmesg | grep thinkpad_acpi
    [ 211.328872] thinkpad_acpi: unknown parameter ‘dbg_bluetoothemul’ ignored
    [ 211.328877] thinkpad_acpi: unknown parameter ‘bluetooth_state’ ignored
    [ 211.329304] thinkpad_acpi: ThinkPad ACPI Extras v0.25
    [ 211.329306] thinkpad_acpi:
    [ 211.329307] thinkpad_acpi: ThinkPad BIOS 8QET58WW (1.19 ), EC unknown
    [ 211.329308] thinkpad_acpi: Lenovo ThinkPad X121e, model 3045CTO
    [ 211.334093] thinkpad_acpi: radio switch found; radios are disabled

    • halftome
      December 13, 2016 at 12:12

      strange… Can you do a modinfo thinkpad_acpi command? It should list the parameters that are allowed. Maybe the parameter name is different on yours (although it shouldn’t be…)
      Mine outputs:

      halftome@x /> modinfo thinkpad_acpi
      filename: /lib/modules/4.8.0-30-generic/kernel/drivers/platform/x86/thinkpad_acpi.ko
      license: GPL
      version: 0.25
      description: ThinkPad ACPI Extras
      author: Henrique de Moraes Holschuh
      author: Borislav Deianov
      alias: dmi:bvnIBM:bvrI[MU]ET??WW*
      alias: tpacpi
      srcversion: B0D02D12F963B9677AED375
      alias: acpi*:LEN0068:*
      alias: acpi*:IBM0068:*
      depends: nvram,snd,video
      intree: Y
      vermagic: 4.8.0-30-generic SMP mod_unload modversions
      parm: experimental:Enables experimental features when non-zero (int)
      parm: debug:Sets debug level bit-mask (uint)
      parm: force_load:Attempts to load the driver even on a mis-identified ThinkPad when true (bool)
      parm: fan_control:Enables setting fan parameters features when true (bool)
      parm: brightness_mode:Selects brightness control strategy: 0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM (uint)
      parm: brightness_enable:Enables backlight control when 1, disables when 0 (uint)
      parm: volume_mode:Selects volume control strategy: 0=auto, 1=EC, 2=N/A, 3=EC+NVRAM (uint)
      parm: volume_capabilities:Selects the mixer capabilites: 0=auto, 1=volume and mute, 2=mute only (uint)
      parm: volume_control:Enables software override for the console audio control when true (bool)
      parm: software_mute:Request full software mute control (bool)
      parm: index:ALSA index for the ACPI EC Mixer (int)
      parm: id:ALSA id for the ACPI EC Mixer (charp)
      parm: enable:Enable the ALSA interface for the ACPI EC Mixer (bool)
      parm: hotkey:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: bluetooth:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: video:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: light:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: cmos:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: led:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: beep:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: brightness:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: volume:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: fan:Simulates thinkpad-acpi procfs command at module load, see documentation
      parm: dbg_wlswemul:Enables WLSW emulation (uint)
      parm: wlsw_state:Initial state of the emulated WLSW switch (bool)
      parm: dbg_bluetoothemul:Enables bluetooth switch emulation (uint)
      parm: bluetooth_state:Initial state of the emulated bluetooth switch (bool)
      parm: dbg_wwanemul:Enables WWAN switch emulation (uint)
      parm: wwan_state:Initial state of the emulated WWAN switch (bool)
      parm: dbg_uwbemul:Enables UWB switch emulation (uint)
      parm: uwb_state:Initial state of the emulated UWB switch (bool)

      • Felix Lohmeier
        December 13, 2016 at 13:37

        Thanks again. Fedora seems to use a trimmed version of the kernel mod. Maybe I should switch to the generic version but I have no experience with kernel mods yet. Nice project for the next weekend ;-).

        [13:31 felix ~]$ modinfo thinkpad_acpi | sort | diff -w -U 0 <(sort lftome.txt) -L lftome_ubuntu? – -L felix_fedora24
        — lftome_ubuntu?
        +++ felix_fedora24
        @@ -5,3 +5,3 @@
        -author: Borislav Deianov
        -author: Henrique de Moraes Holschuh
        -depends: nvram,snd,video
        +author: Borislav Deianov
        +author: Henrique de Moraes Holschuh
        +depends: snd,rfkill,video
        @@ -9 +9 @@
        -filename: /lib/modules/4.8.0-30-generic/kernel/drivers/platform/x86/thinkpad_acpi.ko
        +filename: /lib/modules/4.8.12-200.fc24.x86_64/kernel/drivers/platform/x86/thinkpad_acpi.ko.xz
        @@ -14 +13,0 @@
        -parm: bluetooth_state:Initial state of the emulated bluetooth switch (bool)
        @@ -19,4 +17,0 @@
        -parm: dbg_bluetoothemul:Enables bluetooth switch emulation (uint)
        -parm: dbg_uwbemul:Enables UWB switch emulation (uint)
        -parm: dbg_wlswemul:Enables WLSW emulation (uint)
        -parm: dbg_wwanemul:Enables WWAN switch emulation (uint)
        @@ -35 +29,0 @@
        -parm: uwb_state:Initial state of the emulated UWB switch (bool)
        @@ -41,2 +34,0 @@
        -parm: wlsw_state:Initial state of the emulated WLSW switch (bool)
        -parm: wwan_state:Initial state of the emulated WWAN switch (bool)
        @@ -44 +36 @@
        -vermagic: 4.8.0-30-generic SMP mod_unload modversions
        +vermagic: 4.8.12-200.fc24.x86_64 SMP mod_unload

  3. Peter
    October 13, 2017 at 23:13

    Thanks! I have had intermittent bluetooth for years on my x121e, your “Day 2” suggestion of setting dbg_bluetoothemul=1 bluetooth_state=1 seems to have fixed it 🙂 Now listening with a2dp on my noise cancelling headphones for the first time!

    • halftome
      October 14, 2017 at 13:49

      Glad I could help 🙂 It seems the generic Ubuntu kernel has out-of-box support for it, (at least for bluetooth). It was only with Ubuntu-Gnome that it could not get it to work…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.