Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Figure out how to get the modem to boot in USB mode #3

Open
abrasive opened this issue Oct 17, 2019 · 19 comments
Open

Figure out how to get the modem to boot in USB mode #3

abrasive opened this issue Oct 17, 2019 · 19 comments

Comments

@abrasive
Copy link
Collaborator

At the moment this hack works by disabling the PCIe link and resetting the modem. This relies on ACPI, requires the acpi_call module, and may not survive suspend/resume. It'd be nicer if we could disable PCIe semipermanently.

There are clearly NVM variables in the modem that control PCIe operation. These are probably the obvious place to look.

@abrasive
Copy link
Collaborator Author

abrasive commented Oct 17, 2019

This can be done through NVM: there's a flag you can set to let it run USB and PCI interfaces simultaneously!

Unfortunately, in doing so, I borked my laptop - it comes up with USB ID 2CB7:0007, which is not on the BIOS whitelist, so the thing won't boot. Now I have to pull the card and hotplug it, which sucks, because getting the base off a T490 is a huge effort.

The workaround here will be to change the USB vendor and product IDs (which is also obvious through the NVM interface). Question is, what are the whitelisted USB values in there? Are they the same as the PCI ones, can we just use 8086:7360?

@abrasive
Copy link
Collaborator Author

TODO: is it possible to flip it to dual interface mode without resetting the card, ie. without permanently storing the flag in NVM? This would allow a PCI-based mode switch as per #4 without risk of hitting BIOS whitelists.

@knuxyl
Copy link

knuxyl commented Oct 17, 2019

TODO: is it possible to flip it to dual interface mode without resetting the card, ie. without permanently storing the flag in NVM? This would allow a PCI-based mode switch as per #4 without risk of hitting BIOS whitelists.

I'm guessing the NVM is like the NVRam on a qualcomm phone that stores configs for frequencies etc? What do you use to access that? And yeah, I believe the dual interface mode would be much more preferable for dual booting windows, but automatic switch on linux startup is fine. Being able to manually set the IDs would be great because then we could possible use it in other deivces.

I have a rpi with bios reader, idk if dumping the bios (if it even has one) would be helpful but that's as much as I can do. My card is already out of my P52.

@abrasive
Copy link
Collaborator Author

Yes. NVM = non-volatile memory, ie. it stores data even when the modem is off.

In this case there are AT commands you can send to the modem for reading and writing NVM, eg.

at@nvm:fix_cat_fcclock.fcclock_mode=?
at@nvm:fix_cat_fcclock.fcclock_mode=0
at@nvm:store_nvm_sync(fix_cat_fcclock)
at@nvm:dump_csv("fix_cat_fcclock")
at@nvm:dump_csv("")

...and so forth. I wouldn't be surprised if Fibocom eventually respond by locking these out from production modems.

As far as BIOS goes, the card does have a whole operating system flashed on there - almost 30MB of it - and it's conveniently provided by Lenovo in the firmware updater package ;-) That's how I've found these AT commands, and others.

@juhovh
Copy link

juhovh commented Oct 20, 2019

First of all thanks for all your work on this modem, it is very much appreciated. I came just to say that I was a bit annoyed by the python and acpi_call module dependencies, and also the fact that I had to re-run the script after each reboot, so I rewrote the script as a kernel module and set an alias to it that makes it get loaded by udev on boot. I think the result is actually simpler than the Python version, although comes with some side-effects.

This was mainly just to scratch my own itch, but I thought it might be helpful for someone else as well, so the code can be found from https://github.com/juhovh/xmm7360_usb

@abrasive
Copy link
Collaborator Author

@juhovh That's a much nicer way to do it! Especially since it should avoid suspend/resume issues.

I think I will update the docs to point to this instead of my crappy proof of concept, is there any reason not to? Hopefully someone can contribute a DKMS setup for those users that need it.

@juhovh
Copy link

juhovh commented Oct 20, 2019

I'm still experimenting with it myself, the main problem is that I can see some power management related errors in the dmesg logs when suspending the computer, the driver should probably do some related configuration. It currently also re-enables the PCIe link and resets the device when going to suspend which is unoptimal, but does the same disable+reset when coming back up and I can just re-connect to LTE and things seem to work just fine.

