/** @file wlan_mac_queue.h * @brief Transmit Queue Framework * * This contains code for accessing the transmit queue. * * @copyright Copyright 2013-2019, Mango Communications. All rights reserved. * Distributed under the Mango Communications Reference Design License * See LICENSE.txt included in the design archive or * at http://mangocomm.com/802.11/license * * This file is part of the Mango 802.11 Reference Design (https://mangocomm.com/802.11) */ /*************************** Constant Definitions ****************************/ #ifndef WLAN_MAC_QUEUE_H_ #define WLAN_MAC_QUEUE_H_ /***************************** Include Files *********************************/ #include "wlan_mac_high_sw_config.h" #include "xil_types.h" #include "wlan_common_types.h" #include "wlan_high_types.h" #include "wlan_mac_802_11_defs.h" //Forward declarations struct station_info_t; //----------------------------------------------- // Queue defines // #define QUEUE_ELEMENT_SIZE 0x1000 // 4KB typedef struct __attribute__((__packed__)) pyld_queue_hdr_t{ u32 buffer_length; // Number of bytes until next pyld_queue_hdr_t. Currently fixed at QUEUE_ELEMENT_SIZE //---- 4-bytes ---- dl_entry* dle; //---- 8-bytes ---- } pyld_queue_hdr_t; ASSERT_TYPE_SIZE(pyld_queue_hdr_t, 8); // Base stencil for every Pkt Queue Buffer typedef struct __attribute__((__packed__)) pkt_queue_buffer_t{ pyld_queue_hdr_t pyld_queue_hdr; u8 reserved[QUEUE_ELEMENT_SIZE - sizeof(pyld_queue_hdr_t)]; } pkt_queue_buffer_t; ASSERT_TYPE_SIZE(pkt_queue_buffer_t, QUEUE_ELEMENT_SIZE); // Stencil to use Pkt Queue Buffer for Tx Queue Buffer typedef struct __attribute__((__packed__)) tx_queue_buffer_t{ pyld_queue_hdr_t pyld_queue_hdr; //---- 8-bytes ---- u16 length; u16 seg0_len; //---- 12-bytes ---- u16 seg1_len; u8 seg1_offset; u8 reserved0; //---- 16-bytes ---- struct station_info_t* station_info; //---- 20-bytes ---- tx_queue_details_t tx_queue_details; //---- 32-bytes ---- u16 flags; u8 reserved1[6]; //---- 40-bytes ---- u8 pkt[QUEUE_ELEMENT_SIZE - 40]; } tx_80211_queue_buffer_t; ASSERT_TYPE_SIZE(tx_80211_queue_buffer_t, QUEUE_ELEMENT_SIZE); // Stencil to use Pkt Queue Buffer as Rx Eth Queue Buffer typedef struct __attribute__((__packed__)) eth_rx_queue_buffer_t{ pyld_queue_hdr_t pyld_queue_hdr; //---- 8-bytes ---- u16 length; u8 reserved[ 30 ]; //---- 40-bytes ---- u8 encap_eth_header_placeholder[ sizeof(mac_header_80211) + sizeof(llc_header_t) ]; //---- 72-bytes ---- u8 pkt[QUEUE_ELEMENT_SIZE - 72]; } eth_rx_queue_buffer_t; ASSERT_TYPE_SIZE(eth_rx_queue_buffer_t, QUEUE_ELEMENT_SIZE); ASSERT_FIELD_ALIGNMENT(eth_rx_queue_buffer_t, pkt, 8); //ensure 8-byte alignment on Ethernet frame for DMA // Stencil to use Pkt Queue Buffer as Rx wlan_exp Queue Buffer typedef struct __attribute__((__packed__)) wlan_exp_eth_rx_queue_buffer_t{ pyld_queue_hdr_t pyld_queue_hdr; //---- 8-bytes ---- u16 length; u8 reserved0[ 6 ]; //---- 16-bytes ---- sockaddr_in_t rx_from; u8 reserved1[ 40 ]; //---- 72-bytes ---- u8 pkt[QUEUE_ELEMENT_SIZE - 72]; } wlan_exp_eth_rx_queue_buffer_t; ASSERT_TYPE_SIZE(wlan_exp_eth_rx_queue_buffer_t, QUEUE_ELEMENT_SIZE); ASSERT_FIELD_ALIGNMENT(wlan_exp_eth_rx_queue_buffer_t, pkt, 8); //ensure 8-byte alignment on Ethernet frame for DMA // Stencil to use Pkt Queue Buffer as Tx Eth Queue Buffer typedef struct __attribute__((__packed__)) eth_tx_queue_buffer_t{ pyld_queue_hdr_t pyld_queue_hdr; //---- 8-bytes ---- u16 seg0_len; u16 seg1_len; //---- 12-bytes ---- u8* seg1_addr; //---- 16-bytes --- u8 seg0[QUEUE_ELEMENT_SIZE - 16]; } eth_tx_queue_buffer_t; ASSERT_TYPE_SIZE(eth_tx_queue_buffer_t, QUEUE_ELEMENT_SIZE); ASSERT_FIELD_ALIGNMENT(eth_tx_queue_buffer_t, seg0, 8); //ensure 8-byte alignment on Ethernet frame for DMA // The packet queue buffer types require certain field overlaps. The below macros enforce the necessary // overlap alignment ASSERT_FIELD_OVERLAP_ALIGNMENT(eth_rx_queue_buffer_t, pkt, wlan_exp_eth_rx_queue_buffer_t, pkt); ASSERT_FIELD_OVERLAP_ALIGNMENT(eth_rx_queue_buffer_t, encap_eth_header_placeholder, tx_80211_queue_buffer_t, pkt); #define TX_80211_QUEUE_BUFFER_FLAGS_FILL_TIMESTAMP 0x0001 #define TX_80211_QUEUE_BUFFER_FLAGS_FILL_DURATION 0x0002 #define TX_80211_QUEUE_BUFFER_FLAGS_FILL_UNIQ_SEQ 0x0004 #define TX_80211_QUEUE_BUFFER_FLAGS_BYPASS_RECOVERY 0x0008 #define TX_80211_QUEUE_BUFFER_FLAGS_TYPE_CTS 0x0010 #define TX_80211_QUEUE_BUFFER_FLAGS_TYPE_ACK 0x0020 /*************************** Function Prototypes *****************************/ void queue_init(); int queue_open(function_ptr_t queue_state_change_callback, u32 callback_arg, u32 max_len); int queue_set_max_len(int queue_id, u32 max_len); int queue_close(int queue_id); pkt_queue_buffer_t* queue_retrieve_buffer_from_index(u16 queue_id, u32 idx); #define queue_enqueue(a,b) enqueue_tail((a),(b)) #define queue_dequeue(a) dequeue_head(a) int enqueue_tail(u16 queue_id, dl_entry* queue_entry); int enqueue_head(u16 queue_id, dl_entry* queue_entry); dl_entry* dequeue_head(u16 queue_id); dl_entry* queue_checkout(); void queue_checkin(dl_entry* queue_entry); int queue_checkout_list(dl_list* new_list, u16 num_queue_entry); int queue_checkin_list(dl_list * list); u32 queue_num_free(); u32 queue_length(u16 queue_id); u8 queue_enqueue_allowed(int queue_id); u32 queue_total_size(); void queue_purge(u16 queue_id); #endif /* WLAN_MAC_QUEUE_H_ */