blob: c9123ada57700017aa8f6f0033b3ac785efb4344 [file] [log] [blame]
Eric Holmberg528f75c2013-01-29 14:43:41 -07001Introduction
2============
3
4The Serial Mux (SMUX) is a TTY Line Discipline that multiplexes
5multiple logical channels onto a single TTY serial channel. The
6logical channels are exposed through a kernel API.
7
8Companion adaptation drivers use the kernel API to expose logical
9channels as character devices (SMUX CTL - smux_ctl.c) to the user-space
10and as net devices (SMUX RMNET - msm_rmnet_smux.c) to the TCP/IP stack.
11
12Power control calls are supported to the physical serial driver to
13optimize power usage.
14
15
16Software description
17====================
18
19The Serial Mux driver will be similar in design to the SDIO DMUX and
20BAM DMUX drivers and will use the same multiplexing protocol with
21additional commands to support inactivity timeouts along with
22power-down and wake-up handshaking. Companion adaptation drivers will
23support data-plane traffic through TCP/IP (SMUX_RMNET) and control
24plane traffic through SMUX_CTL.
25
26
27 ttyHS0 RMNET[0..N] smuxctl[0..M]
28 | | |
29 | | |
30 | ------------------ -------------------
31 | | IP Framework | | VFS Framework |
32 | ------------------ -------------------
33 | | | | |
34 | | | | |
35 | ------- ------- ------- -------
36 | | Rmnet | | Rmnet | | CDEV | | CDEV |
37 | | Dev 0 |...| Dev N | | Dev 0 |...| Dev M |
38 | --------------------- --------------------- -------------
39 | | | | | | Other |
40 | | msm_rmnet_smux | | smux_ctl | | Kernel-only |
41 | | | | | | Clients |
42 | --------------------- --------------------- -------------
43 | | | | | |
44 | | | | | |
45 | | | | | |
46 | | | | | |
47 | ---------------------------------------------------
48 | |
49 | |
50 | |
51 | |
52 --------------- --------------------
53 | | | |
54 | TTY Framework | <- Line Discipline -> | SMUX |
55 | | | |
56 --------------- --------------------
57 | |
58 | |
59 --------------- |
60 | | |
61 | HS UART |<---------- Power API -----------
62 | |
63 ---------------
64 |
65 V
66 To Remote System
67
68
69Each logical channel will contain package management structures
70including a watermark to ensure fair usage of the physical layer by
71competing logical channels. All data for logical channels will be
72processed in FIFO order.
73
74Once data has been queued with SMUX, processing, copying of data, and
75notification to clients will be done using a combination of the TTY
76framework notification context and a workqueue. The lifetime of all
77buffers is controlled by the clients with SMUX taking temporary
78ownership of the buffers for read and write operations.
79
80The physical transport is assumed to be perfect and all errors will be
81handled by notifying the client of the failure. Watermark support and
82round-robin scheduling ensure that individual logical channels do not
83starve other logical channels.
84
85Data stalls caused by failure of the remote system are handled by
86Subsystem Restart. The restart logic will notify clients of the
87failure and all read and write buffers will be returned to the client
88with an error notification.
89
90Design
91======
92
93The goals for SMUX are to:
94 1) multiplex multiple logical channels into a single physical
95 channel
96 2) support a kernel API
97 3) provide power control of the physical layer
98
99In addition, the companion adapter modules have the goals:
100 1) support userspace character-device clients (smux_ctl)
101 2) support net devices through the TCP/IP stack (msm_rmnet_smux)
102
103Alternate designs consider including 3GPP 27.010 MUX protocol
104implementations and existing SDIO CMUX/DMUX implementations.
105
106The 3GPP 27.010 MUX protocol as implemented in both n_gsm.c and OpenEZX
107looked promising at first glance. However, upon further inspection,
108the implementations did not fully implement the power-control portions
109of the 27.010 MUX protocol. They also did not support kernel clients
110as they were designed to work only with userspace through TTY devices.
111The code was reviewed to determine the effort to add power-control
112signaling to the physical transport driver and to add a kernel API, but
113it was deemed that adding the API to support both of these behaviors
114would be difficult to do in a generic way such that it would be
115accepted by the upstream community.
116
117The SDIO CMUX/DMUX drivers do not have power control in them and the
118CMUX and DMUX drivers both require a separate physical channel. To use
119them, we would need to create an additional mux layer that would sit
120between CMUX/DMUX and the HS UART driver which would add another MUX
121header.
122
123Design - MUX Protocol
124=====================
125The MUX packet consists of a header (detailed below) and a payload.
126All values are in little-endian format and all reserved fields are set
127to zero unless otherwise mentioned in the individual command
128descriptions.
129
130Invalid commands and malformed commands will be logged to the kernel log
131as an error and ignored.
132
133 -----------------------------------------
134 |31 24| 16| 8| 0|
135 |----------|---------|----------|---------|
136 | Magic Number | Flags | CMD |
137 |----------|---------|----------|---------|
138 | Pad Len | LCID | Packet Length (N) |
139 |-----------------------------------------|
140 | Data Payload (0..N bytes) |
141 |-----------------------------------------|
142 | Pad Data (0..Pad Len bytes) |
143 -----------------------------------------
144
145Field definitions:
146 * Magic Number - always 0x33FC
147 * Flags - flags for individual commands
148 * CMD - SMUX command
149 * Pad Len - Padding in bytes at the end of the payload
150 * LCID - Logical channel ID
151 * Packet Length - Length of the data payload in bytes
152
153Commands
154 0x0 - Data
155 0x1 - Open Logical Channel
156 0x2 - Close Logical Channel
157 0x3 - Status
158 0x4 - Power Control
159
160Data Command
161------------
162The Data command sends data on an already fully-opened logical channel.
163
164Flags:
165 * Bits 0:7 - Reserved
166
167Open Logical Channel Command
168----------------------------
169The Open command is a request to open a logical channel. Each channel
170will have a local and remote open flag. The remote open flag will be
171set to open when receiving an open command and responding with an open
172ACK. The local open flag is set to open when sending an open command
173and receiving an ACK.
174
175 Remote Side | Local Side
176 |
177 SMUX Client SMUX SMUX SMUX Client
178 | | | |
179 | Open | | |
180 |--------->| | |
181 | | Open Logical Channel | |
182 | |---------------------->| |
183 | | |--- |
184 | | | | Set Remote Open |
185 | | |<-- |
186 | | Open ACK | |
187 | |<----------------------| |
188 | |--- | |
189 | | | Set Local Open | |
190 | |<-- | |
191 | ... ... ...
192 | | | msm_smux_open() |
193 | | |<-----------------------|
194 | | Open Logical Channel | |
195 | |<----------------------| |
196 | | | |
197 | |--- | |
198 | | | Set Remote Open | |
199 | |<-- | |
200 | | Open ACK | |
201 | |---------------------->| |
202 | | |--- |
203 | | | | Set Local Open |
204 | | |<-- |
205 | | | notify(SMUX_CONNECTED) |
206 | | |----------------------->|
207
208
209 Logical channel is now fully open and can receive
210 and transmit data.
211
212No data shall be transmitted over the physical link for the logical
213channel unless the channel is open.
214
215Flags:
216 * Bit 0 - 1 = ACK
217 * Bit 1 - Power Collapse Enable
218 * Bit 2 - Remote Loopback Enable
219 * Bits 3:7 - Reserved
220
221Power Collapse Enable (bit 1) enables power-collapse handshaking when
222processing an open command. The first logical channel open command
223received from the remote side will set the global power control state
224and all subsequent open commands should use the same value of the Power
225Collapse bit. The value of this bit can be changed during runtime by
226closing all logical channels and then re-opening them with the new
227global state.
228
229If the protocol stack does not support power collapse and it receives
230an open command with the Power Collapse Enable bit set, then it
231shall respond with an open command with the Power Collapse Enable bit
232cleared.
233
234If Power Collapse is disabled, then Power Control Commands should not
235be sent.
236
237Remote Loopback Enable (bit 2) enables loopback support when data is
238received from the remote side. In this case, SMUX should echo the
239received data packet back to the sender.
240
241Close Logical Channel Command
242-----------------------------
243The Close command closes the logical channel and updates the internal
244open state flags. The remote open flag will be set to closed when
245receiving a close command and responding with an close ACK. The local
246open flag is set to closed when sending a close command and receiving an
247ACK.
248
249No data shall be transmitted over the physical link for the logical
250channel after receiving a close command and responding with the close
251ACK.
252
253Flags:
254 * Bit 0 - ACK (when set to 1)
255 * Bits 1:7 - Reserved
256
257
258Status Command
259--------------
260The Status Command updates the channel status signals which include four
261ITU v.24 status bits in the lower nibble of the flags field along with a
262logical channel flow-control signal. The v.24 signals are pass-through
263and do not affect the state of SMUX.
264
265The Logical Channel Flow Control bit will disable TX on the logical
266channel when set and send a flow-control notification to the logical
267channel client. Any further attempts to transmit will result in an
268error return code.
269
270Flags:
271 * Bit 0 - RTC (DTR/DSR)
272 * Bit 1 - RTR (RTS/CTS)
273 * Bit 2 - RI
274 * Bit 3 - DCD
275 * Bit 4 - Logical Channel Flow Control
276 * Bits 5:7 - Reserved
277
278
279Power Control Command
280---------------------
281The physical layer requires a variable amount of time to wakeup from
282power collapse, reconfigure the hardware, and start processing data.
283Data may be lost until the wakeup has been completed. Because of this,
284a character-based wakeup method will be used to ensure that the remote
285side is active and ready before sending SMUX commands.
286
287If the remote side has previously requested power-down (boot-up state),
288then a wakeup request character is sent at periodic intervals (1 ms or
2898 character-widths, whichever is larger) until a wakeup-acknowledge character
290has been received. Normal transmit operations can then be performed. Once an
291activity timeout occurs, then a sleep vote should be sent to the remote side to
292let it know that the channel is no longer needed. The remote side should
293respond with an ACK.
294
295The following state diagram shows the full sequence of power state transitions.
296This state machine is identical on both the local and remote sides. The states
297marked "(internal)" are transitional states used in this driver that are not
298part of the power states tracked by the remote side. The edges are labeled
299using the format CONDITION:ACTION where condition is the guard condition that
300must be true for the edge to be taken and ACTION is the action that will be
301taken.
302
303 +--------------+ RX Sleep ACK || RX Sleep Request
304 :Flush and power-down | Powering |<---------+
305 UART +---------+ Down Flush | |
306 | | (internal) | |
307 | +--------------+ |
308 | ^ |
309 | | +-------+------+
310 v | | | |
311 +--------------+ | | Powering |
312 | | | | Down |<-----+
313Init --->| OFF | | | | |
314 | |------+ | +--------------+ |
315 | | | | |
316 +------+-------+ | | TX Sleep Request
317 | | | Complete
318 | | | |
319 Data ready to send | | |
320 :TX Wakeup Request | |RX Sleep Request |
321 | | |:TX Sleep ACK |
322 | | +------------+ +-------+------+
323 | | | | Turning Off^|
324 | | | | Flush |
325 | | | | (internal) |
326 | |RX Wakeup Request | +--------------+
327 | |:TX Wakeup ACK | ^
328 | | | |
329 | | | Inactivity Timeout
330 | +--------------+ | :TX Sleep Request
331 | | | |
332 v v | |
333 +--------------+ RX Wakeup ACK +-------+------+ |
334 | +------------------>| UP |+-----+
335 | Powering | | |
336 | Up +------------------>| Packet TX/RX |
337 +----->| | RX Wakeup Request | is now active|<------+
338 | +--+-----------+ :TX Wakeup ACK +----------+---+ |
339 | | | |
340 +---------+ +-----------+
341 Wakeup Request Timeout RX Wakeup Request
342 :TX Wakeup Request :TX Wakeup ACK
343
344
345In-band wakeup bytes:
346 * 0xfd - Wakeup Request
347 * 0xfe - Wakeup Acknowledge
348
349Flags:
350 * Bit 0 - ACK (when set to 1)
351 * Bit 1 - 1 = Sleep Request
352 * Bits 2:7 - Reserved
353
354Initial SMUX State
355------------------
356The boot-up state of SMUX is in power-disabled mode and all logical
357channels closed. Before sending any commands to open logical channels,
358the remote SMUX must be woken up.
359
360Power Management
361================
362
363Power management will consist of wakeup and shutdown control of the
364physical layer based upon an activity timeout. Wakelocks will be
365utilized to prevent the system from going to sleep while the transport
366is active. The activity timeout is anticipated to be 500 ms, but this
367is subject to tuning to meet power and performance specifications.
368
369SMP/multi-core
370==============
371
372Locking and synchronization will be done using mutexes or spinlocks
373where appropriate. The software will be structured such that locking
374can be kept to a minimum by only locking when items are added and
375removed from lists.
376
377Security
378========
379
380No new security issues are anticipated as communication with userspace
381is done through the existing TCP/IP and CDEV frameworks.
382
383Performance
384===========
385
386The throughput requirements for this design are on the order of 250Kbps
387so throughput concerns are not expected to be an issue. However, in
388the hope that this driver can be leveraged in the future instead of
389writing yet another multiplexing layer, performance will be considered
390when making design decisions.
391
392Interface
393=========
394
395The kernel API consists of commands to read and write data, vote for
396power, and verify the state of the logical channels.
397
398
399Open
400----
401int msm_smux_open(uint32_t lcid, void *priv,
402 void (*notify)(void *priv, int event_type, void *metadata),
403 int (*get_rx_buffer)(void *priv, void **pkt_priv,
404 void **buffer, int size))
405
406Open a logical channel. The channel will be first opened locally and
407an open command will be sent to the remote processor. Once the remote
408processor sends an open command, then the port will be fully open and
409ready for data operations -- the client will be notified with an
410SMUX_CONNECTED notification.
411
412For receive notifications, the driver will read the SMUX header into
413temporary storage and then when the logical channel and size are both
414known, the driver will call the get_rx_buffer() function to request a
415buffer for the data. The client should return 0 upon success or < 0
416using standard Linux error codes if an error occurred. If the error
417code is EAGAIN, then the call to get_rx_buffer() will be retried once,
418otherwise the data will be discarded by the driver and a kernel error
419message logged.
420
421Once the receive data has been processed, the notify() function will be
422called with metadata pointing to an instance of struct smux_meta_read
423and the event type will either be SMUX_READ_DONE for successful cases or
424SMUX_READ_FAIL for failure cases.
425
426/*
427 * Notification events that are passed to the notify() function.
428 *
429 * If the @metadata argument in the notifier is non-null, then it will
430 * point to the associated struct smux_meta_* structure.
431 */
432enum {
433 SMUX_CONNECTED, /* @metadata is null */
434 SMUX_DISCONNECTED,
435 SMUX_READ_DONE,
436 SMUX_READ_FAIL,
437 SMUX_WRITE_DONE,
438 SMUX_WRITE_FAIL,
439 SMUX_TIOCM_UPDATE,
440 SMUX_LOW_WM_HIT, /* @metadata is NULL */
441 SMUX_HIGH_WM_HIT, /* @metadata is NULL */
442};
443
444/*
445 * Metadata for SMUX_READ_DONE/SMUX_READ_FAIL notification
446 *
447 * @pkt_priv: Packet-specific private data
448 * @buffer: Buffer pointer passed into msm_smux_write
449 * @len: Buffer length passed into msm_smux_write
450 */
451struct smux_meta_read {
452 void *pkt_priv;
453 void *buffer;
454 int len;
455};
456
457Close
458-----
459int msm_smux_close(uint32_t lcid)
460
461Closes a logical channel locally and sends a close command to the
462remote host.
463
464If there is pending transmit or receive data, then SMUX_WRITE_FAIL and
465SMUX_READ_FAIL notifications will be made to return ownership of the
466buffers to the client.
467
468Once the remote side of the port has been closed, the notify function
469will be called with the event SMUX_DISCONNECTED and metadata pointing
470to a struct smux_meta_disconnected structure. After this point, no
471further notifications will be performed.
472
473/*
474 * Metadata for SMUX_DISCONNECTED notification
475 *
476 * @is_ssr: Disconnect caused by subsystem restart
477 */
478struct smux_meta_disconnected {
479 int is_ssr;
480};
481
482
483Write
484-----
485int msm_smux_write(uint32_t lcid, void *pkt_priv, void *data, int len)
486
487Queues data for transmit. Once the data has been transmitted, the
488SMUX_WRITE_DONE or SMUX_WRITE_FAIL notifications will be sent with
489metadata pointing to an instance of struct smux_meta_write.
490
491If the high watermark has been exceeded, then further writes will
492return -EAGAIN.
493
494Data may be written as soon as the local side of the port has been
495opened, but the data will not be transmitted until the channel has been
496fully opened and the SMUX_CONNECTED event has been sent.
497
498/*
499 * Metadata for SMUX_WRITE_DONE/SMUX_WRITE_FAIL notification
500 *
501 * @pkt_priv: Packet-specific private data
502 * @buffer: Buffer pointer returned by get_rx_buffer()
503 * @len: Buffer length returned by get_rx_buffer()
504 */
505struct smux_meta_write {
506 void *pkt_priv;
507 void *buffer;
508 int len;
509};
510
511Watermark
512---------
513 int msm_smux_is_ch_full(uint32_t lcid)
514 int msm_smux_is_ch_low(uint32_t lcid)
515
516A channel watermark is used to keep individual clients from using
517excessive internal resources. The client may call
518msm_smux_is_ch_full() after every msm_smux_write() operation and if the
519watermark is high, it should not queue any more packets for
520transmission. As an alternative, the client may base this decision
521upon receiving an SMUX_HIGH_WM_HIT notification.
522
523Likewise, the client may call msm_smux_is_ch_low() after every
524SMUX_WRITE_DONE or SMUX_WRITE_FAIL notification and if the watermark is
525low, then new transmit operations can be started. As an alternative,
526the client may base this decision upon receiving an SMUX_LOW_WM_HIT
527notification.
528
529Control Signals
530---------------
531 long msm_smux_tiocm_get(uint32_t lcid)
532 long msm_smux_tiocm_set(uint32_t lcid, uint32_t set, uint32_t clear)
533
534The TIOCM bits do not affect the SMUX internal state as they are
535pass-through for the clients. The client can receive notifications of
536state changes through the SMUX_TIOCM_UPDATE command.
537
538See the "Status Command" section for details on the TIOCM bits.
539
540/*
541 * Metadata for SMUX_TIOCM_UPDATE notification
542 *
543 * @previous: Previous TIOCM state
544 * @current: Current TIOCM state
545 *
546 */
547struct smux_meta_tiocm {
548 uint32_t previous;
549 uint32_t current;
550};
551
552Subsystem Restart
553-----------------
554Subsystem restart is handled by sending a disconnect notification
555followed by sending read and write fail notifications to each client.
556This returns ownership of the read and write buffers to the clients for
557client-appropriate handling.
558
559The sequence of notifications shall be:
560 1) SMUX_DISCONNECTED notification with @metadata->is_ssr == 1
561 2) SMUX_WRITE_FAIL for each packet in TX queue
562 3) SMUX_READ_FAIL for any RX packet in progress
563
564After the completion of the sequence, the client should call msm_smux_close()
565followed by a call to msm_smux_open() to re-open the port.
566
567
568Debug / Testing
569---------------
570
571Several debugfs nodes will be exported under the n_gsm directory for
572testing and debugging.
573 * tbl - prints table of logical channels
574 * stats - prints transfer statistics
575 * enable_local_loopback - echo LCID to enable loopback
576 * disable_local_loopback - echo LCID to enable loopback
577 * enable_remote_loopback - echo LCID to enable loopback
578 * disable_remote_loopback - echo LCID to enable loopback
579
580Driver parameters
581=================
582
583A module parameter called debug_mask will be exported to allow a user
584to set the log level for debugging.
585
586Config options
587==============
588
589No configuration options are planned.
590
591Dependencies
592============
593
594The msm_rmnet_smux and smux_ctl drivers are part of this project and
595are used to interface with the Linux TCP/IP framework and user space.
596
597The physical transport is the HS UART driver which will be extended to
598add a kernel API (the current interface is a TTY interface).
599
600Initialization of dependency drivers is handled using the platform
601device framework. When SMUX is loaded as a line discipline of the TTY
602Framework, it will register separate device drivers with the following
603device names:
604 * SMUX_CTL
605 * SMUX_RMNET
606 * SMUX_DUN_DATA_HSUART
607 * SMUX_RMNET_DATA_HSUART
608 * SMUX_RMNET_CTL_HSUART
609 * SMUX_DIAG
610
611The drivers are removed when SMUX is unloaded from the line discipline.
612
613
614User space utilities
615====================
616
617No userspace utilities are planned aside from testing and example
618applications.
619
620Known issues
621============
622
623None.
624
625To do
626=====
627Once completed, benchmark to determine if FIFO packet scheduling is
628sufficient or if a different scheduling algorithm such as deficit
629round-robin or deficit FIFO scheduling is needed to fairly handle
630variable-sized packets.