Project

General

Profile

XMMUpstreaming » History » Version 23

Denis 'GNUtoo' Carikli, 02/10/2022 05:29 PM
Add link to .write function

1 1 Denis 'GNUtoo' Carikli
h1. XMMUpstreaming
2
3
{{toc}}
4
5
h2. Analysis of Replicant 9 Linux 5.2 modem branch
6
7
These were cleaned up and ported from forkbomb's code:
8
<pre>
9
b4c2df98ed6f misc: xmm6262: Add Samsung IPC USB modem firmware download module
10
77b55273bd6e net: usb: add Samsung IPC-over-HSIC driver
11
f9ae2d1697fa net: add Samsung IPC interface driver
12
7806adad4507 HACK: usb: host: ehci-exynos: add ehci_power sysfs node
13
82c317b0da5e HACK: add modem power on/off driver
14
28e5b460f920 HACK: usb: ehci_exynos: enable OHCI_SUSP_LEGACY
15
e7c122b770c1 ARM: dts: EXYNOS: add 3G modem nodes to midas boards
16
c3201527f7ea ARM: dts: split Exynos 4412 N710x boards up
17
5b55f03cda8c ARM: dts: EXYNOS: add Samsung IPC modem support
18
eca381876d5e ARM: dts: EXYNOS: enable HSIC0 on midas boards
19
7ec9129e3221 replicant_*_defconfig: extend cmdline to get IMSI and other information
20
54c196380507 replicant_*_defconfig: Add modem support
21
[...]
22
0ecfebd2b524 Linux 5.2
23
</pre>
24
25
If we look at the drivers only (not the dts or config changes, or hacks in pre-existing code, we are left with):
26
<pre>
27
b4c2df98ed6f misc: xmm6262: Add Samsung IPC USB modem firmware download module
28
77b55273bd6e net: usb: add Samsung IPC-over-HSIC driver
29
f9ae2d1697fa net: add Samsung IPC interface driver
30
82c317b0da5e HACK: add modem power on/off driver
31
</pre>
32
33
We'd also need to find a way to fix these:
34
<pre>
35
7806adad4507 HACK: usb: host: ehci-exynos: add ehci_power sysfs node
36
28e5b460f920 HACK: usb: ehci_exynos: enable OHCI_SUSP_LEGACY
37
</pre>
38
39
40
So we'd probably need to have something like that instead:
41 3 Denis 'GNUtoo' Carikli
1. A driver for the SIPC (Samsung IPC) protocol (f9ae2d1697fa net: add Samsung IPC interface driver)
42
2. A driver for the SIPC (Samsung IPC) transport on top of HSIC and the protocol (77b55273bd6e net: usb: add Samsung IPC-over-HSIC driver).
43 1 Denis 'GNUtoo' Carikli
3. A modem driver with:
44
** The GPIO handling like drivers/hsi/clients/nokia-modem.c (some GPIOs probably cannot be handled in userspace like gpio_pda_active (see [[XMMBoot#GPIOs-usage]] for more details) (82c317b0da5e HACK: add modem power on/off driver)
45
** The firmware loading code (b4c2df98ed6f misc: xmm6262: Add Samsung IPC USB modem firmware download module)
46 5 Denis 'GNUtoo' Carikli
** Probably some of the hacks here. For instance GPIO input IRQ -> hsic bus reset
47 4 Denis 'GNUtoo' Carikli
48
So we have: Userspace <-> SIPC protocol <-> SIPC transport <-> HSIC
49
50
However I'm not sure about certain things:
51 15 Denis 'GNUtoo' Carikli
* -The SIPC protocol is huge and has different userspace interfaces. Maybe it could be split- It looks fine as-is.
52
* -The SIPC transport driver uses an USB id table (the modem ID once booted). => Should we keep the IDs in it or move them in the modem driver instead?- It's fine there.
53 6 Denis 'GNUtoo' Carikli
54 7 Denis 'GNUtoo' Carikli
Also look at the motorolla cpcap driver for the droid4. The architecture is different though: While it uses USB, it's tied to Qualcomm modem drivers (CDC) which probably doesn't have a specific protocol beside the multiplexing of the UART lines and network interfaces, though CDC could be seen as a specific protocol
55 9 Denis 'GNUtoo' Carikli
56
h2. Analysis of the architecture of the drivers made by Simon Shields
57
58
Simon Shields wrote some drivers that work on top of upstream Linux and that were made to work in at least two conditions:
59
* With the Replicant 11 kernel under Parabola and with Simon Shields patches for libsamsung-ipc being reworked/rebased
60
* With a Galaxy S as part of some other project (PostmarketOS ?) (TODO: Add mailing list link and reference)
61
62
h3. Firmware loading and GPIO driver
63
64 16 Denis 'GNUtoo' Carikli
h4. Issue that lead to this design.
65
66 17 Denis 'GNUtoo' Carikli
h5. Firmware loading
67
68 16 Denis 'GNUtoo' Carikli
Linux has an API to ask userspace for a firmware, retrieve that firmware and so it can send it to the device afterward.
69
70
The issue is that this API typically expect files to be in /lib/firmware while here the data is on a dedicated partition like @RADIO@. 
71
72
So we could for instance do something like that: 
73
<pre>
74
# echo 1 > /sys/class/firmware/<somename>/loading
75
# cat /dev/block/by-partlabel/RADIO > /sys/class/firmware/<somename>/data
76
# echo 0 > /sys/class/firmware/<somename>/loading
77
</pre>
78
79
But the issue is that on GNU/Linux udev and/or systemd handles that and in Android there is also a dedicated daemon for firmware loading, and both probably expect file names that are provided by the kernel to know which file to cat in /sys/class/firmware/<somename>/data.
80
81
So while we could load the firmware, I don't know how the Android firmware loading code would be able to detect that it needs to cat a partition and not a file in /lib/firmware.
82
83
Maybe we could have a symlink to the partition in /lib/firmware?
84
85
Having that work on GNU/Linux is also extremely useful for testing so there we would have issues too to make it work fine.
86 17 Denis 'GNUtoo' Carikli
87
h5. GPIOs
88
89
The GPIOs are used during the firmware loading. But in the vendor kernel they also signal when the host goes in suspend, so we probably need to check how it's done and how to implement it in a way compatible with upstreaming.
90 9 Denis 'GNUtoo' Carikli
91
h3. Main drivers
92
93
h4. Write to /dev/umts_ipc
94
95
<pre>
96 12 Denis 'GNUtoo' Carikli
+----------------+        +---------------+                                                                                                                                          +--------------+
97
| libsamsung-ipc | -----> | /dev/umts_ipc | -----> drivers/net/sipc/miscdev.c: .write -> sipc_misc_write( [...] ) {  [...] // enqueue data to tx_queue_raw + add padding [....] } -> | tx_queue_raw |
98
+----------------+        +---------------+                                                                                                                                          +--------------+
99 11 Denis 'GNUtoo' Carikli
</pre>
100
101
<pre>
102
+--------------+
103
| tx_queue_raw | -----> | dequeue in drivers/net/sipc/core.c in sipc_tx_work ( [...] ) { [...] sipc_do_tx( [...] ); [...] } -----> sipc_do_tx( [...] ep->transmit() [...] );
104
+--------------+
105
</pre>
106
107
<pre>
108
+-------------+
109
| .transmit() | -----> sipc_link_transmit( [...], struct sk_buff *skb ) {  [...] // configure the USB as sndbulkpipe for sending a bulk pipe and sends the skb }
110
+-------------+   ^
111
                  |
112
                  |+--Setup in sipc_probe()
113 9 Denis 'GNUtoo' Carikli
</pre>
114 13 Denis 'GNUtoo' Carikli
115
Here's a more data centric view:
116 23 Denis 'GNUtoo' Carikli
| function                | Content                                                                        |
117
| sipc_link_transmit[1]   | Add USB headers only with usb_sndbulkpipe() and sends the data to the USB core |
118
| sipc_misc_write[2]      | Adds HDLC header and footer and sends the data to sipc_link_transmit           |
119
| /dev/umts_ipc .write[3] | function pointer to sipc_misc_write                                            |
120 1 Denis 'GNUtoo' Carikli
121
fn1. https://git.replicant.us/replicant-next/kernel_replicant_linux/tree/drivers/net/usb/sipc_hsic.c?id=640e70c912b114297c90db7273b08e722d043a59#n119
122 18 Denis 'GNUtoo' Carikli
123 1 Denis 'GNUtoo' Carikli
fn2. https://git.replicant.us/replicant-next/kernel_replicant_linux/tree/drivers/net/sipc/miscdev.c?id=640e70c912b114297c90db7273b08e722d043a59#n79
124 23 Denis 'GNUtoo' Carikli
125
fn3. https://git.replicant.us/replicant-next/kernel_replicant_linux/tree/drivers/net/sipc/miscdev.c?id=640e70c912b114297c90db7273b08e722d043a59#n167
126 14 Denis 'GNUtoo' Carikli
127
In wireshark we need to find out what fields of the urb struct usb_sndbulkpipe() populates, and find the payload in Wireshark.
128
129
Then we should see a 1 byte HDLC header and footer and the payload inside which should normally correspond exactly to what libsamsung-ipc sent (though the bytes may be encoded as big endian or little endian by the USB core).