I guess you could at least link it as an alternative to get more eyes on potential improvements. Also DKMS / akmod would be nice, I might look into that at some point since I'm not interested in recompiling on every kernel upgrade either.

@abrasive
Copy link
Collaborator Author

@juhovh interesting, I don't see any PM errors testing it out here?

In any case, thanks for your efforts!

@juhovh
Copy link

juhovh commented Oct 21, 2019

Could be because I've enabled some extra power saving settings with powertop before. I guess the ideal solution would still be to be able to do this in userspace without additional modules and make it an udev rule, but I guess that would require figuring out a solution to #4 first. Until then I'm happy if my module is useful to someone.

@abrasive

This comment has been minimized.

@kopax

This comment has been minimized.

@abrasive
Copy link
Collaborator Author

Which IRC channel is this?

@kopax
Copy link

kopax commented Oct 29, 2019

@kopax you can just do sudo insmod xmm7360_usb.ko to load the module without installing it?

I just tried and insmod: ERROR: could not insert module xmm7360_usb.ko: File exists

Which IRC channel is this?

#linux@freenode

@juhovh
Copy link

juhovh commented Oct 31, 2019

Just to give a status update, I occasionally got some a bit mysterious page faults while resuming the system from suspend that seemed to be related to my module, and they hung up the system (but didn't give me a dump even with kdump enabled). I wrote a modified version for my own use that didn't register itself as a PCI driver but instead as just a generic driver that scans the PCI bus for matching devices and registers itself to the power management events to be able to re-scan after suspend. The latter version has been completely stable, so I might push it to the repository at some point.

@kopax
Copy link

kopax commented Oct 31, 2019

Thanks @juhovh can't wait to try this. How does the upgrade from abrasive to your version happen?

@juhovh
Copy link

juhovh commented Oct 31, 2019

Everything is the same, I just wrote an alternative version of the xmm2usb script + acpi_call module into a single kernel module that loads automatically on boot. I believe one could get the same result with acpi_call and setting up an udev script calling xmm2usb.

@kopax
Copy link

kopax commented Nov 1, 2019

I have just tried your module and I am now able to login using my LDAP credentials without having to go into console as root to do all the manual configuration. @abrasive this should be the official fix (and maybe driver)

This is awesome @juhovh, I love you guys!

@rjocoleman
Copy link

This can be done through NVM: there's a flag you can set to let it run USB and PCI interfaces simultaneously!

Unfortunately, in doing so, I borked my laptop - it comes up with USB ID 2CB7:0007, which is not on the BIOS whitelist, so the thing won't boot. Now I have to pull the card and hotplug it, which sucks, because getting the base off a T490 is a huge effort.

The workaround here will be to change the USB vendor and product IDs (which is also obvious through the NVM interface). Question is, what are the whitelisted USB values in there? Are they the same as the PCI ones, can we just use 8086:7360?

@abrasive nice work. really nice work. I started playing around with this a year ago and parked it without success - I'm really happy to see you've cracked it and shared your work - thanks!

I've got a couple of these xmm7360 based cards (2 of the Lenovo Fibocom 850 and a HP version of the same part with different ids). I also have a couple of USB WWAN adapters and an x1c6 (the base is much easier to remove).

Would you mind please pointing me in the direction of the nvm commands you used to trigger usb mode, and change vendor IDs? (at@nvm:dump_csv("") has a lot to sort though!)

I've dumped and traced the x1c5, x1c6 and t480s bioses in past to check the whitelists. Last I looked x1c6 and t480s both include just 8086:7360. Some revisions also had the sierra wireless em7565 (which was much easier to use) but this was silently added and silently removed after a couple of bios revisions.
I'll check the t490 whitelist sometime in the next couple of days too.

@rjocoleman
Copy link

rjocoleman commented Nov 9, 2019

For lack of a better place here are my notes on the whitelists for a few machines incase it's helpful.

I'm currently trying to reproduce changed of vendor id, device id (and importantly see if I can change subsystem device id) to an Fibocom L850-GL that @abrasive mentioned was possible.

My goal is changing the card to USB or USB+PCIe mode permanently and to have a vendor/product/subsystem id combo that passes the whitelist (8086/7360/8086/0020 is the most flexible imo).

Lenovo ThinkPad T490s / X390 N2JET77P, version 1.55

https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-t-series-laptops/thinkpad-t490s-type-20nx-20ny/20nx/parts/display/compatible

Bios Link: https://support.lenovo.com/us/en/downloads/ds539062 (n2juj17w.exe)

Whitelist entities: 2

  1. Whitelist String: 010000008680607386802000

1802 Message String: 8086/7360/8086/0020

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 8086:0020

  1. Whitelist String: 0100000086806073F81C0585

1802 Message String: 8086/7360/1CF8/8505

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 1CF8:8505

Lenovo ThinkPad T490/ThinkPad P43s/ThinkPad T590/ThinkPad P53s/ThinkPad T490 HC (P-BIOS) System Firmware N2IET77P, version 1.55

Parts: https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-t-series-laptops/thinkpad-t490-type-20n2-20n3/20n2/parts/display/compatible

Bios Link: https://support.lenovo.com/us/en/downloads/ds539061 (n2iul15w.zip)

Whitelist entities: 3

  1. Whitelist String: 010000008680607386802000

1802 Message String: 8086/7360/8086/0020

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 8086:0020

  1. Whitelist String: 0100000086806073F81C0585

1802 Message String: 8086/7360/1CF8/8505

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 1CF8:8505

  1. Whitelist String: 0100000086806075F81C0186

1802 Message String: 8086/7560/1CF8/8601

Vendor ID: 8086
Device ID: 7560
Subsystem Device ID: 1CF8:8601

Lenovo Thinkpad X1 Carbon 7th / X1 Yoga 4th System Firmware N2HET40P, version 1.23.

https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-x-series-laptops/thinkpad-x1-carbon-7th-gen-type-20r1-20r2/20r1/parts/display/compatible

Bios Link: https://support.lenovo.com/us/en/downloads/ds540232 (n2hul13w.zip)

Whitelist entities: 3

  1. Whitelist String: 010000008680607386802000

1802 Message String: 8086/7360/8086/0020

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 8086:0020

  1. Whitelist String: 0100000086806073F81C0585

1802 Message String: 8086/7360/1CF8/8505

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 1CF8:8505

  1. Whitelist String: 0100000086806075F81C0186

1802 Message String: 8086/7560/1CF8/8601

Vendor ID: 8086
Device ID: 7560
Subsystem Device ID: 1CF8:8601

Lenovo ThinkPad X1 Carbon 6th System Firmware N23ET68W, version 1.43

https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-x-series-laptops/thinkpad-x1-carbon-6th-gen-type-20kh-20kg/20kh/parts/display/compatible

Bios Link: https://support.lenovo.com/us/en/downloads/ds502281 (n23ul19w.zip)

Whitelist entities: 1

  1. Whitelist String: 010000008680607386802000

1802 Message String: 8086/7360/8086/0020

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 8086:0020

Note: Sierra Wireless EM7565 is listed on the parts list but is not in the whitelist - it was in some prior bios versions but has disappeared in more recent releases.

Lenovo ThinkPad P52/P72 System Firmware N2CET46W, version 1.29

https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-p-series-laptops/thinkpad-p52-type-20m9-20ma/20m9/parts/display/compatible

Bios Link: https://support.lenovo.com/us/en/downloads/ds504024 (n2cet46w.cab)

Whitelist entities: 2

  1. Whitelist String: 010000008680607300000000

1802 Message String: 8086/7360/0000/0000

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 0000:0000

  1. Whitelist String: 010000008680607386802000

1802 Message String: 8086/7360/8086/0020

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 8086:0020

Lenovo ThinkPad P53/P73 System Firmware N2NET31P, version 1.16

https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-p-series-laptops/thinkpad-p53-type-20qn-20qq/20qn/parts/display/compatible

Bios Link: https://support.lenovo.com/us/en/downloads/ds540999 (n2nul06w.zip)

Whitelist entities: 3

  1. Whitelist String: 010000008680607386802000

1802 Message String: 8086/7360/8086/0020

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 8086:0020

  1. Whitelist String: 010000008680607300000000

1802 Message String: 8086/7360/0000/0000

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 0000:0000

  1. Whitelist String: 0100000086806073F81C0585

1802 Message String: 8086/7360/1CF8/8505

Vendor ID: 8086
Device ID: 7360
Subsystem Device ID: 1CF8:8505

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants