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

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

1.8.0 release wlan-mac-se

File size: 23.7 KB
Line 
1/** @file wlan_mac_queue.c
2 *  @brief Queue Framework
3 *
4 *  This contains code for accessing the packet queue.
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 "wlan_mac_high_sw_config.h"
17
18// Xilinx / Standard library includes
19#include "xil_types.h"
20#include "stdlib.h"
21#include "stdio.h"
22#include "wlan_platform_high.h"
23#include "string.h"
24
25// WLAN includes
26#include "wlan_mac_common.h"
27#include "wlan_mac_high.h"
28#include "wlan_mac_queue.h"
29#include "wlan_mac_dl_list.h"
30#include "wlan_mac_eth_util.h"
31#include "wlan_mac_pkt_buf_util.h"
32#include "wlan_platform_common.h"
33#include "wlan_mac_station_info.h"
34
35// WLAN Exp includes
36#include "wlan_exp_common.h"
37
38#define ADDRESS_SAFETY_CHECKS 0
39
40
41/************************** Locally Scoped Types *************************************/
42typedef struct _queue_t {
43    dl_list list;
44    u32 flags;
45    function_ptr_t queue_state_change_callback;
46    u32 callback_arg;
47    u32 max_len;
48} _queue_t;
49
50#define _QUEUE_FLAGS_OPEN 0x00000001
51
52/********************** Externed Global Variable Definitions *************************/
53
54// User callback to see if the higher-level framework can send a packet to
55// the lower-level framework to be transmitted.
56extern platform_common_dev_info_t platform_common_dev_info;
57extern platform_high_dev_info_t platform_high_dev_info;
58
59/**************** Locally Scoped Global Variable Definitions *************************/
60
61// List to hold all of the empty, free entries
62static dl_list _free_queue;
63
64// The queue_array variable is an array of lists that will be filled with queue
65// entries from the free_queue list
66//
67// NOTE:  This implementation sparsely packs the queue_array array to allow fast
68//     indexing at the cost of some wasted memory.
69
70static _queue_t* _queue_array;
71static u16 _num_queues;
72
73// Total number of queue entries
74static volatile u32 _total_queue_entries;
75
76/*****************************************************************************/
77/**
78 * @brief  Initialize the queue framework
79 *
80 * The number of queue elements we can initialize is limited by the smaller of two values:
81 *     (1) The number of dl_entry structs we can squeeze into QUEUE_DL_ENTRY_MEM_SIZE
82 *     (2) The number of QUEUE_BUFFER_SIZE MPDU buffers we can squeeze into QUEUE_BUFFER_SIZE
83 *
84 * @param  u8 dram_present        - Flag to indicate if DRAM is present
85 *                                  (1 = present; other = not present)
86 *
87 *****************************************************************************/
88void queue_init() {
89    u32 i;
90    dl_entry* dl_entry_base;
91
92    // Set the total number of supported queue entries
93    _total_queue_entries = WLAN_MIN((QUEUE_DL_ENTRY_MEM_SIZE / sizeof(dl_entry)), // Max dl_entry
94                                    (QUEUE_BUFFER_SIZE / QUEUE_ELEMENT_SIZE));    // Max buffers
95
96    // Initialize the queue_array
97    //     NOTE:  queue_array is initially NULL because it will be dynamically allocated and
98    //         initialized.
99    //
100    _queue_array = NULL;
101    _num_queues = 0;
102
103    // Initialize the free queue
104    dl_list_init(&_free_queue);
105
106    // Zero all queue elements
107    bzero((void*)QUEUE_BUFFER_BASE, QUEUE_BUFFER_SIZE);
108
109    // Allocate the memory space into queue entries
110    //
111    // All queue entries are initially part of the free queue.  Each queue entry consists of:
112    //     (1) Buffer to hold data
113    //     (2) dl_entry to describe the buffer
114    //
115    // NOTE:  The code below exploits the fact that the starting state of all queue entries is
116    //     sequential.  Therefore, it can use matrix addressing.  Matrix addressing is not safe
117    //     once the queue is used and the insert/remove helper functions should be used instead.
118    //
119    dl_entry_base = (dl_entry*)(QUEUE_DL_ENTRY_MEM_BASE);
120
121    for (i = 0; i < _total_queue_entries; i++) {
122        // Segment the buffer in QUEUE_BUFFER_SIZE pieces
123        dl_entry_base[i].data = (void*)(QUEUE_BUFFER_BASE + (i * QUEUE_ELEMENT_SIZE));
124
125        // Copy the pointer to the dl_entry into the DRAM payload. This will allow any context
126        // (like Ethernet Rx) to find the dl_entry that points to a given DRAM payload
127        ((pkt_queue_buffer_t*)(dl_entry_base[i].data))->pyld_queue_hdr.dle = &(dl_entry_base[i]);
128
129        // Insert new dl_entry into the free queue
130        dl_entry_insertEnd(&_free_queue, &(dl_entry_base[i]));
131    }
132
133    // Print status
134    xil_printf("Allocated %d queue buffers in DRAM using %d kB\n", _total_queue_entries,
135                                                           ((_total_queue_entries * QUEUE_ELEMENT_SIZE) / 1024));
136}
137
138/*****************************************************************************/
139/**
140 * @brief Open a queue
141 *
142 * This function will open a queue and return a QID that can be used by the
143 * calling context to enqueue and dequeue items.
144 *
145 * @param function_ptr_t queue_state_change_callback - function that the framework
146 *        should call when the newly-opened queue transitions from empty to
147 *        non-empty or vice versa
148 *
149 * @param u32 callback_arg - argument provided to callback
150 *
151 * @param u32 max_len - maximum length of queue. 0 means unlimited.
152 *
153 * @return int -1 if error, QID otherwise
154 *
155 *****************************************************************************/
156int queue_open(function_ptr_t queue_state_change_callback, u32 callback_arg, u32 max_len){
157    u32 i;
158
159    // First, we will search through the existing array to see if any queues
160    //  have been closed and can be re-used
161
162    for(i = 0; i < _num_queues; i++){
163        if( (_queue_array[i].flags & _QUEUE_FLAGS_OPEN) == 0){
164            _queue_array[i].flags |= _QUEUE_FLAGS_OPEN;
165            _queue_array[i].queue_state_change_callback = queue_state_change_callback;
166            _queue_array[i].callback_arg = callback_arg;
167            _queue_array[i].max_len = max_len;
168            return i;
169        }
170    }
171
172    // Otherwise, we need to reallocate the array to make a new queue
173
174    _queue_array = wlan_mac_high_realloc(_queue_array, ((_num_queues + 1) * sizeof(_queue_t)));
175
176    if(_queue_array == NULL){
177        xil_printf("Queue error: Unable to reallocate queue array. Check heap usage\n");
178        return WLAN_FAILURE;
179    }
180
181    i = _num_queues;
182
183    // Increment the number of queues
184    _num_queues++;
185
186
187    // Initialize the dl_list in the newly allocated space
188    dl_list_init(&(_queue_array[i].list));
189
190    // Set queue metadata
191    _queue_array[i].flags |= _QUEUE_FLAGS_OPEN;
192    _queue_array[i].queue_state_change_callback = queue_state_change_callback;
193    _queue_array[i].callback_arg = callback_arg;
194    _queue_array[i].max_len = max_len;
195
196    // Return the new QID (which is 0 indexed, so it is length-1)
197    return (i);
198}
199
200/*****************************************************************************/
201/**
202 * @brief Set maximum queue length
203 *
204 * This function will set a new maximum queue length in the provided queue.
205 *
206 * @param u32 max_len - maximum length of queue
207 *
208 * @return int WLAN_SUCCESS or WLAN_FAILURE
209 *
210 *****************************************************************************/
211int queue_set_max_len(int queue_id, u32 max_len){
212    if ((queue_id + 1) > _num_queues) {
213        xil_printf("ERROR (queue_set_max_len): queue_id %d out of range\n", queue_id);
214        return WLAN_FAILURE;
215    }
216
217    _queue_array[queue_id].max_len = max_len;
218
219    return WLAN_SUCCESS;
220}
221
222/*****************************************************************************/
223/**
224 * @brief Close a queue
225 *
226 * This function will close the provided QID so it can be re-opened in the future.
227 * This function will return an error if the queue has occupancy. It will not
228 * implicitly purge the contents of the queue.
229 *
230 * @param int queue_id - queue selection index (returned from queue_open)
231 *
232 * @return int WLAN_SUCCESS or WLAN_FAILURE
233 *
234 *****************************************************************************/
235int queue_close(int queue_id){
236    if ((queue_id + 1) > _num_queues) {
237        xil_printf("ERROR (queue_close): queue_id %d out of range\n", queue_id);
238        return WLAN_FAILURE;
239    }
240
241    if (_queue_array[queue_id].list.length != 0){
242        xil_printf("Queue error: Unable to close queue_id %d because\n", queue_id);
243        xil_printf(" list has %d elements that would be leaked\n", _queue_array[queue_id].list.length);
244        return WLAN_FAILURE;
245    }
246
247    // Lower the QUEUE_FLAGS_OPEN flag so this QID can be re-used in the future
248    _queue_array[queue_id].flags = (_queue_array[queue_id].flags & ~_QUEUE_FLAGS_OPEN);
249
250    return WLAN_SUCCESS;
251}
252
253/*****************************************************************************/
254/**
255 * @brief Check if enqueue is allowed
256 *
257 * @param int queue_id - queue selection index (returned from queue_open)
258 *
259 * @return u8 1 if allowed, 0 otherwise
260 *
261 *****************************************************************************/
262u8 queue_enqueue_allowed(int queue_id){
263    if ((queue_id + 1) > _num_queues) {
264        return 0;
265    }
266
267    if ((_queue_array[queue_id].flags & _QUEUE_FLAGS_OPEN) == 0){
268        return 0;
269    }
270
271    if ((queue_length(queue_id) >= _queue_array[queue_id].max_len) && (_queue_array[queue_id].max_len != 0)){
272        return 0;
273    }
274
275    return 1;
276}
277
278/*****************************************************************************/
279/**
280 * @brief  Total number of queue entries
281 *
282 * This is the sum of all free and occupied queue entries
283 *
284 * @return u32
285 *
286 *****************************************************************************/
287u32 queue_total_size(){
288    return _total_queue_entries;
289}
290
291
292
293/*****************************************************************************/
294/**
295 * @brief  Number of free queue entries
296 *
297 * @return u32
298 *
299 *****************************************************************************/
300u32 queue_num_free(){
301    return _free_queue.length;
302}
303
304
305
306/*****************************************************************************/
307/**
308 * @brief  Number of queue entries in a given queue
309 *
310 * @param  u16 queue_id - ID of the queue
311 *
312 * @return u32
313 *
314 *****************************************************************************/
315u32 queue_length(u16 queue_id){
316    if((queue_id+1) > _num_queues){
317        return 0;
318    } else {
319        return _queue_array[queue_id].list.length;
320    }
321}
322
323/*****************************************************************************/
324/**
325 * @brief  Removes all queue entries in the selected queue
326 *
327 * This function removes all entries from the selected queue and returns them to
328 * the free pool.
329 *
330 * Note: if any actions need to be taken by the users of the queue prior to purging,
331 * it is their responsibility to do so prior to calling this function. See
332 * wlan_mac_purge_wireless_tx() as an example.
333 *
334 * @param  u16 queue_id - ID of the queue to purge
335 *
336 *****************************************************************************/
337void queue_purge(u16 queue_id){
338    u32 num_queued;
339    u32 i;
340    dl_entry* queue_entry;
341    volatile interrupt_state_t prev_interrupt_state;
342
343    num_queued = queue_length(queue_id);
344
345    if (num_queued > 0) {
346#if WLAN_SW_CONFIG_ENABLE_WLAN_EXP
347        wlan_exp_printf(WLAN_EXP_PRINT_INFO, print_type_queue, "Purging %d packets from queue %d\n", num_queued, queue_id);
348#endif
349
350        // NOTE:  There is an interesting condition that can occur if an LTG is running (ie creating new TX queue
351        //     entries) and purge_queue is called.  In this case, you have one process removing elements from the
352        //     queue while another process is adding elements to the queue.  Therefore, purge_queue will only
353        //     remove a fixed number of elements from the queue (ie all queued elements at the time the function
354        //     is called).  If purge_queue used a while loop with no checking on the number of elements removed,
355        //     then it could conceivably run forever.
356        //
357        for (i = 0; i < num_queued; i++) {
358            // The queue purge is not interrupt safe
359            //     NOTE:  Since there could be many elements in the queue, we need to toggle the interrupts
360            //         inside the for loop so that we do not block CPU High for an extended period of time.
361            //         This could result in CPU Low dropping a reception.
362            //
363            prev_interrupt_state = wlan_platform_intc_stop();
364
365            queue_entry = dequeue_head(queue_id);
366
367            if (queue_entry){
368                queue_checkin(queue_entry);
369            }
370
371            // Re-enable interrupts
372            wlan_platform_intc_set_state(prev_interrupt_state);
373        }
374    }
375}
376
377/*****************************************************************************/
378/**
379 * @brief  Retrieve a packet queue buffer pointer
380 *
381 * Returns a pointer to a packet queue buffer at a particular index. This function
382 * does not remove it from the queue.
383 *
384 * @param  u16 queue_id - ID of the queue from which the packet will be retrieved.
385 * @param  u32 idx       - Index into the queue. 0 represents the HEAD entry
386 *
387 * @return pkt_queue_buffer_t* - NULL if error, pointer to packet queue buffer otherwise
388 *
389 *****************************************************************************/
390pkt_queue_buffer_t* queue_retrieve_buffer_from_index(u16 queue_id, u32 idx){
391    pkt_queue_buffer_t* ret = NULL;
392    dl_entry* queue_entry;
393    volatile interrupt_state_t prev_interrupt_state;
394    u32 num_queued, i;
395
396    if ((queue_id + 1) > _num_queues) {
397        xil_printf("ERROR (queue_retrieve_buffer_from_index 1): queue_id %d out of range\n", queue_id);
398        return ret;
399    }
400
401    if (idx > (_queue_array[queue_id].list.length - 1)) {
402        xil_printf("ERROR (queue_retrieve_buffer_from_index 2): idx %d is out of range\n", idx);
403        return ret;
404    }
405
406    prev_interrupt_state = wlan_platform_intc_stop();
407    num_queued = queue_length(queue_id);
408    queue_entry = _queue_array[queue_id].list.first;
409    if (num_queued > 0) {
410        for (i = 0; i < num_queued; i++) {
411            if(i == idx){
412                break;
413            }
414            queue_entry = dl_entry_next(queue_entry);
415        }
416        if(queue_entry) ret = (pkt_queue_buffer_t*)(queue_entry->data);
417    }
418    // Re-enable interrupts
419    wlan_platform_intc_set_state(prev_interrupt_state);
420
421    return ret;
422}
423
424/*****************************************************************************/
425/**
426 * @brief  Adds a queue entry to a specified queue at the tail
427 *
428 * Adds the queue entry pointed to by queue_entry to the queue with ID queue_id.
429 *
430 * @param  u16 queue_id          - ID of the queue to which queue_entry is added.
431 * @param  dl_entry* queue_entry  - Queue entry containing packet
432 *
433 * @return int - WLAN_SUCCESS or WLAN_FAILURE
434 *
435 *****************************************************************************/
436int enqueue_tail(u16 queue_id, dl_entry* queue_entry){
437
438#if ADDRESS_SAFETY_CHECKS
439    if( ((u32)queue_entry < QUEUE_DL_ENTRY_MEM_BASE) || ((u32)queue_entry > CALC_MEM_HIGH_ADDR(QUEUE_DL_ENTRY_MEM_BASE,QUEUE_DL_ENTRY_MEM_SIZE)) ){
440        xil_printf("%s error: dl_entry @ 0x%08x out of range\n",  __FUNCTION__, queue_entry);
441    }
442#endif
443
444    if ((queue_id + 1) > _num_queues) {
445        xil_printf("Queue error: queue_id %d out of range\n", queue_id);
446        return WLAN_FAILURE;
447    }
448
449    if ((queue_length(queue_id) >= _queue_array[queue_id].max_len) && (_queue_array[queue_id].max_len != 0)){
450        xil_printf("ERROR (enqueue_tail): queue ID %d at max occupancy (%d)\n", queue_id, _queue_array[queue_id].max_len);
451        return WLAN_FAILURE;
452    }
453
454    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
455
456    // Insert the queue entry into the dl_list representing the selected queue
457    dl_entry_insertEnd(&(_queue_array[queue_id].list), (dl_entry*)queue_entry);
458
459    if(_queue_array[queue_id].list.length == 1){
460        //If the queue element we just added is now the only member of this queue, we should inform
461        //the top-level MAC that the queue has transitioned from empty to non-empty.
462        _queue_array[queue_id].queue_state_change_callback(_queue_array[queue_id].callback_arg, 1);
463    }
464
465    wlan_platform_intc_set_state(curr_interrupt_state);
466
467    return WLAN_SUCCESS;
468}
469
470
471/*****************************************************************************/
472/**
473 * @brief  Adds a queue entry to a specified queue at the head
474 *
475 * Adds the queue entry pointed to by queue_entry to the queue with ID queue_id.
476 *
477 * @param  u16 queue_id          - ID of the queue to which queue_entry is added.
478 * @param  dl_entry* queue_entry  - Queue entry containing packet
479 *
480 * @return int - WLAN_SUCCESS or WLAN_FAILURE
481 *
482 *****************************************************************************/
483int enqueue_head(u16 queue_id, dl_entry* queue_entry){
484
485#if ADDRESS_SAFETY_CHECKS
486    if( ((u32)queue_entry < QUEUE_DL_ENTRY_MEM_BASE) || ((u32)queue_entry > CALC_MEM_HIGH_ADDR(QUEUE_DL_ENTRY_MEM_BASE,QUEUE_DL_ENTRY_MEM_SIZE)) ){
487        xil_printf("%s error: dl_entry @ 0x%08x out of range\n",  __FUNCTION__, queue_entry);
488    }
489#endif
490
491    if ((queue_id + 1) > _num_queues) {
492        xil_printf("Queue error: queue_id %d out of range\n", queue_id);
493        return WLAN_FAILURE;
494    }
495
496    if ((queue_length(queue_id) >= _queue_array[queue_id].max_len) && (_queue_array[queue_id].max_len != 0)){
497        xil_printf("ERROR (enqueue_head): queue ID %d at max occupancy (%d)\n", queue_id, _queue_array[queue_id].max_len);
498        return WLAN_FAILURE;
499    }
500
501    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
502
503    // Insert the queue entry into the dl_list representing the selected queue
504    dl_entry_insertBeginning(&(_queue_array[queue_id].list), (dl_entry*)queue_entry);
505
506    if(_queue_array[queue_id].list.length == 1){
507        //If the queue element we just added is now the only member of this queue, we should inform
508        //the top-level MAC that the queue has transitioned from empty to non-empty.
509        _queue_array[queue_id].queue_state_change_callback(_queue_array[queue_id].callback_arg, 1);
510    }
511
512    wlan_platform_intc_set_state(curr_interrupt_state);
513
514    return WLAN_SUCCESS;
515}
516
517
518/*****************************************************************************/
519/**
520 * @brief  Removes the head entry from the specified queue
521 *
522 * If queue_id is not empty this function returns a queue_entry pointer
523 * for the head entry in the queue. If the specified queue is empty this
524 * function returns NULL.
525 *
526 * @param  u16 queue_id  - ID of the queue from which to dequeue an entry
527 *
528 * @return dl_entry*     - Pointer to queue entry if available,
529 *                                  NULL if queue is empty
530 *
531 *****************************************************************************/
532dl_entry* dequeue_head(u16 queue_id){
533    dl_entry* curr_dl_entry;
534
535    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
536
537    if ((queue_id + 1) > _num_queues) {
538        wlan_platform_intc_set_state(curr_interrupt_state);
539        return NULL;
540    } else {
541        if (_queue_array[queue_id].list.length == 0) {
542            // Requested queue exists but is empty
543            wlan_platform_intc_set_state(curr_interrupt_state);
544            return NULL;
545        } else {
546            curr_dl_entry = (_queue_array[queue_id].list.first);
547            dl_entry_remove(&_queue_array[queue_id].list, curr_dl_entry);
548
549            if(_queue_array[queue_id].list.length == 0){
550                //If the queue element we just removed empties the queue, we should inform
551                //the top-level MAC that the queue has transitioned from non-empty to empty.
552                _queue_array[queue_id].queue_state_change_callback(_queue_array[queue_id].callback_arg, 0);
553            }
554            wlan_platform_intc_set_state(curr_interrupt_state);
555
556            return (dl_entry *) curr_dl_entry;
557        }
558    }
559}
560
561/*****************************************************************************/
562/**
563 * @brief  Checks out one queue entry from the free pool
564 *
565 * The queue framework maintains a pool of free queue entries. This function
566 * removes one entry from the free pool and returns it for use by the MAC
567 * application. If the free pool is empty NULL is returned.
568 *
569 * @return dl_entry *     - Pointer to new queue entry if available,
570 *                                  NULL if free queue is empty
571 *
572 *****************************************************************************/
573dl_entry* queue_checkout(){
574    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
575
576    dl_entry* queue_entry;
577
578    if(_free_queue.length > 0){
579        queue_entry = ((dl_entry*)(_free_queue.first));
580        dl_entry_remove(&_free_queue,_free_queue.first);
581
582        // Set buffer length
583        //  In the current architecture, this length is fixed.
584        ((pkt_queue_buffer_t*)(queue_entry->data))->pyld_queue_hdr.buffer_length = QUEUE_ELEMENT_SIZE;
585
586        wlan_platform_intc_set_state(curr_interrupt_state);
587        return queue_entry;
588    } else {
589        wlan_platform_intc_set_state(curr_interrupt_state);
590        return NULL;
591    }
592}
593
594
595
596/*****************************************************************************/
597/**
598 * @brief  Checks in one queue entry to the free pool
599 *
600 * The queue framework maintains a pool of free queue entries. This function
601 * returns one entry to the free pool.  queue_entry must be a valid pointer to a queue
602 * entry which the MAC application no longer needs. The application must not
603 * use the entry pointed to by tqe after calling this function.
604 *
605 * @param  dl_entry* queue_entry  - Pointer to queue entry to be returned to free pool
606 *
607 *****************************************************************************/
608void queue_checkin(dl_entry* queue_entry){
609
610#if ADDRESS_SAFETY_CHECKS
611    if( ((u32)queue_entry < QUEUE_DL_ENTRY_MEM_BASE) || ((u32)queue_entry > CALC_MEM_HIGH_ADDR(QUEUE_DL_ENTRY_MEM_BASE,QUEUE_DL_ENTRY_MEM_SIZE)) ){
612        xil_printf("%s error: dl_entry @ 0x%08x out of range\n",  __FUNCTION__, queue_entry);
613    }
614#endif
615
616    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
617    if (queue_entry != NULL) {
618        dl_entry_insertEnd(&_free_queue, (dl_entry*)queue_entry);
619    }
620    wlan_platform_free_queue_entry_notify();
621    wlan_platform_intc_set_state(curr_interrupt_state);
622}
623
624
625
626/*****************************************************************************/
627/**
628 * @brief Checks out multiple queue entries from the free pool
629 *
630 * The queue framework maintains a pool of free queue entries. This function
631 * attempts to check out num_queue_entry queue entries from the free pool. The number of
632 * queue entries successfully checked out is returned. This may be less than
633 * requested if the free pool had fewer than num_queue_entry entries available.
634 *
635 * @param   dl_list* new_list    - Pointer to dl_list to which queue entries are appended
636 * @param   u16 num_queue_entry  - Number of queue entries requested
637 *
638 * @return  Number of queue entries successfully checked out and appended to new_list
639 *
640 *****************************************************************************/
641int queue_checkout_list(dl_list* list, u16 num_queue_entry){
642    int num_moved;
643    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
644    num_moved = dl_entry_move(&_free_queue, list, num_queue_entry);
645    wlan_platform_intc_set_state(curr_interrupt_state);
646    return num_moved;
647}
648
649
650
651/*****************************************************************************/
652/**
653 * @brief Checks in multiple queue entries into the free pool
654 *
655 * The queue framework maintains a pool of free queue entries. This function will
656 * check in all queue entries from the provided list to the end of the free pool.
657 *
658 * @param   dl_list * new_list    - Pointer to dl_list from which queue entries will be checked in
659 *
660 * @return  Number of queue entries successfully checked in
661 *
662 *****************************************************************************/
663int queue_checkin_list(dl_list* list) {
664    int num_moved;
665    interrupt_state_t curr_interrupt_state = wlan_platform_intc_stop();
666    num_moved = dl_entry_move(list, &_free_queue, list->length);
667    wlan_platform_intc_set_state(curr_interrupt_state);
668    wlan_platform_free_queue_entry_notify();
669    return num_moved;
670}
671
672
Note: See TracBrowser for help on using the repository browser.