3.3. mango_wlan_msg_fifo Kernel Module

The mango_wlan_msg_fifo kernel module implements a bi-directional message FIFO to facilitate communication between the kernel and the Mango 802.11 MAC software. The mango_wlan driver uses this message FIFO to communicate with the MAC. Other kernel modules can also use the FIFO to exchange messages with custom extensions of the MAC software that bypass the mango_wlan module.

Device Tree Requirements

The mango_wlan_msg_fifo module must be configured via a node in the device tree. The device tree node specifies the physical memory address and interrupt ID of the mailbox core in the PL design and the memory address of the LPD DMA channel dedicated to the message FIFO.

By default the module declares a compatible string of mango,wlan-msg-fifo-1.0. This string can be overridden at compile time by defining the DT_COMPAT_OVERRIDE macro with the desired compatible string.

Example message FIFO device tree node for MPSoC platforms:

# 0x00_B1000000 is 64-bit physical address of mailbox core in PL
# Interrupt ID 89 is PL-PS interrupt from mailbox core in PL
# 0x00_FFAC0000 is 64-bit physical address of LPD DMA channel #7
# &gic is label for APU interrupt controller in device tree
mango_wlan_msg_fifo {
    status = "okay";
    compatible = "mango,wlan-msg-fifo-1.0";
    interrupt-parent = <&gic>;
    interrupts = <0 89 4>;
    reg = <0x0 0xb1000000 0x0 0x4000>,<0x0 0xffac0000 0x0 0x1000>;
};

Example message FIFO device tree node for Zynq-7000 platforms:

# 0x81000000 is 32-bit physical address of mailbox core in PL
# Interrupt ID 29 is PL-PS interrupt from mailbox core in PL
# &intc is label for PS interrupt controller in device tree
mango_wlan_msg_fifo {
    status = "okay";
    compatible = "mango,wlan-msg-fifo-1.0";
    interrupt-parent = <&intc>;
    interrupts = <0 29 4>;
    reg = <0x81000000 0x4000>;
};

API

The mango_wlan_msg_fifo module implements a simple API for exchanging messages with the MAC. The API uses exported symbols that can be called directly from other kernel code. The mango_wlan module uses this API for all communication with the MAC. Custom kernel modules can use the API at the same time to communicate with custom code added to the MAC software.

The msg_fifo API defines two uni-directional channels:

  • MAC-to-Driver (mtod): messages from the MAC to the kernel drivers
  • Driver-to-MAC (dtom): messages from the kernel drivers to the MAC

The mtod and dtom labels identify these channels throughout the msg_fifo code.

Each kernel module which uses the msg_fifo API must declare a unique message group ID when registering a callback function to handle custom MAC-to-driver messages. ID 0 is reserved and ID 1 is used by mango_wlan. Other group IDs are available for custom extensions of the MAC design.

The message FIFO API consists of two functions:

/**
 * @brief Sets callback for MAC-to-Driver message Rx
 *
 * The caller (custom kernel module) must define a function to handle new
 * MAC-to-Driver messages for the specified group ID. The callback function
 * has prototype:
 *   void mtod_msg_rx_callback(int msg_len, void* msg);
 *
 * @param int grp_id
 *  - Arbitrary group ID selected by caller; group IDs 0 and 1 are reserved
 * @param recv_callback
 *  - Function pointer for mtod message Rx callback implemented by caller
 *
 * @return WLAN_SUCCESS or nonzero WLAN_FAILURE
 */
int mango_wlan_msg_fifo_set_mtod_recv_callback(int grp_id,
                                               void (*recv_callback)(int msg_len,
                                                                     void *msg));
/**
 * @brief Sends a new Driver-to-MAC message
 *
 * Sends a new Driver-to-MAC message with group ID grp_id. This grp_id must
 * match the group ID passed to mango_wlan_msg_fifo_set_mtod_recv_callback().
 *
 * @param int grp_id
 *  - Arbitrary group ID selected by caller; group IDs 0 and 1 are reserved
 * @param int msg_len
 *  - Length of message in bytes
 * @param void *msg
 *  - Pointer to message
 * @param bool use_dma)
 *  - Boolean flag indicating whether the msg_fifo module should use the platform
 *    DMA controller to read the message into the mailbox. The caller should only
 *    set use_dma=1 when the msg is stored in memory accessible by the DMA controller.
 *
 * @return WLAN_SUCCESS or nonzero WLAN_FAILURE
 */
int mango_wlan_msg_fifo_send_dtom_msg(int grp_id,
                                      int msg_len,
                                      void *msg,
                                      bool use_dma);