source: ReferenceDesigns/w3_802.11/c/wlan_mac_common_framework/wlan_mac_common.c

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

1.8.0 release wlan-mac-se

File size: 10.7 KB
Line 
1/** @file wlan_mac_common.c
2 *  @brief Common Code
3 *
4 *  This contains code common to both CPU_LOW and CPU_HIGH.
5 *
6 *  @copyright Copyright 2013-2019, Mango Communications. All rights reserved.
7 *          Distributed under the Mango Communications Reference Design License
8 *                See LICENSE.txt included in the design archive or
9 *                at http://mangocomm.com/802.11/license
10 *
11 *  This file is part of the Mango 802.11 Reference Design (https://mangocomm.com/802.11)
12 */
13
14/***************************** Include Files *********************************/
15
16#include "stdlib.h"
17#include "string.h"
18
19#include "xil_io.h"
20#include "xstatus.h"
21#include "xparameters.h"
22
23#include "wlan_platform_common.h"
24#include "wlan_mac_common.h"
25#include "wlan_mac_802_11_defs.h"
26
27/*********************** Global Variable Definitions *************************/
28
29extern int __malloc_sbrk_base; ///< Internal malloc variable in .data
30extern int __malloc_trim_threshold; ///< Internal malloc variable in .data
31extern int __malloc_av_; ///< Internal malloc variable in .data
32
33
34/*************************** Variable Definitions ****************************/
35
36static wlan_mac_hw_info_t mac_hw_info;
37
38
39/*************************** Functions Prototypes ****************************/
40
41
42/******************************** Functions **********************************/
43
44/**
45 * @brief Initialize Malloc
46 *
47 * Dynamic memory allocation through malloc uses metadata in the data section
48 * of the elf binary. This metadata is not reset upon software reset (i.e., when a
49 * user presses the reset button on the hardware). This will cause failures on
50 * subsequent boots because this metadata has not be reset back to its original
51 * state at the first boot.
52 *
53 * This function explicitly overwrites the relevant pieces of the data section
54 * with a good default state for malloc. The initial values of the variables
55 * __malloc_sbrk_base, __malloc_trim_threshold, and __malloc_av__ can be found
56 * here: https://github.com/Xilinx/newlib/blob/xsdk_14.4/newlib/libc/stdlib/mallocr.c
57 *
58 * @param None
59 * @return None
60 *
61 * @note This function should be the first thing called after boot. If it is
62 * called after other parts have the code have started dynamic memory access,
63 * there will be unpredictable results on software reset.
64 */
65void wlan_mac_common_malloc_init(){
66    u32  i, val;
67    u32* malloc_sbrk_base_ptr;
68    u32* malloc_trim_threshold_ptr;
69    u32* malloc_av_ptr;
70
71    malloc_sbrk_base_ptr = (u32*)&__malloc_sbrk_base;
72    malloc_trim_threshold_ptr = (u32*)&__malloc_trim_threshold;
73    malloc_av_ptr = (u32*)&__malloc_av_;
74
75    malloc_sbrk_base_ptr[0] = 0xFFFFFFFF;
76
77    malloc_trim_threshold_ptr[0] = 0x00020000;
78
79    malloc_av_ptr[0] = 0;
80    malloc_av_ptr[1] = 0;
81
82    val = 0;
83    for(i=2; i<258; i+=2){
84        malloc_av_ptr[i] = (u32)((char*)(&malloc_av_ptr[2*val+2])) - 2*sizeof(size_t);
85        malloc_av_ptr[i+1] = malloc_av_ptr[i];
86        val++;
87    }
88}
89
90
91/*****************************************************************************/
92/**
93 * Null Callback
94 *
95 * This function will always return WLAN_SUCCESS and should be used to initialize
96 * callbacks.  All input parameters will be ignored.
97 *
98 * @param   param            - Void pointer for parameters
99 *
100 * @return  int              - Status:
101 *                                 WLAN_SUCCESS - Command completed successfully
102 *****************************************************************************/
103int wlan_null_callback(void* param) {
104    return WLAN_SUCCESS;
105}
106
107
108
109/*****************************************************************************/
110/**
111 * Verify channel is supported
112 *
113 * @param   channel          - Channel to verify
114 *
115 * @return  int              - Channel supported?
116 *                                 WLAN_SUCCESS - Channel supported
117 *                                 WLAN_FAILURE - Channel not supported
118 *****************************************************************************/
119int wlan_verify_channel(u32 channel) {
120    int return_value;
121
122    // The 802.11 reference design allows a subset of 2.4 and 5 GHz channels
123    //     Channel number follows 802.11 conventions:
124    //         https://en.wikipedia.org/wiki/List_of_WLAN_channels
125    //
126#if 1
127    switch (channel) {
128        // 2.4GHz channels
129        case 1:
130        case 2:
131        case 3:
132        case 4:
133        case 5:
134        case 6:
135        case 7:
136        case 8:
137        case 9:
138        case 10:
139        case 11:
140        // 5GHz channels
141        case 36:
142        case 40:
143        case 44:
144        case 48:
145            return_value = WLAN_SUCCESS;
146        break;
147        default:
148            return_value = WLAN_FAILURE;
149        break;
150    }
151#else
152    switch (channel) {
153            // 2.4GHz channels
154            case 1:
155            case 2:
156            case 3:
157            case 4:
158            case 5:
159            case 6:
160            case 7:
161            case 8:
162            case 9:
163            case 10:
164            case 11:
165            // 5GHz channels
166            case 36: // 5180 MHz
167            case 38: // 5190 MHz
168            case 40: // 5200 MHz
169            case 44: // 5220 MHz
170            case 46: // 5230 MHz
171            case 48: // 5240 MHz
172            case 52: // 5260 MHz
173            case 54: // 5270 MHz
174            case 56: // 5280 MHz
175            case 60: // 5300 MHz
176            case 62: // 5310 MHz
177            case 64: // 5320 MHz
178            case 100: // 5500 MHz
179            case 102: // 5510 MHz
180            case 104: // 5520 MHz
181            case 108: // 5540 MHz
182            case 110: // 5550 MHz
183            case 112: // 5560 MHz
184            case 116: // 5580 MHz
185            case 118: // 5590 MHz
186            case 120: // 5600 MHz
187            case 124: // 5620 MHz
188            case 126: // 5630 MHz
189            case 128: // 5640 MHz
190            case 132: // 5660 MHz
191            case 134: // 5670 MHz
192            case 136: // 5680 MHz
193            case 140: // 5700 MHz
194            case 142: // 5710 MHz
195            case 144: // 5720 MHz
196            case 149: // 5745 MHz
197            case 151: // 5755 MHz
198            case 153: // 5765 MHz
199            case 157: // 5785 MHz
200            case 159: // 5795 MHz
201            case 161: // 5805 MHz
202            case 165: // 5825 MHz
203            case 172: // 5860 MHz
204            case 174: // 5870 MHz
205            case 175: // 5875 MHz
206            case 176: // 5880 MHz
207            case 177: // 5885 MHz
208            case 178: // 5890 MHz
209                return_value = WLAN_SUCCESS;
210            break;
211            default:
212                xil_printf("ERROR (wlan_verify_channel): Channel %d invalid\n", channel);
213                return_value = WLAN_FAILURE;
214            break;
215        }
216#endif
217
218    return return_value;
219}
220
221
222/*****************************************************************************/
223/**
224 * Initialize the MAC Hardware Info
225 *
226 * This function will initialize the MAC hardware information structure for
227 * the CPU based on information contained in the EEPROM and the wlan_exp_type
228 * provided.  This function should only be called after the EEPROM has been
229 * initialized.
230 *
231 * @param   None
232 *
233 *****************************************************************************/
234void init_mac_hw_info() {
235    mac_hw_info = wlan_platform_get_hw_info();
236}
237
238time_hr_min_sec_t wlan_mac_time_to_hr_min_sec(u64 time) {
239    time_hr_min_sec_t time_hr_min_sec;
240    u64 time_sec;
241    u32 remainder;
242
243    time_sec = time / 1e6;
244    remainder = time_sec % 3600;
245
246    time_hr_min_sec.hr = time_sec / 3600;
247    time_hr_min_sec.min = remainder / 60;
248    time_hr_min_sec.sec = remainder % 60;
249
250    return time_hr_min_sec;
251}
252
253/*****************************************************************************/
254/**
255 * Common Packet Contructors
256 *
257 * Control packets need to be created by both CPU_HIGH and CPU_LOW, so their
258 * constructors are placed here in the common MAC framework.
259 *
260 *****************************************************************************/
261int wlan_create_rts_frame(u8* pkt,
262                          u8* address_ra,
263                          u8* address_ta,
264                          u16 duration) {
265    mac_header_80211_RTS* rts_header;
266
267    if(pkt == NULL) return WLAN_FAILURE;
268
269    rts_header = (mac_header_80211_RTS*)(pkt);
270
271    rts_header->frame_control_1 = MAC_FRAME_CTRL1_SUBTYPE_RTS;
272    rts_header->frame_control_2 = 0;
273    rts_header->duration_id = duration;
274    memcpy(rts_header->address_ra, address_ra, MAC_ADDR_LEN);
275    memcpy(rts_header->address_ta, address_ta, MAC_ADDR_LEN);
276
277    //Include FCS in packet size (MAC accounts for FCS, even though the PHY calculates it)
278    return (sizeof(mac_header_80211_RTS)+WLAN_PHY_FCS_NBYTES);
279}
280
281int wlan_create_cts_frame(u8* pkt,
282                          u8* address_ra,
283                          u16 duration) {
284    mac_header_80211_CTS* cts_header;
285
286    if(pkt == NULL) return WLAN_FAILURE;
287
288    cts_header = (mac_header_80211_CTS*)(pkt);
289
290    cts_header->frame_control_1 = MAC_FRAME_CTRL1_SUBTYPE_CTS;
291    cts_header->frame_control_2 = 0;
292    cts_header->duration_id = duration;
293    memcpy(cts_header->address_ra, address_ra, MAC_ADDR_LEN);
294
295    //Include FCS in packet size (MAC accounts for FCS, even though the PHY calculates it)
296    return (sizeof(mac_header_80211_CTS)+WLAN_PHY_FCS_NBYTES);
297}
298
299int wlan_create_ack_frame(void* pkt,
300                          u8* address_ra) {
301    mac_header_80211_ACK* ack_header;
302
303    if(pkt == NULL) return WLAN_FAILURE;
304
305    ack_header = (mac_header_80211_ACK*)(pkt);
306
307    ack_header->frame_control_1 = MAC_FRAME_CTRL1_SUBTYPE_ACK;
308    ack_header->frame_control_2 = 0;
309    ack_header->duration_id = 0;
310    memcpy(ack_header->address_ra, address_ra, MAC_ADDR_LEN);
311
312    //Include FCS in packet size (MAC accounts for FCS, even though the PHY calculates it)
313    return (sizeof(mac_header_80211_ACK)+WLAN_PHY_FCS_NBYTES);
314}
315
316
317// Many Xilinx drivers use Xil_Assert to validate inputs
318// By default a failed assertion will halt the CPU quietly
319// This function can be assigned via Xil_AssertSetCallback() to print
320//  the file/line number of a failing assertion before the CPU halts
321void wlan_assert_print(const char *FilenamePtr, int LineNumber) {
322    xil_printf("ASSERT: File Name: %s ", FilenamePtr);
323    xil_printf("Line Number: %d\r\n", LineNumber);
324}
325
326/*****************************************************************************/
327/**
328 * Get the MAC Hardware Info
329 *
330 * Return the MAC hardware information structure.  This should only be used
331 * after the structure is initialized.
332 *
333 * @return  wlan_mac_hw_info_t *  - Pointer to HW info structure
334 *
335 *****************************************************************************/
336wlan_mac_hw_info_t* get_mac_hw_info() { return &mac_hw_info; }
337u8* get_mac_hw_addr_wlan() { return mac_hw_info.hw_addr_wlan; }
338u8* get_mac_hw_addr_wlan_exp() { return mac_hw_info.hw_addr_wlan_exp; }
339
Note: See TracBrowser for help on using the repository browser.