00001
00013 #ifndef _TXL_HE_H_
00014 #define _TXL_HE_H_
00015
00016
00026
00027
00028
00029
00030 #include "co_int.h"
00031 #include "hal_desc.h"
00032 #include "mm_timer.h"
00033
00034 #if NX_MAC_HE
00035 struct sta_info_tag;
00036 struct vif_info_tag;
00037 struct txdesc;
00038 struct rxdesc;
00039 struct mm_set_mu_edca_req;
00040 struct mm_set_uora_req;
00041
00042
00043
00044
00046 struct mu_edca_param_tag
00047 {
00049 struct tx_hd *first_frame_exch;
00051 uint32_t edca;
00053 uint8_t timeout;
00055 uint8_t timer;
00057 bool edca_off;
00058 };
00059
00060
00062 struct uora_tag
00063 {
00065 uint8_t eocw_min;
00067 uint8_t eocw_max;
00068 };
00070 struct mu_edca_tag
00071 {
00073 struct mm_timer_tag timer;
00075 struct mu_edca_param_tag params[NX_TXQ_CNT];
00077 uint8_t edca_stopping;
00080 uint8_t he_tb_activity;
00083 bool valid;
00084 };
00085
00087 struct he_trigger_tag
00088 {
00090 struct sta_info_tag *sta;
00092 uint32_t uph;
00094 uint32_t max_len;
00096 struct mac_addr ta;
00098 uint16_t mmss;
00100 uint16_t ul_length;
00102 uint8_t ac;
00104 uint8_t trig_type;
00106 uint8_t gi_type;
00108 uint8_t ul_mcs;
00110 uint8_t ul_nss;
00112 uint8_t ul_bw;
00114 uint8_t ru_size;
00116 uint8_t pref_ac;
00118 uint8_t spacing_factor;
00120 bool uora;
00122 bool trig_valid;
00123 };
00124
00126 struct txl_he_env_tag
00127 {
00128 #if NX_UMAC_PRESENT && NX_BEACONING
00130 struct mm_timer_tag trig_timer;
00131 #endif
00133 struct vif_info_tag *tb_vif;
00135 struct mu_edca_tag mu_edca;
00137 struct uora_tag uora;
00139 struct he_trigger_tag trigger;
00141 bool tb_ongoing;
00142 };
00143
00144
00145
00146
00147
00149 #define TX_HE_TB_PROG_TIME 5
00150
00152 #define TX_HE_BSR_FULL (MAC_HTC_HE_CTRL_ID_BSR | MAC_HTC_HE_BSR_QSIZE_ALL_MSK | \
00153 MAC_HTC_HE_BSR_QSIZE_HIGH_MSK | MAC_HTC_HE_BSR_SCALING_FAC_MSK | \
00154 MAC_HTC_HE_BSR_DELTA_TID_MSK)
00155
00156
00157
00158
00159
00161 extern struct txl_he_env_tag txl_he_env;
00162
00163
00164
00165
00166
00167
00178 __INLINE uint32_t txl_he_tb_uph_get(void)
00179 {
00180 return (txl_he_env.trigger.uph);
00181 }
00182
00202 uint32_t txl_he_htc_get(struct txdesc *txdesc, struct sta_info_tag *sta);
00203
00213 __INLINE bool txl_he_is_he_su(uint32_t rate_info)
00214 {
00215 uint32_t format = (rate_info & FORMAT_MOD_TX_RCX_MASK) >> FORMAT_MOD_TX_RCX_OFT;
00216
00217 return (format == FORMATMOD_HE_SU);
00218 }
00219
00231 __INLINE bool txl_he_is_edca_off(uint8_t access_category)
00232 {
00233 return (txl_he_env.mu_edca.params[access_category].edca_off);
00234 }
00235
00246 __INLINE void txl_he_ltf_type_set(uint32_t rate_info, uint32_t *pwr_info)
00247 {
00248 int he_ltf_type = TX_2x_HE_LTF_FOR_6_4_US;
00249
00250 if ((rate_info & HE_GI_TYPE_TX_RCX_MASK) == GI_TYPE_3_2)
00251 he_ltf_type = TX_4x_HE_LTF_FOR_12_8_US;
00252
00253 *pwr_info &= ~TX_HE_LTF_TYPE_PT_RCX_MASK;
00254 *pwr_info |= he_ltf_type;
00255 }
00256
00266 __INLINE bool txl_he_tb_ongoing(uint8_t *ac)
00267 {
00268 *ac = txl_he_env.trigger.ac;
00269
00270 return (txl_he_env.tb_ongoing);
00271 }
00272
00286 __INLINE bool txl_he_tb_can_chain_edca(uint8_t ac)
00287 {
00288 uint8_t tb_ac;
00289
00290 return (!txl_he_is_edca_off(ac) && (!txl_he_tb_ongoing(&tb_ac) || (tb_ac != ac)));
00291 }
00292
00305 __INLINE uint8_t txl_he_get_queue_size(uint32_t buffered)
00306 {
00307 uint8_t queue_size, sf = 0, uv = 0;
00308 const uint8_t sf_oft = 6;
00309
00310 if(buffered <= 1008)
00311 {
00312 sf = 0;
00313 uv = (CO_ALIGNx_HI(buffered, 16)) / 16;
00314 }
00315 else if (buffered <= 1024)
00316 {
00317 sf = 1;
00318 uv = 0;
00319 }
00320 else if (buffered <= 17152)
00321 {
00322 sf = 1;
00323 uv = (CO_ALIGNx_HI(buffered - 1024, 16)) / 16;
00324 }
00325 else if (buffered <= 17408)
00326 {
00327 sf = 2;
00328 uv = 0;
00329 }
00330 else if (buffered <= 146432)
00331 {
00332 sf = 2;
00333 uv = (CO_ALIGNx_HI(buffered - 17408, 2048)) / 2048;
00334 }
00335 else if (buffered <= 148480)
00336 {
00337 sf = 3;
00338 uv = 0;
00339 }
00340 else if (buffered <= 2147328)
00341 {
00342 sf = 3;
00343 uv = (CO_ALIGNx_HI(buffered - 148480, 32768)) / 32768;
00344 }
00345 else if (buffered < 4294967295)
00346 {
00347 sf = 3;
00348 uv = 62;
00349 }
00350 else
00351 {
00352 sf = 3;
00353 uv = 63;
00354 }
00355
00356 queue_size = (sf << sf_oft) | uv;
00357
00358 return queue_size;
00359 }
00368 void txl_he_init(void);
00369
00377 void txl_he_reset(void);
00378
00389 void txl_he_trigger_push(struct rxdesc *rxdesc);
00390
00401 void txl_he_tb_prot_trigger(void);
00402
00415 void txl_he_tb_transmit_cancelled(void);
00416
00428 void txl_he_tb_transmit_trigger(void);
00429
00440 uint32_t txl_he_idx_to_32us_len_get(int base_idx, uint8_t bw);
00441
00452 uint16_t txl_he_idx_to_1us_len_get(int base_idx, uint8_t bw);
00453
00468 int txl_he_ampdu_param_get(struct txdesc *txdesc,
00469 uint8_t format_mod,
00470 uint32_t *max_len_sta,
00471 uint32_t *nss);
00472
00485 bool txl_he_decode_m_ba(struct rxdesc *badesc, struct tx_agg_desc *agg_desc);
00486
00494 void txl_he_mu_edca_param_set(struct mm_set_mu_edca_req const *param);
00495
00503 void txl_he_uora_param_set(struct mm_set_uora_req const *param);
00504
00518 void txl_he_mu_edca_blocked(struct tx_hd *thd, uint8_t ac);
00519
00529 void txl_he_tb_config(void);
00530
00536 void txl_he_tb_disable(void);
00537
00543 void txl_he_tb_enable(void);
00544
00545
00562 void txl_he_non_edca_chain(struct tx_hd *first_thd,
00563 struct tx_hd *last_thd,
00564 uint8_t access_category);
00565
00566 #if NX_UMAC_PRESENT && NX_BEACONING
00567
00577 void txl_he_start_trigger_scheduler(struct sta_info_tag *sta);
00578 #endif // NX_UMAC_PRESENT && NX_BEACONING
00579
00593 void txl_he_txop_dur_rtscts_thres_ampdu_check(struct txdesc *txdesc);
00594
00606 void txl_he_txop_dur_rtscts_thres_mpdu_check(struct txdesc *txdesc);
00607
00619 void txl_he_bsr_compute(struct vif_info_tag *vif);
00620
00621 #endif // NX_MAC_HE
00622
00625
00626 #endif // _TXL_HE_H_