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 | |
---|
15 | static XMbox* xmbox_ptr; |
---|
16 | static platform_common_dev_info_t platform_common_dev_info; |
---|
17 | static platform_high_dev_info_t platform_high_dev_info; |
---|
18 | |
---|
19 | // IPC variables |
---|
20 | static wlan_ipc_msg_t ipc_msg_from_low; ///< IPC message from lower-level |
---|
21 | static u32 ipc_msg_from_low_payload[MAILBOX_MSG_MAX_NUM_WORDS]; ///< Buffer space for IPC message from lower-level |
---|
22 | |
---|
23 | void _mailbox_rx_watchdog(u32 timer_id); |
---|
24 | |
---|
25 | void 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 | */ |
---|
45 | void 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 | *****************************************************************************/ |
---|
59 | int 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 | *****************************************************************************/ |
---|
92 | void 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 | |
---|
136 | void _mailbox_rx_watchdog(u32 timer_id){ |
---|
137 | wlan_mac_high_ipc_rx(); |
---|
138 | } |
---|