00001
00019
00020
00021
00022
00023
00024 #include "td.h"
00025
00026 #if (NX_TD)
00027
00028 #include "ke_timer.h"
00029
00030 #if (NX_DPSM)
00031 #include "ps.h"
00032 #endif //(NX_DPSM)
00033 #if (NX_CHNL_CTXT)
00034 #include "chan.h"
00035 #include "vif_mgmt.h"
00036 #endif //(NX_CHNL_CTXT)
00037 #if (NX_P2P_GO)
00038 #include "p2p.h"
00039 #endif //(NX_P2P_GO)
00040 #if (NX_TD_STA)
00041 #include "sta_mgmt.h"
00042 #include "vif_mgmt.h"
00043 #endif //(NX_TD_STA)
00044 #if NX_MAC_HE
00045 #include "txl_he.h"
00046 #endif
00047
00048
00049
00050
00051
00052
00058 #define TD_DEBUG_TRACES_EN (0)
00059
00060 #if (TD_DEBUG_TRACES_EN)
00062 #define TD_DEBUG_PRINT(lvl, format, ...) \
00063 do { \
00064 if (lvl <= TD_DEBUG_TRACES_EN) \
00065 { \
00066 dbg(format, ## __VA_ARGS__); \
00067 } \
00068 } while (0);
00069 #else
00070 #define TD_DEBUG_PRINT(lvl, format, ...)
00071 #endif //(TD_DEBUG_TRACES_EN)
00072
00073
00074
00075
00076
00077
00079 #define TD_GET_VIF_INDEX(td_env) \
00080 ((td_env - &td_env_tab[0]) / sizeof(struct td_env_tag))
00081
00082
00083
00084
00085
00086
00087 struct td_env_tag td_env_tab[NX_VIRT_DEV_MAX];
00088 #if (NX_TD_STA)
00090 struct td_sta_env_tag td_sta_env[NX_REMOTE_STA_MAX];
00091 #endif //(NX_TD_STA)
00092
00093
00094
00095
00096
00097
00098 #if (NX_TD_STA)
00099
00104 static void td_update_sta_status(uint8_t sta_idx)
00105 {
00106
00107 struct td_sta_env_tag *tds_env = &td_sta_env[sta_idx];
00108
00109 uint8_t new_status = 0;
00110
00111 if (tds_env->pck_cnt_tx >= TD_DEFAULT_PCK_NB_THRES)
00112 {
00113 new_status |= CO_BIT(TD_STATUS_TX);
00114 }
00115
00116 if (tds_env->pck_cnt_rx >= TD_DEFAULT_PCK_NB_THRES)
00117 {
00118 new_status |= CO_BIT(TD_STATUS_RX);
00119 }
00120
00121
00122 tds_env->status = new_status;
00123
00124
00125 tds_env->pck_cnt_tx = 0;
00126 tds_env->pck_cnt_rx = 0;
00127 }
00128 #endif //(NX_TD_STA)
00129
00135 static void td_timer_end(void *env)
00136 {
00137
00138 struct td_env_tag *td_env = (struct td_env_tag *)env;
00139
00140 uint32_t current_time = ke_time();
00141
00142 uint8_t new_status = 0;
00143
00144 TD_DEBUG_PRINT(2, D_CRT "td_timer_end v=%d c=%d tx=%d rx=%d\n", td_env->vif_index,
00145 td_env->has_active_chan, td_env->pck_cnt_tx, td_env->pck_cnt_rx);
00146
00147
00148 PROF_TD_TIMER_END_SET();
00149
00150 #if NX_MAC_HE
00151
00152 txl_he_bsr_compute(&vif_info_tab[td_env->vif_index]);
00153 #endif
00154
00155 #if (NX_CHNL_CTXT)
00156
00157 if (td_env->has_active_chan)
00158 #endif //(NX_CHNL_CTXT)
00159 {
00160 #if (NX_TD_STA)
00161
00162 struct vif_info_tag *vif = &vif_info_tab[td_env->vif_index];
00163
00164 struct sta_info_tag *sta;
00165 #endif //(NX_TD_STA)
00166
00167
00168 if (td_env->pck_cnt_tx >= TD_DEFAULT_PCK_NB_THRES)
00169 {
00170 new_status |= CO_BIT(TD_STATUS_TX);
00171 }
00172
00173
00174 if (td_env->pck_cnt_rx >= TD_DEFAULT_PCK_NB_THRES)
00175 {
00176 new_status |= CO_BIT(TD_STATUS_RX);
00177 }
00178
00179 #if (NX_DPSM)
00180
00181 if (td_env->pck_cnt_tx_ps >= TD_DEFAULT_PCK_NB_THRES)
00182 {
00183 new_status |= CO_BIT(TD_STATUS_TX_PS);
00184 }
00185
00186
00187 if (td_env->pck_cnt_rx_ps >= TD_DEFAULT_PCK_NB_THRES)
00188 {
00189 new_status |= CO_BIT(TD_STATUS_RX_PS);
00190 }
00191
00192
00193 if ((td_env->status ^ new_status) & (CO_BIT(TD_STATUS_TX_PS) | CO_BIT(TD_STATUS_RX_PS)))
00194 {
00195
00196 ps_traffic_status_update(td_env->vif_index,
00197 (new_status & (CO_BIT(TD_STATUS_TX_PS) | CO_BIT(TD_STATUS_RX_PS))));
00198 }
00199 #endif //(NX_DPSM)
00200
00201 #if (NX_P2P_GO)
00202
00203 if ((td_env->status ^ new_status) & (CO_BIT(TD_STATUS_TX) | CO_BIT(TD_STATUS_RX)))
00204 {
00205
00206 p2p_go_td_evt(td_env->vif_index, new_status & (CO_BIT(TD_STATUS_TX) | CO_BIT(TD_STATUS_RX)));
00207 }
00208 #endif //(NX_P2P_GO)
00209
00210
00211 td_env->status = new_status;
00212
00213 #if (NX_TD_STA)
00214 sta = (struct sta_info_tag *)co_list_pick(&vif->sta_list);
00215
00216 while (sta)
00217 {
00218
00219 td_update_sta_status(sta->staid);
00220
00221
00222 sta = (struct sta_info_tag *)sta->list_hdr.next;
00223 }
00224 #endif //(NX_TD_STA)
00225 }
00226
00227
00228 td_env->pck_cnt_tx = 0;
00229 td_env->pck_cnt_rx = 0;
00230 #if (NX_DPSM)
00231 td_env->pck_cnt_tx_ps = 0;
00232 td_env->pck_cnt_rx_ps = 0;
00233 #endif //(NX_DPSM)
00234
00235 #if (NX_CHNL_CTXT)
00236 if (chan_env.current_ctxt == vif_info_tab[td_env->vif_index].chan_ctxt)
00237 {
00238 td_env->has_active_chan = true;
00239 }
00240 else
00241 {
00242 td_env->has_active_chan = false;
00243 }
00244 #endif //(NX_CHNL_CTXT)
00245
00246
00247 mm_timer_set(&td_env->td_timer, current_time + TD_DEFAULT_INTV_US);
00248
00249
00250 PROF_TD_TIMER_END_CLR();
00251 }
00252
00253
00254
00255
00256
00257
00258 void td_init(void)
00259 {
00260 uint8_t counter;
00261
00262 TD_DEBUG_PRINT(1, D_CRT "td_init\n");
00263
00264
00265 for (counter = 0; counter < NX_VIRT_DEV_MAX; counter++)
00266 {
00267 td_reset(counter);
00268 }
00269
00270 #if (NX_TD_STA)
00271
00272 for (counter = 0; counter < NX_REMOTE_STA_MAX; counter++)
00273 {
00274 td_sta_reset(counter);
00275 }
00276 #endif //(NX_TD_STA)
00277 }
00278
00279 void td_reset(uint8_t vif_index)
00280 {
00281
00282 struct td_env_tag *td_env = &td_env_tab[vif_index];
00283
00284 TD_DEBUG_PRINT(1, D_CRT "td_reset idx=%d\n", vif_index);
00285
00286 if (td_env->is_on)
00287 {
00288
00289 mm_timer_clear(&td_env->td_timer);
00290 }
00291
00292
00293 memset(td_env, 0, sizeof(struct td_env_tag));
00294
00295
00296 td_env->td_timer.cb = td_timer_end;
00297 td_env->td_timer.env = td_env;
00298
00299
00300 td_env->vif_index = vif_index;
00301 }
00302
00303 #if (NX_TD_STA)
00304 void td_sta_reset(uint8_t sta_index)
00305 {
00306
00307 struct td_sta_env_tag *tds_env = &td_sta_env[sta_index];
00308
00309 TD_DEBUG_PRINT(1, D_CRT "td_sta_reset idx=%d\n", sta_index);
00310
00311
00312 tds_env->pck_cnt_tx = 0;
00313 tds_env->pck_cnt_rx = 0;
00314 tds_env->status = 0;
00315 }
00316 #endif //(NX_TD_STA)
00317
00318 void td_start(uint8_t vif_index)
00319 {
00320
00321 struct td_env_tag *td_env = &td_env_tab[vif_index];
00322
00323
00324 if (!td_env->is_on)
00325 {
00326
00327 uint32_t current_time = ke_time();
00328
00329 TD_DEBUG_PRINT(1, D_CRT "td_start idx=%d\n", vif_index);
00330
00331
00332 td_env->is_on = true;
00333
00334
00335 mm_timer_set(&td_env->td_timer, current_time + TD_DEFAULT_INTV_US);
00336 }
00337 }
00338
00339 void td_pck_ind(uint8_t vif_index, uint8_t sta_index, bool rx)
00340 {
00341
00342 struct td_env_tag *td_env = &td_env_tab[vif_index];
00343 #if (NX_TD_STA)
00344
00345 struct td_sta_env_tag *tds_env = (sta_index < NX_REMOTE_STA_MAX) ? &td_sta_env[sta_index] : NULL;
00346 #endif //(NX_TD_STA)
00347
00348 TD_DEBUG_PRINT(3, D_CRT "td_pck_ind vif_idx=%d, sta_idx=%d, rx=%d\n", vif_index, sta_idx, rx);
00349
00350 if (rx)
00351 {
00352
00353 PROF_TD_CHECK_RX_SET();
00354
00355
00356 td_env->pck_cnt_rx++;
00357
00358 #if (NX_TD_STA)
00359
00360 ASSERT_ERR(tds_env);
00361
00362 if (tds_env->pck_cnt_rx < TD_DEFAULT_PCK_NB_THRES)
00363 {
00364 tds_env->pck_cnt_rx++;
00365 }
00366 #endif //(NX_TD_STA)
00367
00368
00369 PROF_TD_CHECK_RX_CLR();
00370 }
00371 else
00372 {
00373
00374 PROF_TD_CHECK_TX_SET();
00375
00376
00377 td_env->pck_cnt_tx++;
00378
00379 #if (NX_TD_STA)
00380 if (tds_env && (tds_env->pck_cnt_tx < TD_DEFAULT_PCK_NB_THRES))
00381 {
00382 tds_env->pck_cnt_tx++;
00383 }
00384 #endif //(NX_TD_STA)
00385
00386
00387 PROF_TD_CHECK_TX_CLR();
00388 }
00389 }
00390
00391 #if (NX_DPSM)
00392 void td_pck_ps_ind(uint8_t vif_index, bool rx)
00393 {
00394 TD_DEBUG_PRINT(3, D_CRT "td_pck_ps_ind idx=%d, rx=%d\n", vif_index, rx);
00395
00396 if (rx)
00397 {
00398
00399 PROF_TD_CHECK_RX_PS_SET();
00400
00401
00402 td_env_tab[vif_index].pck_cnt_rx_ps++;
00403
00404
00405 PROF_TD_CHECK_RX_PS_CLR();
00406 }
00407 else
00408 {
00409
00410 PROF_TD_CHECK_TX_PS_SET();
00411
00412
00413 td_env_tab[vif_index].pck_cnt_tx_ps++;
00414
00415
00416 PROF_TD_CHECK_TX_PS_CLR();
00417 }
00418 }
00419 #endif //(NX_DPSM)
00420
00421 #endif //(NX_TD)
00422