Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame^] | 1 | Introduction |
| 2 | ============ |
| 3 | |
| 4 | QUALCOMM MSM Interface (QMI) defines the interface between MSM and |
| 5 | attached Terminal Equipment (TE). RmNet interface is a new logical |
| 6 | device in QMI framework for data services. RmNet in accordance with |
| 7 | QMI architecture defines channels for control and data transfers and |
| 8 | for example it uses Data I/O channel for IP data transfer and control |
| 9 | I/O channel for QMI messaging (functionality similar to AT commands). |
| 10 | RmNet may be used in place of legacy USB modem interface. |
| 11 | |
| 12 | Tethered networking is one of the function from MSM which can also be |
| 13 | supported using QMI protocol. There are other standard protocols exists |
| 14 | such as CDC-ECM and Windows proprietary RNDIS. On the host-side system, |
| 15 | the gadget rmnet device looks like a ethernet adapter. |
| 16 | |
| 17 | Hardware description |
| 18 | ==================== |
| 19 | |
| 20 | QMI is a messaging protocol to expose various functionalities of MSM |
| 21 | and one of the functionality to be tethered networking which is being |
| 22 | exposed over QMI using RmNet protocol. This usb gadget has one bulk-in, |
| 23 | one bulk-out and one interrupt-in endpoint. |
| 24 | |
| 25 | Design: |
| 26 | ======= |
| 27 | RmNet function driver design follows two approaches: |
| 28 | |
| 29 | Approach 1: |
| 30 | ----------- |
| 31 | Single function driver is used to communicate with |
| 32 | Modem(both for data and control). Most of the initial |
| 33 | MSM targets are following this approach. |
| 34 | |
| 35 | The main disadvantage with this approach is there are |
| 36 | multiple RmNet drivers for any change in DATA and Control |
| 37 | Layer. There is no re-use in the code. |
| 38 | |
| 39 | Approach 2: |
| 40 | ----------- |
| 41 | RmNet driver is divided into 3 components |
| 42 | |
| 43 | 1. USB: |
| 44 | This component has the functionality to deal with composite layer. |
| 45 | Allocates Interfaces, Endpoints, listens to connect/disconnect |
| 46 | interrupts and gives connect/disconnect notifications to DATA and |
| 47 | CONTROL modules. |
| 48 | |
| 49 | 2. Data: |
| 50 | This component talks to modem to transfer IP data. Usually DATA |
| 51 | and CONTROL go over same channel. However, to achieve higher |
| 52 | data rates new transport channel for DATA may be used. |
| 53 | |
| 54 | 3. Control: |
| 55 | This component talks to modem to transfer rmnet control data. |
| 56 | |
| 57 | Software description |
| 58 | ==================== |
| 59 | The RmNet suports following data and control transports: |
| 60 | as follows: |
| 61 | 1. SMD Interface |
| 62 | 2. SDIO Interface |
| 63 | 3. BAM Interface |
| 64 | 4. SMD Control Interface |
| 65 | |
| 66 | SMD interface uses the Shared memory for the RmNet driver to communicate |
| 67 | with the MSM modem processor. |
| 68 | SDIO interface acts as a link for communication of RmNet driver with the |
| 69 | MDM modem processor. |
| 70 | |
| 71 | USB INTERACTION: |
| 72 | ---------------- |
| 73 | |
| 74 | The RmNet function driver binds with the USB using the struct usb_function. |
| 75 | The function is added using the usb_function_add(). |
| 76 | Control Transfers: The RmNet handles two Class-specific control |
| 77 | transfers: SEND_ENCAPSULATED_COMMAND and GET_ENCAPSULATED_RESPONSE. |
| 78 | The asynchronous protocol QMI which consists of the QMI requests/responses |
| 79 | is used for handling the transfers between the RmNet and the Host where the |
| 80 | host sends a new QMI request before receiving the response for the current |
| 81 | QMI request. |
| 82 | |
| 83 | Control & Data flow: |
| 84 | 1. Host issues a SEND_ENCAPSULATED command to send a QMI request. |
| 85 | SMD: If the SMD control channel has enough room to accomodate a QMI request, |
| 86 | it is written into the SMD buffer. Otherwise, append/add that request to |
| 87 | qmi_request queue. A tasklet is scheduled to drain all QMI requests in |
| 88 | qmi_request queue. |
| 89 | SDIO: Add each request in the qmi_request queue and is processed until |
| 90 | the queue is empty. |
| 91 | |
| 92 | 2. Append/Add QMI response from modem to qmi_response queue. |
| 93 | A notification on an interrupt end point is used to communicate the QMI |
| 94 | response to host. |
| 95 | |
| 96 | 3. Host issues a GET_ENCAPSULATED command to retrieve the QMI response. |
| 97 | The response from qmi_response queue will be sent to the host. |
| 98 | |
| 99 | 4. After the connection is fully established data can be sent to |
| 100 | bulk-out endpoint and data can be received from bulk-in endpoint. |
| 101 | |
| 102 | 5. Host can send QMI requests even after the connection is established. |
| 103 | |
| 104 | RmNet gadget driver is completely unaware of QMI/IP protocol. It just |
| 105 | acts as a bridge between the modem and the PC. |
| 106 | |
| 107 | All the request/response queues in the driver can be accessed either |
| 108 | from tasklet/workqueue or from interrupt context (either usb or smd/sdio |
| 109 | interrupt handler). Hence a spinlock is used to protect all data/control req |
| 110 | lists. |
| 111 | |
| 112 | |
| 113 | SMD Interface: |
| 114 | -------------- |
| 115 | |
| 116 | 1. Each QMI request/response can at most be 2048 bytes. Eight 2KB buffers |
| 117 | are allocated using kmalloc for storing maximum of 8 requests/responses. |
| 118 | |
| 119 | 2. Four 2KB buffers are allocated using kmalloc for data transfers on |
| 120 | each bulk endpoint. |
| 121 | |
| 122 | Data structures: |
| 123 | struct qmi_buf - Buffer to handle QMI requests & responses |
| 124 | struct rmnet_smd_info - Control & Data SMD channel private data |
| 125 | struct rmnet_dev - Endpoint and driver specific data |
| 126 | |
| 127 | Workqueues: |
| 128 | rmnet_connect_work - Called on device connection. |
| 129 | Opens SMD channels; enables endpoints |
| 130 | rmnet_disconnect_work - Called on device disconnection. |
| 131 | Closes SMD channels. |
| 132 | |
| 133 | Tasklets: |
| 134 | rmnet_control_rx_tlet |
| 135 | rmnet_control_tx_tlet - Control transfer data reception and transmission |
| 136 | handler |
| 137 | |
| 138 | rmnet_data_rx_tlet |
| 139 | rmnet_data_tx_tlet - Data transfer data reception and transmission handler |
| 140 | |
| 141 | |
| 142 | SMD control interface |
| 143 | ---------------------- |
| 144 | This function driver implements exchnage of control informtion with |
| 145 | modem over SMD. Uses smd_read/write commands to read or write rmnet |
| 146 | ctrl packets. Exposes a call back function to usb component to write |
| 147 | control packet and at the same time call a call back usb component |
| 148 | callback to send data to usb host. |
| 149 | |
| 150 | Data structures and Interfaces are very similar to control interfaces |
| 151 | explained in "SMD Interface" |
| 152 | |
| 153 | BAM MUX interface |
| 154 | ------------------ |
| 155 | BAM Mux interface is very similar to SDIO MUX interface. However there |
| 156 | are differences in the way BAM and SDIO operate but all of the details |
| 157 | are masked by MUX Driver. |
| 158 | |
| 159 | Refer to the SDIO interfaces for more information on data structures |
| 160 | |
| 161 | SDIO Interface: |
| 162 | --------------- |
| 163 | |
| 164 | 1. Each QMI request/response buffer is allocated depending on the size |
| 165 | of data to be transmitted for the request/response. |
| 166 | |
| 167 | 2. A 2KB network buffer is allocated for data transfer on bulk-out |
| 168 | endpoint. The SDIO allocates the required buffer for data transfers |
| 169 | on an bulk-in endpoint. |
| 170 | |
| 171 | Data structures: |
| 172 | struct rmnet_sdio_qmi_buf - Buffer to handle QMI requests/responses. |
| 173 | struct rmnet_dev - Endpoint and driver specific data |
| 174 | |
| 175 | Workqueues: |
| 176 | rmnet_connect_work - Device connection handler. Opens SDIO |
| 177 | channels; enables and allocate buffer for |
| 178 | endpoints |
| 179 | rmnet_disconnect_work - Device disconnection handler. Closes |
| 180 | SDIO channels; Frees allocated buffers. |
| 181 | rmnet_control_rx_work - Control data reception handler. |
| 182 | rmnet_data_rx_work - Network data reception handler. |
| 183 | |
| 184 | |
| 185 | Two SMD/SDIO channels (control and data) are used as communication channels |
| 186 | between Modem and Apps processor. The driver opens the SMD/SDIO channels |
| 187 | on USB device connection. Data is either read from/written to the channels |
| 188 | as one complete packet. |
| 189 | |
| 190 | SMD/SDIO provides a notification whenever the Modem processor completes |
| 191 | read/write of a packet. Based on these SMD/SDIO notifications all the |
| 192 | pending read/write requests will be handled. Tasklets(SMD)/Workqueues(SDIO) |
| 193 | are used to get the requests done. |
| 194 | |
| 195 | There is another variant of rmnet driver called rmnet_smd_sdio which is used |
| 196 | on some boards. This driver allows the transport (SMD/SDIO) to be chosen |
| 197 | at runtime. This is required because either MDM processor or MODEM processor |
| 198 | is only active at a time for data transfers. As SMD and SDIO interfaces |
| 199 | are different, different endpoint completion handlers are used. This driver |
| 200 | leverage the existing rmnet over smd and rmnet over sdio drivers. The control |
| 201 | messages (QMI) always routed over SDIO. After the control messages exchange, |
| 202 | user space will come to know about the available data transport (SMD/SDIO). |
| 203 | User space notify the same to driver and the corresponding transport is |
| 204 | activated. It is assumed that transport will not change while a USB cable |
| 205 | is connected. |
| 206 | |
| 207 | Rmnet over SMD and rmnet over SDIO doesn't expose any of its interfaces to |
| 208 | either kernelspace or userspace. But rmnet over smd/sdio expose a sysfs |
| 209 | interface for userspace to notify the available transport to driver. |
| 210 | |
| 211 | The sysfs file can be found at |
| 212 | /sys/class/usb_composite/rmnet_smd_sdio/transport |
| 213 | |
| 214 | The below command activates the SMD transport |
| 215 | echo 0 > /sys/class/usb_composite/rmnet_smd_sdio/transport |
| 216 | |
| 217 | The below command activates the SDIO transport |
| 218 | echo 1 > /sys/class/usb_composite/rmnet_smd_sdio/transport |
| 219 | |
| 220 | -EINVAL is returned if a write is attempted to transport when a USB cable |
| 221 | is not connected. |
| 222 | |