- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/lmac/src/tdls/tdls_task.c

Go to the documentation of this file.

    00001
    00020 /*
    00021  * INCLUDE FILES
    00022  ****************************************************************************************
    00023  */
    00024 #include "co_endian.h"
    00025
    00026 #include "mac_frame.h"
    00027 #include "tdls.h"
    00028 #include "ps.h"
    00029 #if NX_UMAC_PRESENT
    00030 #include "me.h"
    00031 #include "rxu_cntrl.h"
    00032 #endif
    00033 #include "tdls_task.h"
    00034 #include "mm_bcn.h"
    00035 #include "phy.h"
    00036
    00037 #include "reg_mac_pl.h"
    00038 #include "reg_mac_core.h"
    00039 #include "hal_machw.h"
    00040 #include "dbg.h"
    00041
    00042 #include "rxl_cntrl.h"
    00043 #include "txl_cntrl.h"
    00044
    00045 #include "sta_mgmt.h"
    00046 #include "vif_mgmt.h"
    00047
    00048 #include "version.h"
    00049
    00050 #include "mm_timer.h"
    00051
    00052 #include "chan.h"
    00053 #if (RW_BFMER_EN)
    00054 #include "bfr.h"
    00055 #endif //(RW_BFMER_EN)
    00056
    00057 #include "tpc.h"
    00058 #include "mm.h"
    00059
    00060 #if (NX_TDLS)
    00061
    00062 /*
    00063  * MESSAGE HANDLERS
    00064  ****************************************************************************************
    00065  */
    00066
    00080 static
    00081 int tdls_chan_switch_req_handler(ke_msg_id_t const msgid,
    00082                                  struct tdls_chan_switch_req const *param,
    00083                                  ke_task_id_t const dest_id,
    00084                                  ke_task_id_t const src_id)
    00085 {
    00086     uint8_t status = CO_FAIL;
    00087
    00088     #if NX_UMAC_PRESENT
    00089     do
    00090     {
    00091         struct vif_info_tag *vif;
    00092         struct sta_info_tag *sta;
    00093
    00094         if (param->vif_index == INVALID_VIF_IDX)
    00095         {
    00096             break;
    00097         }
    00098         vif = &vif_info_tab[param->vif_index];
    00099
    00100         if ((param->sta_idx == INVALID_STA_IDX) ||
    00101             (vif->u.sta.tdls_chsw_sta_idx != INVALID_STA_IDX))
    00102         {
    00103             break;
    00104         }
    00105
    00106         // Set TDLS STA index for channel switch request
    00107         vif->u.sta.tdls_chsw_sta_idx = param->sta_idx;
    00108         sta = &sta_info_tab[param->sta_idx];
    00109
    00110         if (!sta->tdls.chsw_allowed)
    00111         {
    00112             TRACE_TDLS(ERR, "TDLS channel switch is not allowed.");
    00113             break;
    00114         }
    00115
    00116         // Set the parameters
    00117         if (sta->valid)
    00118         {
    00119             sta->tdls.chsw = param->chan;
    00120             sta->tdls.chsw_op_class = param->op_class;
    00121             sta->tdls.chsw_req_timer.cb = tdls_chsw_req_evt;
    00122             sta->tdls.chsw_req_timer.env = vif;
    00123             sta->tdls.chsw_active = true;
    00124             sta->tdls.chsw_initiator = false;
    00125
    00126             status = CO_OK;
    00127
    00128             // Reset state
    00129             ke_state_set(TASK_TDLS, TDLS_BASE_CHANNEL);
    00130
    00131             PROF_TDLS_CHSW_REQ_TX_TIMER_SET();
    00132             // Set next channel switch request
    00133             mm_timer_set(&sta->tdls.chsw_req_timer,
    00134                     vif->tbtt_timer.time + TDLS_CHSW_REQ_DELAY_US);
    00135         }
    00136     } while(0);
    00137     #endif // NX_UMAC_PRESENT
    00138
    00139     // Send back the confirmation
    00140     struct tdls_chan_switch_cfm *cfm = KE_MSG_ALLOC(TDLS_CHAN_SWITCH_CFM,
    00141             src_id, dest_id,
    00142             tdls_chan_switch_cfm);
    00143     cfm->status = status;
    00144
    00145     ke_msg_send(cfm);
    00146
    00147     return (KE_MSG_CONSUMED);
    00148 }
    00149
    00163 static
    00164 int tdls_cancel_chan_switch_req_handler(ke_msg_id_t const msgid,
    00165                                         struct tdls_cancel_chan_switch_req const *param,
    00166                                         ke_task_id_t const dest_id,
    00167                                         ke_task_id_t const src_id)
    00168 {
    00169     uint8_t status = CO_FAIL;
    00170
    00171     #if NX_UMAC_PRESENT
    00172     do
    00173     {
    00174         struct vif_info_tag *vif = &vif_info_tab[param->vif_index];
    00175         struct sta_info_tag *sta;
    00176
    00177         if (param->sta_idx == INVALID_STA_IDX)
    00178         {
    00179             break;
    00180         }
    00181
    00182         if (param->sta_idx != vif->u.sta.tdls_chsw_sta_idx)
    00183         {
    00184             TRACE_TDLS(ERR, "TDLS Channel Switch is not active for STA %d.", param->sta_idx);
    00185             break;
    00186         }
    00187
    00188         sta = &sta_info_tab[param->sta_idx];
    00189         // Clear channel switch request timer
    00190         PROF_TDLS_CHSW_REQ_TX_TIMER_CLR();
    00191         mm_timer_clear(&sta->tdls.chsw_req_timer);
    00192         sta->tdls.chsw_active = false;
    00193         sta->tdls.chsw_initiator = false;
    00194         if (ke_state_get(TASK_TDLS) == TDLS_BASE_CHANNEL)
    00195         {
    00196             // If already on base channel, reset TDLS ChSw station index
    00197             vif->u.sta.tdls_chsw_sta_idx = INVALID_STA_IDX;
    00198         }
    00199         else
    00200         {
    00201             // If on off channel, switch back to base channel
    00202             struct mm_remain_on_channel_req roc_param;
    00203
    00204             PROF_TDLS_CHSW_TIME_TIMER_CLR();
    00205             mm_timer_clear(&sta->tdls.chsw_time_timer);
    00206             PROF_TDLS_CHSW_END_TIMER_CLR();
    00207             mm_timer_clear(&sta->tdls.chsw_end_timer);
    00208             roc_param.vif_index = vif->index;
    00209             roc_param.op_code = MM_ROC_OP_CANCEL;
    00210             PROF_TDLS_SWITCH_TO_BASECH_SET();
    00211             chan_roc_req(&roc_param, TASK_TDLS);
    00212             PROF_TDLS_SWITCH_TO_BASECH_CLR();
    00213
    00214             ke_state_set(TASK_TDLS, TDLS_BASE_CHANNEL);
    00215         }
    00216         status = CO_OK;
    00217     } while (0);
    00218
    00219     #endif // NX_UMAC_PRESENT
    00220
    00221     // Send back the confirmation
    00222     struct tdls_cancel_chan_switch_cfm *cfm = KE_MSG_ALLOC(TDLS_CANCEL_CHAN_SWITCH_CFM,
    00223             src_id, dest_id,
    00224             tdls_cancel_chan_switch_cfm);
    00225     cfm->status = status;
    00226
    00227     ke_msg_send(cfm);
    00228
    00229     return (KE_MSG_CONSUMED);
    00230 }
    00231
    00232 #if NX_UMAC_PRESENT
    00233
    00246 static
    00247 int tdls_peer_traffic_ind_req_handler(ke_msg_id_t const msgid,
    00248                               struct tdls_peer_traffic_ind_req const *param,
    00249                               ke_task_id_t const dest_id,
    00250                               ke_task_id_t const src_id)
    00251 {
    00252     uint8_t status = CO_FAIL;
    00253
    00254     if (param->sta_idx == INVALID_STA_IDX)
    00255     {
    00256         return status;
    00257     }
    00258
    00259     // Send Peer Traffic Indication frame
    00260     status = txl_frame_send_tdls_peer_traffic_ind_frame(param, &tdls_peer_traffic_ind_tx_cfm);
    00261
    00262     if (status == CO_OK)
    00263     {
    00264         struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
    00265         // set dialog token
    00266         sta->tdls.dialog_token = param->dialog_token;
    00267         // keep in mind that there is traffic bufferized at host level
    00268         sta->tdls.traffic_available = true;
    00269         // set TDLS STA status
    00270         ke_state_set(TASK_TDLS, TDLS_TRAFFIC_IND_TX);
    00271     }
    00272
    00273     // Send back the confirmation
    00274     struct tdls_peer_traffic_ind_cfm *cfm = KE_MSG_ALLOC(TDLS_PEER_TRAFFIC_IND_CFM,
    00275                                                          src_id, dest_id,
    00276                                                          tdls_peer_traffic_ind_cfm);
    00277     cfm->status = status;
    00278
    00279     ke_msg_send(cfm);
    00280
    00281     return (KE_MSG_CONSUMED);
    00282
    00283 }
    00284 #endif // NX_UMAC_PRESENT
    00285
    00286 /*
    00287  * TASK DESCRIPTOR DEFINITIONS
    00288  ****************************************************************************************
    00289  */
    00291 const struct ke_msg_handler tdls_default_state[] =
    00292 {
    00293     // From UMAC
    00294     {TDLS_CHAN_SWITCH_REQ, (ke_msg_func_t)tdls_chan_switch_req_handler},
    00295     // From UMAC
    00296     {TDLS_CANCEL_CHAN_SWITCH_REQ, (ke_msg_func_t)tdls_cancel_chan_switch_req_handler},
    00297 #if (NX_UMAC_PRESENT)
    00298     // From UMAC
    00299     {TDLS_PEER_TRAFFIC_IND_REQ, (ke_msg_func_t)tdls_peer_traffic_ind_req_handler},
    00300 #endif
    00301 };
    00302
    00304 const struct ke_state_handler tdls_default_handler =
    00305     KE_STATE_HANDLER(tdls_default_state);
    00306
    00308 ke_state_t tdls_state[TDLS_IDX_MAX];
    00309
    00310 #endif // NX_TDLS
    00311