| Introduction |
| ============ |
| |
| The BAM data mux (bam_dmux) is a kernel module that facilitates |
| communication between the existing RMNET driver and the Bus Access |
| Manager (BAM) driver for LTE data connections. |
| |
| Software description |
| ==================== |
| |
| The bam_dmux will follow the design and implementation of the sdio_dmux |
| (already present in older platforms) and provide identical functionality |
| where applicable. |
| |
| The bam_dmux driver will consist of a small transport abstraction layer |
| for RMNET in drivers/net/ and the core functionality will exist in |
| drivers/soc/qcom/. The core functionality of the bam_dmux module is |
| to mux one bam channel into eight logical channels for use by RMNET. |
| |
| |
| ------------------------------------------------- |
| | | |
| | IP Framework | |
| | | |
| ------------------------------------------------- |
| | | | | | | |
| | Rmnet | Rmnet | | Rmnet | Rmnet | |
| | Dev 0 | Dev 1 | ... | Dev 6 | Dev 7 | |
| | | | | | | |
| ----------------- ----------------- |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| ------------------------------------------------- |
| | | |
| | BAM Data Multiplexer | |
| | | |
| ------------------------------------------------- |
| | |
| | |
| | |
| ----------------- |
| | | |
| | BAM | |
| | | |
| ----------------- |
| |
| Uplink data packets from a RMNET logical channel will have a mux packet |
| header added to the top (identical to sdio_dmux), sent over BAM to the |
| A2 module on the modem, where the packets will be de-muxed and processed. |
| Downlink data packets will arive over BAM from A2, be de-muxed, have the |
| mux header stripped and handed to RMNET via the logical channel indicated |
| in the mux header. |
| |
| Logical channels will be established using the same handshake protocol |
| used in sdio_dmux. |
| |
| Identical to sdio_dmux, a workqueue will be spawned during module |
| initialization for the purpose of processing data from clients to prevent |
| blocking, and to process data from BAM. |
| |
| Design |
| ====== |
| |
| The goal of this design is to provide an interface to BAM for RMNET to |
| achieve LTE data rates of 100 megabits per second. The sdio_dmux |
| module already achieves this goal over SDIO, so its design was repurposed |
| to achieve the same over the BAM transport. |
| |
| The basic use case for a logical channel would be |
| |
| 1. for the client to register a platform driver on the logical channel. |
| When the bam_dmux driver is ready, it will register platform |
| devices for all the logical channels. This will cause the probe |
| functions of all registered platform drivers to be invoked. |
| |
| 2. Once invoked, the probe function can open a logical channel. |
| |
| 3. After that, the client is free to queue data to be transmitted via the |
| bam_dmux driver's write function. |
| |
| 4. Received data will be sent to the client via the callback function |
| registered at open(). |
| |
| SMP/multi-core |
| ============= |
| |
| A number of data structures internal to the driver will store state, and |
| will need to be protected against concurrent updates from multiple threads |
| and interrupt handlers. Any structures that may be used in interrupt |
| context will be protected with spinlocks, otherwise mutexes will suffice. |
| |
| Performance |
| =========== |
| |
| The expected data rate of traffic through bam_dmux is 100 megabits per |
| second. The expected data rate per logical channel is 100/N megabits per |
| second where N is the number of logical channels with active data at |
| that point in time, depending on system load. |
| |
| Interface |
| ========= |
| |
| Bam_dmux will provide a simple API to kernel clients. |
| |
| Open: |
| |
| int msm_bam_dmux_open(uint32_t id, void *priv, |
| void (*receive_cb)(void *, struct sk_buff *) |
| void (*write_done)(void *, struct sk_buff *)); |
| |
| id - id of the channel to open |
| priv - private data pointer for the client, passed to the callbacks |
| receive_cb - callback function. Invoked when data is read from BAM. |
| Private data pointer and the data read are given as parameters. |
| client must free sk_buff structure when done with the data. |
| write_done - callback function. Invoked when data is successfully |
| transmitted over BAM. Private data pointer and the data |
| transmitted are given as parameters. |
| return - 0 on success or negative value indicating error type |
| |
| Close: |
| |
| int msm_bam_dmux_close(uint32_t id); |
| |
| id - id of an open channel to close |
| return - 0 on success or negative value indicating error type |
| |
| Write: |
| |
| int msm_bam_dmux_write(uint32_t id, struct sk_buff *skb); |
| |
| id - id of an open channel to queue data for transmit |
| skb - data packet to transmit |
| return - 0 on success or negative value indicating error type |
| |
| A debugfs node (bam_dmux) will be created with two subnodes within (tbl, |
| loopback_test). The first node (tbl) will display diagnostic information |
| such as the state of the logical channels and the amount of data |
| read/transmitted. The second node (loopback_test) will provide a simple |
| mechanism for putting the module into a loopback mode for functional testing. |
| |
| Dependencies |
| ============ |
| |
| The bam_dmux requires the BAM driver. It will communicate with the |
| A2 module on the modem through BAM for the purpose of transferring LTE rate |
| data from RMNET to the modem. |
| |
| The bam_dmux driver depends on the socket buffer data structure which is |
| provided as part of the standard linux kernel. |