source: ReferenceDesigns/w3_802.11/c/wlan_mac_high_framework/wlan_mac_high_mailbox_util.c

Last change on this file was 6319, checked in by chunter, 5 years ago

1.8.0 release wlan-mac-se

File size: 5.0 KB
Line 
1#include "xmbox.h"
2
3#include "wlan_mac_common.h"
4#include "wlan_mac_high.h"
5#include "wlan_mac_high_mailbox_util.h"
6#include "wlan_mac_mailbox_util.h"
7#include "wlan_platform_common.h"
8#include "wlan_platform_high.h"
9#include "wlan_mac_schedule.h"
10
11
12#define MAILBOX_RIT 0 /* mailbox receive interrupt threshold */
13#define MAILBOX_SIT 0 /* mailbox send interrupt threshold */
14
15static XMbox* xmbox_ptr;
16static platform_common_dev_info_t platform_common_dev_info;
17static platform_high_dev_info_t platform_high_dev_info;
18
19// IPC variables
20static wlan_ipc_msg_t ipc_msg_from_low;                                           ///< IPC message from lower-level
21static u32 ipc_msg_from_low_payload[MAILBOX_MSG_MAX_NUM_WORDS];     ///< Buffer space for IPC message from lower-level
22
23void _mailbox_rx_watchdog(u32 timer_id);
24
25void wlan_mac_high_init_mailbox(){
26
27    xmbox_ptr = init_mailbox();
28
29    //Create IPC message to receive into
30    ipc_msg_from_low.payload_ptr = &(ipc_msg_from_low_payload[0]);
31
32    platform_common_dev_info = wlan_platform_common_get_dev_info();
33    platform_high_dev_info   = wlan_platform_high_get_dev_info();
34}
35
36/**
37 * @brief WLAN MAC IPC receive
38 *
39 * IPC receive function that will poll the mailbox for as many messages as are
40 * available and then call the CPU high IPC processing function on each message
41 *
42 * @param  None
43 * @return None
44 */
45void wlan_mac_high_ipc_rx(){
46    while (read_mailbox_msg(&ipc_msg_from_low) == IPC_MBOX_SUCCESS) {
47        wlan_mac_high_process_ipc_msg(&ipc_msg_from_low, ipc_msg_from_low_payload);
48    }
49}
50
51/*****************************************************************************/
52/**
53 * Setup mailbox interrupt
54 *
55 * @return  int              - Status:
56 *                                 WLAN_SUCCESS - Command completed successfully
57 *                                 WLAN_FAILURE - Command failed
58 *****************************************************************************/
59int setup_mailbox_interrupt() {
60    int status;
61
62    // Set Send / Receive threshold for interrupts
63    XMbox_SetSendThreshold(xmbox_ptr, MAILBOX_SIT);
64    XMbox_SetReceiveThreshold(xmbox_ptr, MAILBOX_RIT);
65
66    // Connect interrupt handler
67    status = wlan_platform_interrupt_connect(platform_high_dev_info.mailbox_int_id, (wlan_intr_handler_t)mailbox_int_handler, xmbox_ptr);
68
69    if (status != WLAN_SUCCESS) {
70        return WLAN_FAILURE;
71    }
72
73    // Enable interrupt
74    XMbox_SetInterruptEnable(xmbox_ptr, XMB_IX_RTA);
75    wlan_platform_interrupt_enable(platform_high_dev_info.mailbox_int_id);
76
77    // Enable watchdog - checks for (unlikely but not impossible) mailbox messages received without
78    //  interrupt assertion
79    wlan_mac_schedule_add_event(SCHEDULE_ID_COARSE, 200000, SCHEDULE_REPEAT_FOREVER, (void*)_mailbox_rx_watchdog);
80
81    return WLAN_SUCCESS;
82}
83
84
85/*****************************************************************************/
86/**
87 * Mailbox interrupt handler
88 *
89 * @param   callback_ref     - Callback reference (set by interrupt framework)
90 *
91 *****************************************************************************/
92void mailbox_int_handler(void* callback_ref){
93    u32 mask;
94    XMbox* mbox_ptr = (XMbox *)callback_ref;
95
96#ifdef _ISR_PERF_MON_EN_
97    wlan_mac_set_dbg_hdr_out(ISR_PERF_MON_GPIO_MASK);
98#endif
99
100    // First, we raise the receive threshold to its maximum value. The argument to the function
101    // is a u32, but only the lower log2(FIFO Depth) bits are used
102    XMbox_SetReceiveThreshold(xmbox_ptr, 0xFFFFFFFF);
103
104    // Get the interrupt status
105    mask = XMbox_GetInterruptStatus(mbox_ptr);
106
107    // If this is a receive interrupt, then call the callback function
108    if (mask & XMB_IX_RTA) {
109        wlan_mac_high_ipc_rx();
110    }
111
112    // It is technically possible that the mailbox could become full and
113    // abandoned if the FIFO transitions from empty to completely full
114    // at this part of the code before the following XMbox_ClearInterrupt
115    // call. Under normal circumstanced, this is impossible. However, if
116    // the debugger were to pause operation of the processor at this point,
117    // it is conceivable that the bug could be exercised. The fix for this
118    // event is the periodic call to the _mailbox_rx_watchdog() function.
119
120    // Clear the interrupt
121    //     - Since only the XMB_IX_RTA interrupt was enabled in setup_mailbox_interrupt()
122    //       that is the only interrupt that will ever need to be cleared
123    XMbox_ClearInterrupt(mbox_ptr, XMB_IX_RTA);
124
125    // Drop the receive threshold to its correct value. The purpose of this is to avoid a race condition
126    // that could occur if a reception occurs in between the call to wlan_mac_high_ipc_rx() and XMbox_ClearInterrupt().
127    // By lowering the threshold, we will force another interrupt in that scenario.
128    XMbox_SetReceiveThreshold(xmbox_ptr, MAILBOX_RIT);
129
130#ifdef _ISR_PERF_MON_EN_
131    wlan_mac_clear_dbg_hdr_out(ISR_PERF_MON_GPIO_MASK);
132#endif
133}
134
135
136void _mailbox_rx_watchdog(u32 timer_id){
137    wlan_mac_high_ipc_rx();
138}
Note: See TracBrowser for help on using the repository browser.