00001
00013 #ifndef _TXL_AGG_H_
00014 #define _TXL_AGG_H_
00015
00016
00026
00027
00028
00029
00030 #include "co_int.h"
00031
00032
00033 #include "mac.h"
00034
00035 #include "co_status.h"
00036
00037 #include "co_list.h"
00038 #include "tx_swdesc.h"
00039 #include "ke_event.h"
00040 #include "hal_machw.h"
00041
00042 #include "sta_mgmt.h"
00043
00044 #if NX_AMPDU_TX
00045
00046
00047
00048
00049
00050
00051
00052
00054 struct tx_agg_desc
00055 {
00057 struct co_list_hdr list_hdr;
00059 uint16_t status;
00061 uint16_t available_len;
00063 uint8_t available_cnt;
00065 uint8_t sta_idx;
00067 uint8_t tid;
00070 uint8_t user_cnt;
00072 struct tx_hd a_thd;
00074 struct tx_hd bar_thd;
00076 struct bar_frame bar_payl;
00078 struct tx_policy_tbl bar_pol_tbl;
00080 struct ba_ssc_bitmap *ssc_bitmap;
00082 struct ba_ssc_bitmap_256 ssc_bitmap_tab;
00083 #if NX_MAC_HE
00085 struct tx_policy_tbl pol_tbl;
00087 struct txdesc *txdesc_last;
00088 #endif
00089 #if NX_BW_LEN_ADAPT
00091 struct txdesc *txdesc[NX_BW_LEN_STEPS - 1];
00092 #endif
00093 #if RW_MUMIMO_TX_EN
00096 struct co_list cfm;
00098 struct tx_agg_desc *prim_agg_desc;
00100 struct tx_hd *last_bar_thd;
00103 uint8_t download;
00104 #endif
00106 struct co_list *free_list;
00107 };
00108
00109
00110
00111
00112
00114 extern struct co_list tx_agg_desc_pool[];
00115
00116
00117
00118
00119
00120
00131 __INLINE bool is_mpdu_agg(struct txdesc * txdesc)
00132 {
00133 return ((txdesc->umac.flags & AMPDU_BIT) == AMPDU_BIT);
00134 }
00135
00143 __INLINE bool is_mpdu_first(struct txdesc *txdesc)
00144 {
00145 return ((txdesc->umac.flags & WHICHDESC_MSK) == WHICHDESC_AMPDU_FIRST);
00146 }
00147
00155 __INLINE bool is_mpdu_interm(struct txdesc * txdesc)
00156 {
00157 return ((txdesc->umac.flags & WHICHDESC_MSK) == WHICHDESC_AMPDU_INT);
00158 }
00159
00167 __INLINE bool is_mpdu_last(struct txdesc * txdesc)
00168 {
00169 return ((txdesc->umac.flags & WHICHDESC_MSK) == WHICHDESC_AMPDU_LAST);
00170 }
00171
00180 __INLINE bool is_mpdu_unpos(struct txdesc * txdesc)
00181 {
00182
00183
00184
00185 return ((txdesc->umac.flags & WHICHDESC_MSK) == WHICHDESC_AMPDU_EXTRA);
00186 }
00187
00196 __INLINE void set_mpdu_pos(struct txdesc * txdesc, uint32_t pos)
00197 {
00198 txdesc->umac.flags = ( txdesc->umac.flags &
00199 (~(WHICHDESC_MSK & (~AMPDU_BIT))) ) | pos;
00200 }
00201
00209 __INLINE uint16_t txl_mpdu_subframe_len(struct tx_hd *thd)
00210 {
00211
00212 return (CO_ALIGN4_HI(thd->frmlen) + DELIMITER_LEN);
00213 }
00214
00215 #if RW_MUMIMO_TX_EN
00216
00223 __INLINE bool is_in_mumimo_ppdu(struct txdesc * txdesc)
00224 {
00225 struct tx_agg_desc *agg_desc = txdesc->lmac.agg_desc;
00226
00227 return ((agg_desc != NULL) && (agg_desc->prim_agg_desc != NULL));
00228 }
00229
00239 __INLINE bool is_primary_user(struct txdesc * txdesc)
00240 {
00241 struct tx_agg_desc *agg_desc = txdesc->lmac.agg_desc;
00242
00243 return (agg_desc == agg_desc->prim_agg_desc);
00244 }
00245
00253 __INLINE bool is_mumimo_group_id(uint8_t group_id)
00254 {
00255 return (group_id > 0) && (group_id < 63);
00256 }
00257
00267 __INLINE uint8_t get_group_id(struct txdesc * txdesc)
00268 {
00269 return (txdesc->host.mumimo_info & 0x3F);
00270 }
00271 #endif
00272
00282 __INLINE uint8_t get_user_pos(struct txdesc * txdesc)
00283 {
00284 #if RW_MUMIMO_TX_EN
00285 return (txdesc->host.mumimo_info >> 6);
00286 #else
00287 return 0;
00288 #endif
00289 }
00290
00300 __INLINE struct tx_agg_desc * txl_agg_desc_alloc(uint8_t access_category)
00301 {
00302 return ((struct tx_agg_desc *)co_list_pop_front(&tx_agg_desc_pool[access_category]));
00303 }
00304
00312 __INLINE void txl_agg_desc_free(struct tx_agg_desc *agg_desc)
00313 {
00314
00315 co_list_push_back(agg_desc->free_list, (struct co_list_hdr *)agg_desc);
00316 }
00317
00323 void txl_agg_init(void);
00324
00332 void txl_agg_reset(void);
00333
00357 int txl_agg_push_mpdu(struct txdesc *txdesc, uint8_t ac);
00358
00370 void txl_agg_finish(uint8_t ac);
00371
00372 #if (NX_BW_LEN_ADAPT)
00373
00383 void txl_agg_bw_drop_handle(uint8_t access_category);
00384 #endif
00385
00395 void txl_agg_check(uint8_t access_category);
00396
00407 void txl_agg_set_ampdu_protection(uint32_t *rc);
00408
00419 void txl_agg_check_rtscts_retry_limit(struct tx_hd *a_thd, uint8_t access_category);
00420
00434 void txl_agg_check_saved_agg_desc(uint8_t access_category);
00435
00436 #if RW_MUMIMO_TX_EN
00437
00448 void txl_agg_mumimo_close(uint8_t ac);
00449
00457 void txl_agg_sec_transmit_trigger(void);
00458 #endif // RW_MUMIMO_TX_EN
00459
00471 uint16_t txl_agg_mpdu_nb_delims(struct tx_hd *thd, uint16_t mmss_bytes);
00472
00480 void txl_agg_release(struct tx_agg_desc *agg_desc);
00481
00495 struct tx_hd *txl_agg_change_to_singleton(struct txdesc *txdesc, bool he_tb);
00496
00497 #if NX_MAC_HE
00498
00512 struct tx_hd *txl_agg_set_new_ampdu_head(struct txdesc *txdesc, struct tx_hd **bar_thd);
00513
00534 struct tx_hd *txl_agg_he_tb_prep(struct txdesc *txdesc, struct txdesc **txdesc_next,
00535 uint32_t max_len, uint16_t min_mpdu_len, uint8_t ac);
00536
00537 #endif // NX_MAC_HE
00538
00539 #endif // NX_AMPDU_TX
00540
00543
00544 #endif // _TXL_AGG_H_