- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/umac/src/me/me_task.c

Go to the documentation of this file.

    00001
    00013 #include "me_task.h"
    00014 #include "me.h"
    00015
    00016 #include "mm.h"
    00017 #include "me_utils.h"
    00018 #include "scan_task.h"
    00019 //#include "tpm.h"
    00020 #include "dbg.h"
    00021 #include "rxu_task.h"
    00022 #include "sta_mgmt.h"
    00023 #include "vif_mgmt.h"
    00024 #include "ps.h"
    00025 #include "co_endian.h"
    00026
    00044 static int
    00045 me_config_req_handler(ke_msg_id_t const msgid,
    00046                       struct me_config_req const *param,
    00047                       ke_task_id_t const dest_id,
    00048                       ke_task_id_t const src_id)
    00049 {
    00050     #if NX_POWERSAVE
    00051     struct mm_set_ps_mode_req *ps = KE_MSG_ALLOC(MM_SET_PS_MODE_REQ, TASK_MM,
    00052                                                  TASK_ME, mm_set_ps_mode_req);
    00053     #endif
    00054
    00055     me_env.capa_flags = 0;
    00056
    00057     // Copy the HT, VHT and HE capabilities
    00058     if (param->ht_supp)
    00059     {
    00060         LOCAL_CAPA_SET(HT);
    00061         me_env.ht_cap = param->ht_cap;
    00062     }
    00063     #if NX_VHT
    00064     if (param->vht_supp)
    00065     {
    00066         LOCAL_CAPA_SET(VHT);
    00067         me_env.vht_cap = param->vht_cap;
    00068     }
    00069     #endif
    00070     #if NX_HE
    00071     if (param->he_supp)
    00072     {
    00073         LOCAL_CAPA_SET(HE);
    00074         me_env.he_cap = param->he_cap;
    00075     }
    00076     if (param->he_ul_on)
    00077     {
    00078         LOCAL_CAPA_SET(OFDMA_UL);
    00079     }
    00080     #endif
    00081
    00082     // Set maximum supported bandwidth
    00083     me_env.phy_bw_max = param->phy_bw_max;
    00084
    00085     ke_msg_send_basic(ME_CONFIG_CFM, src_id, dest_id);
    00086
    00087     // Perform additional checks depending on HT/VHT/HE support
    00088     if (LOCAL_CAPA(HT))
    00089     {
    00090         // Set the maximum number of NSS supported when using STBC for TX
    00091         me_env.stbc_nss = (phy_get_nss()+1)/2;
    00092
    00093         // Get the maximum BW supported
    00094         #if NX_HE
    00095         if (LOCAL_CAPA(HE))
    00096         {
    00097             bool stbc_tx_under_80 = HE_PHY_CAPA_BIT_IS_SET(&me_env.he_cap, STBC_TX_UNDER_80MHZ);
    00098             bool stbc_tx_above_80 = HE_PHY_CAPA_BIT_IS_SET(&me_env.he_cap, STBC_TX_ABOVE_80MHZ);
    00099
    00100             if (me_env.phy_bw_max > PHY_CHNL_BW_80)
    00101                 me_env.he_stbc_nss = stbc_tx_under_80 & stbc_tx_above_80 ? 1 : 0;
    00102             else
    00103                 me_env.he_stbc_nss = stbc_tx_under_80 ? 1 : 0;
    00104         }
    00105         #endif
    00106     }
    00107     else
    00108     {
    00109         me_env.stbc_nss = 0;
    00110     }
    00111
    00112     // Set the lifetime of packets sent under BA agreement
    00113     me_env.tx_lft = param->tx_lft;
    00114
    00115     #if NX_POWERSAVE
    00116     // Save PS mode flags
    00117     me_env.ps_on = param->ps_on;
    00118     me_env.ps_mode = param->dpsm ? PS_MODE_ON_DYN : PS_MODE_ON;
    00119
    00120     // Enable PS mode if required
    00121     if (me_env.ps_on)
    00122     {
    00123         // No requester ID
    00124         me_env.requester_id = TASK_NONE;
    00125
    00126         // Send the message to the LMAC
    00127         ps->new_state = me_env.ps_mode;
    00128         ke_msg_send(ps);
    00129
    00130         // Move to BUSY state
    00131         ke_state_set(TASK_ME, ME_BUSY);
    00132     }
    00133     #endif
    00134
    00135     #if (NX_ANT_DIV)
    00136     // Send message MM_ANT_DIV_INIT_REQ
    00137     struct mm_ant_div_init_req *req = KE_MSG_ALLOC(MM_ANT_DIV_INIT_REQ,
    00138                                                    TASK_MM, TASK_ME,
    00139                                                    mm_ant_div_init_req);
    00140     req->enable = param->ant_div_on;
    00141     ke_msg_send(req);
    00142     #endif //(NX_ANT_DIV)
    00143
    00144     return (KE_MSG_CONSUMED);
    00145 }
    00146
    00159 static int
    00160 me_chan_config_req_handler(ke_msg_id_t const msgid,
    00161                            struct me_chan_config_req const *param,
    00162                            ke_task_id_t const dest_id,
    00163                            ke_task_id_t const src_id)
    00164 {
    00165     // Copy the channel list
    00166     me_env.chan = *param;
    00167
    00168     ke_msg_send_basic(ME_CHAN_CONFIG_CFM, src_id, dest_id);
    00169
    00170     return (KE_MSG_CONSUMED);
    00171 }
    00172
    00188 static int
    00189 me_set_control_port_req_handler(ke_msg_id_t const msgid,
    00190                                 struct me_set_control_port_req const *param,
    00191                                 ke_task_id_t const dest_id,
    00192                                 ke_task_id_t const src_id)
    00193 {
    00194     // Get the STA entry
    00195     struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
    00196     // Get the associated VIF entry
    00197     struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
    00198
    00199     // Copy the HT and VHT capabilities
    00200     sta->ctrl_port_state = param->control_port_open?PORT_OPEN:PORT_CONTROLED;
    00201
    00202     // If port is open for a STA, reenable the PS mode now that the association is complete
    00203     // do not reenable PS mode in case of association with the TDLS station
    00204     if ((vif->type == VIF_STA) && (sta->ctrl_port_state == PORT_OPEN)
    00205         #if NX_TDLS
    00206          && !sta->is_tdls
    00207         #endif
    00208        )
    00209     {
    00210         struct me_set_ps_disable_req *ps = KE_MSG_ALLOC(ME_SET_PS_DISABLE_REQ, TASK_ME, TASK_SM,
    00211                                                         me_set_ps_disable_req);
    00212         ps->ps_disable = false;
    00213         ps->vif_idx = sta->inst_nbr;
    00214
    00215         ke_msg_send(ps);
    00216     }
    00217
    00218     ke_msg_send_basic(ME_SET_CONTROL_PORT_CFM, src_id, dest_id);
    00219
    00220     return (KE_MSG_CONSUMED);
    00221 }
    00222
    00237 static int
    00238 me_sta_add_req_handler(ke_msg_id_t const msgid,
    00239                        struct me_sta_add_req const *param,
    00240                        ke_task_id_t const dest_id,
    00241                        ke_task_id_t const src_id)
    00242 {
    00243     // Allocate the response structure
    00244     struct mm_sta_add_req sta_add_req;
    00245     struct me_sta_add_cfm *rsp = KE_MSG_ALLOC(ME_STA_ADD_CFM, src_id, dest_id, me_sta_add_cfm);
    00246     uint16_t ampdu_size_max_ht = 0;
    00247     uint32_t ampdu_size_max_vht = 0;
    00248     uint32_t ampdu_size_max_he = 0;
    00249     uint8_t ampdu_spacing_min = 0;
    00250     uint8_t hw_sta_idx;
    00251     uint8_t pm_state = rxu_cntrl_get_pm();
    00252     struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
    00253     uint32_t paid_gid = 0;
    00254
    00255     #if (NX_TDLS)
    00256     // In case of TDLS station disable PS
    00257     if (param->tdls_sta)
    00258     {
    00259         struct me_set_ps_disable_req *ps = KE_MSG_ALLOC(ME_SET_PS_DISABLE_REQ, TASK_ME, TASK_SM,
    00260                                                         me_set_ps_disable_req);
    00261         ps->ps_disable = true;
    00262         ps->vif_idx = param->vif_idx;
    00263
    00264         ke_msg_send(ps);
    00265     }
    00266     #endif
    00267
    00268     // Compute HT, VHT and HE A-MPDU parameters
    00269     if (param->flags & STA_HT_CAPA)
    00270     {
    00271         struct mac_htcapability const *ht_cap = &param->ht_cap;
    00272         struct mac_vhtcapability const *vht_cap = NULL;
    00273         struct mac_hecapability const *he_cap = NULL;
    00274
    00275         #if NX_VHT
    00276         if (param->flags & STA_VHT_CAPA)
    00277         {
    00278             vht_cap = &param->vht_cap;
    00279             // Compute the 'unicast' VHT partial AID and GID
    00280             switch (vif->type)
    00281             {
    00282                 // to TDLS STA
    00283                 case VIF_STA:
    00284                     paid_gid = mac_paid_gid_ap_compute(&vif->bss_info.bssid,
    00285                                                        param->aid);
    00286                     break;
    00287                 // to MESH STA
    00288                 case VIF_MESH_POINT:
    00289                     paid_gid = mac_paid_gid_sta_compute(&param->mac_addr);
    00290                     break;
    00291                 // from AP to associated STA
    00292                 case VIF_AP:
    00293                     paid_gid = mac_paid_gid_ap_compute(&vif->mac_addr, param->aid);
    00294                     break;
    00295                 default:
    00296                     break;
    00297             }
    00298         }
    00299         #endif
    00300
    00301         #if NX_HE
    00302         if (param->flags & STA_HE_CAPA)
    00303         {
    00304             he_cap = &param->he_cap;
    00305         }
    00306         #endif
    00307
    00308         me_get_ampdu_params(ht_cap, vht_cap, he_cap, &ampdu_size_max_ht,
    00309                             &ampdu_size_max_vht, &ampdu_size_max_he,
    00310                             &ampdu_spacing_min);
    00311     }
    00312
    00313     sta_add_req.paid_gid = paid_gid;
    00314     sta_add_req.mac_addr = param->mac_addr;
    00315     sta_add_req.bssid_index = 0;
    00316     sta_add_req.max_bssid_ind = 0;
    00317     sta_add_req.ampdu_size_max_ht = ampdu_size_max_ht;
    00318     sta_add_req.ampdu_size_max_vht = ampdu_size_max_vht;
    00319     sta_add_req.ampdu_spacing_min = ampdu_spacing_min;
    00320     sta_add_req.inst_nbr = param->vif_idx;
    00321     #if (NX_TDLS)
    00322     sta_add_req.tdls_sta = param->tdls_sta;
    00323     sta_add_req.tdls_initiator = param->tdls_initiator;
    00324     sta_add_req.tdls_chsw_allowed = param->tdls_chsw_allowed;
    00325     #endif
    00326
    00327     // Register the new station
    00328     rsp->status = mm_sta_add(&sta_add_req, &rsp->sta_idx, &hw_sta_idx);
    00329
    00330     // If station was successfully allocated
    00331     if (rsp->status == CO_OK)
    00332     {
    00333         struct sta_info_tag *sta = &sta_info_tab[rsp->sta_idx];
    00334         struct sta_capa_info *info = &sta->info;
    00335         struct me_bss_info *bss = &vif->bss_info;
    00336         bool smps = false;
    00337         // Initialize the capabilities of the new STA
    00338         info->rate_set = param->rate_set;
    00339         if (param->flags & STA_QOS_CAPA)
    00340         {
    00341             STA_CAPA_SET(sta, QOS);
    00342
    00343             if ((param->flags & STA_HT_CAPA) && LOCAL_CAPA(HT))
    00344             {
    00345                 STA_CAPA_SET(sta, HT);
    00346                 info->ht_cap = param->ht_cap;
    00347                 #if NX_HE
    00348                 if ((param->flags & STA_HE_CAPA) && LOCAL_CAPA(HE))
    00349                 {
    00350                     STA_CAPA_SET(sta, HE);
    00351                     info->he_cap = param->he_cap;
    00352                     #if NX_BEACONING
    00353                     if (LOCAL_CAPA(OFDMA_UL))
    00354                         txl_he_start_trigger_scheduler(sta);
    00355                     #endif
    00356                 }
    00357                 #endif
    00358                 #if NX_VHT
    00359                 if ((param->flags & STA_VHT_CAPA) &&
    00360                     (LOCAL_CAPA(VHT) || STA_CAPA(sta, HE)))
    00361                 {
    00362                     STA_CAPA_SET(sta, VHT);
    00363                     info->vht_cap = param->vht_cap;
    00364                 }
    00365                 #endif
    00366
    00367                 // Configure some HT and VHT parameters of the peer STA
    00368                 smps = me_set_sta_ht_vht_param(sta, bss);
    00369             }
    00370         }
    00371
    00372         #if NX_MFP
    00373         if (param->flags & STA_MFP_CAPA)
    00374         {
    00375             STA_CAPA_SET(sta, MFP);
    00376         }
    00377         #endif
    00378
    00379         // Initialize U-APSD parameters
    00380         info->uapsd_queues = param->uapsd_queues;
    00381         info->max_sp_len   = param->max_sp_len;
    00382         sta->aid = param->aid;
    00383
    00384         // Initialize the RC for this STA
    00385         me_init_rate(sta);
    00386
    00387         // Check if STA has notified operation mode in its AssocReq
    00388         if ((param->flags & STA_OPMOD_NOTIF) && !(param->opmode & MAC_OPMODE_RXNSS_TYPE_BIT))
    00389         {
    00390             uint8_t bw = (param->opmode & MAC_OPMODE_BW_MSK) >> MAC_OPMODE_BW_OFT;
    00391             uint8_t nss = (param->opmode & MAC_OPMODE_RXNSS_MSK) >> MAC_OPMODE_RXNSS_OFT;
    00392
    00393             // Update maximum supported bandwidth
    00394             me_sta_bw_nss_max_upd(sta->staid, bw, nss);
    00395         }
    00396
    00397         // Check if STA is using SMPS
    00398         if (smps)
    00399         {
    00400             // Allow only 1 SS to be transmitted
    00401             me_sta_bw_nss_max_upd(sta->staid, 0xFF, 0);
    00402         }
    00403
    00404         // Initialize tx power on first transmit
    00405         sta->pol_tbl.upd_field |= CO_BIT(STA_MGMT_POL_UPD_TX_POWER);
    00406
    00407         // Init port status
    00408         sta->ctrl_port_state = (vif->flags & CONTROL_PORT_HOST)?PORT_CONTROLED:PORT_OPEN;
    00409         sta->ctrl_port_ethertype = co_ntohs(vif->u.ap.ctrl_port_ethertype);
    00410
    00411         // Get the PM state of the station in case it was catched by the PM monitor
    00412         rsp->pm_state = pm_state;
    00413
    00414         if (rsp->pm_state)
    00415         {
    00416             // Set the PM state of the station
    00417             sta->ps_state = pm_state;
    00418
    00419             // Update the number of PS stations
    00420             if (!vif->u.ap.ps_sta_cnt)
    00421             {
    00422                 PROF_PS_BCMC_STATE_SET();
    00423                 PROF_PS_STATE_VAL_SET(PS_MODE_ON);
    00424                 mm_ps_change_ind(VIF_TO_BCMC_IDX(vif->index), PS_MODE_ON);
    00425                 PROF_PS_BCMC_STATE_CLR();
    00426             }
    00427
    00428             // Update the number of PS stations
    00429             vif->u.ap.ps_sta_cnt++;
    00430
    00431             #if (NX_P2P_GO)
    00432             p2p_go_ps_state_update(vif);
    00433             #endif //(NX_P2P_GO)
    00434         }
    00435     }
    00436
    00437     // Send the confirmation
    00438     ke_msg_send(rsp);
    00439
    00440     return (KE_MSG_CONSUMED);
    00441 }
    00442
    00443
    00456 static int
    00457 me_sta_del_req_handler(ke_msg_id_t const msgid,
    00458                        struct me_sta_del_req const *param,
    00459                        ke_task_id_t const dest_id,
    00460                        ke_task_id_t const src_id)
    00461 {
    00462     struct mm_sta_del_req *sta_del = KE_MSG_ALLOC(MM_STA_DEL_REQ, TASK_MM,
    00463                                                   TASK_ME, mm_sta_del_req);
    00464     #if NX_AMPDU_TX || NX_REORD
    00465     // Release all the Block Ack agreement
    00466     bam_delete_all_ba_agg(param->sta_idx);
    00467     #endif
    00468
    00469     // Send the message to the LowerMAC
    00470     sta_del->sta_idx = param->sta_idx;
    00471     ke_msg_send(sta_del);
    00472
    00473     // In case of TDLS station enable PS
    00474     if (param->tdls_sta)
    00475     {
    00476         struct me_set_ps_disable_req *ps = KE_MSG_ALLOC(ME_SET_PS_DISABLE_REQ, TASK_ME, TASK_SM,
    00477                                                         me_set_ps_disable_req);
    00478         ps->ps_disable = false;
    00479         ps->vif_idx = sta_mgmt_get_vif_idx(param->sta_idx);
    00480         ke_msg_send(ps);
    00481     }
    00482
    00483     // Send the confirmation to the upper MAC
    00484     ke_msg_send_basic(ME_STA_DEL_CFM, src_id, dest_id);
    00485
    00486     return (KE_MSG_CONSUMED);
    00487 }
    00488
    00489
    00502 static int
    00503 me_traffic_ind_req_handler(ke_msg_id_t const msgid,
    00504                            struct me_traffic_ind_req const *param,
    00505                            ke_task_id_t const dest_id,
    00506                            ke_task_id_t const src_id)
    00507 {
    00508     struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
    00509     // Indicate if MM_TIM_UPDATE_REQ message must be sent
    00510     bool send_req = true;
    00511
    00512     if (param->uapsd)
    00513     {
    00514         // Update the traffic flag in the STA entry
    00515         if (param->tx_avail)
    00516             sta->traffic_avail |= UAPSD_TRAFFIC_HOST;
    00517         else
    00518             sta->traffic_avail &= ~UAPSD_TRAFFIC_HOST;
    00519
    00520         if (sta->info.uapsd_queues != MAC_QOS_INFO_STA_UAPSD_ENABLED_ALL)
    00521         {
    00522             send_req = false;
    00523         }
    00524     }
    00525     else
    00526     {
    00527         if (param->tx_avail)
    00528             sta->traffic_avail |= PS_TRAFFIC_HOST;
    00529         else
    00530             sta->traffic_avail &= ~PS_TRAFFIC_HOST;
    00531     }
    00532
    00533     if (send_req)
    00534     {
    00535         struct mm_tim_update_req *tim = KE_MSG_ALLOC(MM_TIM_UPDATE_REQ, TASK_MM,
    00536                                                      TASK_ME, mm_tim_update_req);
    00537
    00538         tim->aid = sta->aid;
    00539         tim->inst_nbr = sta->inst_nbr;
    00540         tim->tx_avail = param->tx_avail;
    00541
    00542         ke_msg_send(tim);
    00543     }
    00544
    00545     // Send the confirmation to the upper MAC
    00546     ke_msg_send_basic(ME_TRAFFIC_IND_CFM, src_id, dest_id);
    00547
    00548     return (KE_MSG_CONSUMED);
    00549 }
    00550
    00551
    00565 static int
    00566 me_set_active_req_handler(ke_msg_id_t const msgid,
    00567                           struct me_set_active_req const *param,
    00568                           ke_task_id_t const dest_id,
    00569                           ke_task_id_t const src_id)
    00570 {
    00571     // Check if the request can be handled immediately
    00572     if (ke_state_get(TASK_ME) == ME_BUSY)
    00573         return (KE_MSG_SAVED);
    00574
    00575     // Check if the current state is already OK
    00576     if ((me_env.active_vifs && param->active) ||
    00577         (!me_env.active_vifs && !param->active))
    00578     {
    00579         // Update the bit corresponding to the VIF
    00580         if (param->active)
    00581             me_env.active_vifs |= CO_BIT(param->vif_idx);
    00582
    00583         // Send the confirmation immediately
    00584         ke_msg_send_basic(ME_SET_ACTIVE_CFM, src_id, dest_id);
    00585     }
    00586     else
    00587     {
    00588         struct mm_set_idle_req *active =  KE_MSG_ALLOC(MM_SET_IDLE_REQ, TASK_MM,
    00589                                                        dest_id, mm_set_idle_req);
    00590
    00591         // Update the bit corresponding to the VIF
    00592         if (param->active)
    00593             me_env.active_vifs |= CO_BIT(param->vif_idx);
    00594         else
    00595             me_env.active_vifs &= ~CO_BIT(param->vif_idx);
    00596
    00597         // Save the ID of the requester
    00598         me_env.requester_id = src_id;
    00599
    00600         // Send the message to the LMAC
    00601         active->hw_idle = (me_env.active_vifs == 0);
    00602         ke_msg_send(active);
    00603
    00604         // Move to BUSY state
    00605         ke_state_set(dest_id, ME_BUSY);
    00606     }
    00607
    00608     return (KE_MSG_CONSUMED);
    00609 }
    00610
    00623 static int
    00624 mm_set_idle_cfm_handler(ke_msg_id_t const msgid,
    00625                         void const *param,
    00626                         ke_task_id_t const dest_id,
    00627                         ke_task_id_t const src_id)
    00628 {
    00629     // Sanity check - This message can be received only in the BUSY state
    00630     ASSERT_ERR(ke_state_get(dest_id) == ME_BUSY);
    00631
    00632     // Send the confirmation to the requester
    00633     if (me_env.requester_id != TASK_NONE)
    00634         ke_msg_send_basic(ME_SET_ACTIVE_CFM, me_env.requester_id, dest_id);
    00635
    00636     // Back to IDLE state
    00637     ke_state_set(dest_id, ME_IDLE);
    00638
    00639     return (KE_MSG_CONSUMED);
    00640 }
    00641
    00655 static int
    00656 me_set_ps_disable_req_handler(ke_msg_id_t const msgid,
    00657                               struct me_set_ps_disable_req const *param,
    00658                               ke_task_id_t const dest_id,
    00659                               ke_task_id_t const src_id)
    00660 {
    00661     #if NX_POWERSAVE
    00662     uint8_t ps_disable_vifs = me_env.ps_disable_vifs;
    00663
    00664     // Update the bit corresponding to the VIF
    00665     if (param->ps_disable)
    00666         me_env.ps_disable_vifs |= CO_BIT(param->vif_idx);
    00667     else
    00668         me_env.ps_disable_vifs &= ~CO_BIT(param->vif_idx);
    00669
    00670     // Check if PS is enabled or not
    00671     if (!me_env.ps_on)
    00672     {
    00673         // Send the confirmation immediately
    00674         ke_msg_send_basic(ME_SET_PS_DISABLE_CFM, src_id, dest_id);
    00675
    00676         return (KE_MSG_CONSUMED);
    00677     }
    00678
    00679     // Check if the request can be handled immediately
    00680     if (ke_state_get(TASK_ME) == ME_BUSY)
    00681         return (KE_MSG_SAVED);
    00682
    00683     // Check if the current state is already OK
    00684     if ((ps_disable_vifs && param->ps_disable) ||
    00685         (!ps_disable_vifs && !param->ps_disable))
    00686     {
    00687         // Send the confirmation immediately
    00688         ke_msg_send_basic(ME_SET_PS_DISABLE_CFM, src_id, dest_id);
    00689     }
    00690     else
    00691     {
    00692         struct mm_set_ps_mode_req *ps = KE_MSG_ALLOC(MM_SET_PS_MODE_REQ, TASK_MM,
    00693                                                      dest_id, mm_set_ps_mode_req);
    00694
    00695         // Save the ID of the requester
    00696         me_env.requester_id = src_id;
    00697
    00698         // Send the message to the LMAC
    00699         ps->new_state = (me_env.ps_disable_vifs == 0)?me_env.ps_mode:PS_MODE_OFF;
    00700         ke_msg_send(ps);
    00701
    00702         // Move to BUSY state
    00703         ke_state_set(dest_id, ME_BUSY);
    00704     }
    00705     #else
    00706     // Send the confirmation immediately
    00707     ke_msg_send_basic(ME_SET_PS_DISABLE_CFM, src_id, dest_id);
    00708     #endif
    00709
    00710     return (KE_MSG_CONSUMED);
    00711 }
    00712
    00713 #if NX_POWERSAVE
    00714
    00726 static int
    00727 me_set_ps_mode_req_handler(ke_msg_id_t const msgid,
    00728                            struct me_set_ps_mode_req const *param,
    00729                            ke_task_id_t const dest_id,
    00730                            ke_task_id_t const src_id)
    00731 {
    00732     struct mm_set_ps_mode_req *ps;
    00733
    00734     // Check if the request can be handled immediately
    00735     if (ke_state_get(TASK_ME) == ME_BUSY)
    00736         return (KE_MSG_SAVED);
    00737
    00738
    00739     me_env.ps_on = param->ps_state > 0 ? true : false;
    00740
    00741     if (me_env.ps_disable_vifs != 0)
    00742     {
    00743         ke_msg_send_basic(ME_SET_PS_MODE_CFM, src_id, dest_id);
    00744         return (KE_MSG_CONSUMED);
    00745     }
    00746
    00747     ps = KE_MSG_ALLOC(MM_SET_PS_MODE_REQ, TASK_MM, TASK_ME, mm_set_ps_mode_req);
    00748
    00749     // No requester ID
    00750     me_env.requester_id = TASK_NONE;
    00751
    00752     // Send the message to the LMAC
    00753     ps->new_state = (me_env.ps_on) ? me_env.ps_mode : PS_MODE_OFF;
    00754     ke_msg_send(ps);
    00755
    00756     // Move to BUSY state
    00757     ke_state_set(TASK_ME, ME_BUSY);
    00758
    00759     ke_msg_send_basic(ME_SET_PS_MODE_CFM, src_id, dest_id);
    00760
    00761     return (KE_MSG_CONSUMED);
    00762 }
    00763
    00776 static int
    00777 mm_set_ps_mode_cfm_handler(ke_msg_id_t const msgid,
    00778                            void const *param,
    00779                            ke_task_id_t const dest_id,
    00780                            ke_task_id_t const src_id)
    00781 {
    00782     // Sanity check - This message can be received only in the BUSY state
    00783     ASSERT_ERR(ke_state_get(dest_id) == ME_BUSY);
    00784
    00785     // Send the confirmation to the requester
    00786     if (me_env.requester_id != TASK_NONE)
    00787         ke_msg_send_basic(ME_SET_PS_DISABLE_CFM, me_env.requester_id, dest_id);
    00788
    00789     // Back to IDLE state
    00790     ke_state_set(dest_id, ME_IDLE);
    00791
    00792     return (KE_MSG_CONSUMED);
    00793 }
    00794 #endif
    00795
    00808 static int
    00809 me_rc_stats_req_handler(ke_msg_id_t const msgid,
    00810                        struct me_rc_stats_req const *param,
    00811                        ke_task_id_t const dest_id,
    00812                        ke_task_id_t const src_id)
    00813 {
    00814     // Allocate the response structure
    00815     struct me_rc_stats_cfm *rsp = KE_MSG_ALLOC(ME_RC_STATS_CFM, src_id, dest_id, me_rc_stats_cfm);
    00816
    00817     // retrieve statistics for the requested station (number sta_idx)
    00818     struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
    00819     struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
    00820     struct rc_sta_stats *rc_ss = rc->sta_stats;
    00821     uint16_t i;
    00822
    00823     // set station index
    00824     rsp->sta_idx = param->sta_idx;
    00825     if (rc_ss)
    00826     {
    00827         // set number of samples
    00828         rsp->no_samples = rc_ss->no_samples;
    00829         // set number of MPDUs transmitted (per sampling interval)
    00830         rsp->ampdu_len = rc_ss->ampdu_len;
    00831         // set number of AMPDUs transmitted (per sampling interval)
    00832         rsp->ampdu_packets = rc_ss->ampdu_packets;
    00833         // set average number of MPDUs in each AMPDU frame (EWMA)
    00834         rsp->avg_ampdu_len = rc_ss->avg_ampdu_len;
    00835         // set step 0 of the retry chain
    00836         rsp->sw_retry_step = rc_ss->sw_retry_step;
    00837         // set current value of the trial TX countdown
    00838         rsp->sample_wait = rc_ss->sample_wait;
    00839         // copy the retry chain steps
    00840         memcpy(rsp->retry_step_idx, rc_ss->retry_step_idx, sizeof(rsp->retry_step_idx));
    00841         // copy the statistics (only the first RC_MAX_N_SAMPLE)
    00842         memcpy(&rsp->rate_stats[0], &rc_ss->rate_stats[0], sizeof(rsp->rate_stats) -
    00843                                                     NX_HE * sizeof(struct rc_rate_stats));
    00844         // calculate TP
    00845         for (i = 0; i < rc_ss->no_samples; i++)
    00846         {
    00847             rsp->tp[i] = rc_calc_tp(rc_ss, i);
    00848         }
    00849         #if NX_HE
    00850         GLOBAL_INT_DISABLE();
    00851         // Copy the HE statistics - must be done with interrupt disabled as some parts
    00852         // are modified under interrupt
    00853         rsp->rate_stats[RC_HE_STATS_IDX] = rc_ss->rate_stats[RC_HE_STATS_IDX];
    00854         // calculate HE TB throughput
    00855         rsp->tp[RC_HE_STATS_IDX] = rc_calc_tp(rc_ss, RC_HE_STATS_IDX);
    00856         GLOBAL_INT_RESTORE();
    00857         #endif
    00858     }
    00859     else
    00860     {
    00861         rsp->no_samples = 0;
    00862     }
    00863
    00864     // Send the confirmation
    00865     ke_msg_send(rsp);
    00866
    00867     return (KE_MSG_CONSUMED);
    00868 }
    00869
    00882 static int
    00883 me_rc_set_rate_req_handler(ke_msg_id_t const msgid,
    00884                            struct me_rc_set_rate_req const *param,
    00885                            ke_task_id_t const dest_id,
    00886                            ke_task_id_t const src_id)
    00887 {
    00888     struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
    00889     struct sta_pol_tbl_cntl *pt = &sta->pol_tbl;
    00890     struct rc_sta_stats *rc_ss = pt->sta_stats;
    00891     ASSERT_ERR(rc_ss != NULL);
    00892     uint16_t fixed_rate_cfg = param->fixed_rate_cfg;
    00893
    00894     if (fixed_rate_cfg != RC_FIXED_RATE_NOT_SET)
    00895     {
    00896         if (rc_check_fixed_rate_config(rc_ss, fixed_rate_cfg))
    00897         {
    00898             // Set the fixed rate configuration in the RC structure
    00899             rc_ss->fixed_rate_cfg = fixed_rate_cfg;
    00900             // Update the fixed rate request flag
    00901             rc_ss->info &= ~RC_FIX_RATE_STATUS_MASK;
    00902             rc_ss->info |= RC_FIX_RATE_REQ_MASK;
    00903         }
    00904     }
    00905     else
    00906     {
    00907         // Set the fixed rate configuration in the RC structure
    00908         rc_ss->fixed_rate_cfg = fixed_rate_cfg;
    00909         rc_ss->info &= ~RC_FIX_RATE_STATUS_MASK;
    00910         // Check if the rates should be updated
    00911         if (rc_ss->info & RC_FIX_RATE_UPD_SS_REQ_MASK)
    00912         {
    00913             // Update the rates of rate control algorithm
    00914             rc_update_sample_table(param->sta_idx);
    00915             rc_ss->info &= ~RC_FIX_RATE_UPD_SS_REQ_MASK;
    00916         }
    00917     }
    00918
    00919     return (KE_MSG_CONSUMED);
    00920 }
    00921
    00922
    00935 static int
    00936 me_config_monitor_req_handler(ke_msg_id_t const msgid,
    00937                               struct me_config_monitor_req const *param,
    00938                               ke_task_id_t const dest_id,
    00939                               ke_task_id_t const src_id)
    00940 {
    00941     struct me_config_monitor_cfm *rsp;
    00942     struct vif_info_tag *vif;
    00943
    00944     // Check if the request can be handled immediately
    00945     if (ke_state_get(TASK_ME) == ME_BUSY)
    00946         return (KE_MSG_SAVED);
    00947
    00948     // Allocate the response structure
    00949     rsp = KE_MSG_ALLOC(ME_CONFIG_MONITOR_CFM, src_id, dest_id, me_config_monitor_cfm);
    00950
    00951     // Sanity check - One monitor interface shall exist
    00952     ASSERT_ERR(vif_mgmt_env.monitor_vif != INVALID_VIF_IDX);
    00953     vif = &vif_info_tab[vif_mgmt_env.monitor_vif];
    00954
    00955     #if NX_UF_EN
    00956     if (phy_uf_supported())
    00957         phy_uf_enable(param->uf);
    00958     #endif /* NX_UF_EN */
    00959
    00960     if (!vif->chan_ctxt)
    00961     {
    00962         rsp->chan_index = CHAN_CTXT_UNUSED;
    00963         ke_msg_send(rsp);
    00964         return (KE_MSG_CONSUMED);
    00965     }
    00966
    00967     rsp->chan_index = vif->chan_ctxt->idx;
    00968
    00969     // Check if there is no active managed interface
    00970     if ((param->chan_set) && (co_list_cnt(&vif_mgmt_env.used_list) == 1))
    00971     {
    00972         struct mm_chan_ctxt_update_req *req = KE_MSG_ALLOC(MM_CHAN_CTXT_UPDATE_REQ, TASK_MM, TASK_ME,
    00973                                                                mm_chan_ctxt_update_req);
    00974
    00975         // Fill-in the channel context addition request
    00976         req->chan_index = vif->chan_ctxt->idx;
    00977         req->chan = param->chan;
    00978
    00979         // Send the message
    00980         ke_msg_send(req);
    00981
    00982         // The channel has been updated as requested
    00983         rsp->chan = param->chan;
    00984     }
    00985     else
    00986     {
    00987         // The channel has not been updated, inform host which one is in use.
    00988         rsp->chan = vif->chan_ctxt->channel;
    00989     }
    00990
    00991     ke_msg_send(rsp);
    00992
    00993     return (KE_MSG_CONSUMED);
    00994 }
    00995
    00997 const struct ke_msg_handler me_default_state[] =
    00998 {
    00999     {ME_CONFIG_REQ, (ke_msg_func_t)me_config_req_handler},
    01000     {ME_CHAN_CONFIG_REQ, (ke_msg_func_t)me_chan_config_req_handler},
    01001     {ME_SET_CONTROL_PORT_REQ, (ke_msg_func_t)me_set_control_port_req_handler},
    01002     {ME_STA_ADD_REQ, (ke_msg_func_t)me_sta_add_req_handler},
    01003     {ME_STA_DEL_REQ, (ke_msg_func_t)me_sta_del_req_handler},
    01004     {ME_SET_ACTIVE_REQ, (ke_msg_func_t)me_set_active_req_handler},
    01005     {ME_SET_PS_DISABLE_REQ, (ke_msg_func_t)me_set_ps_disable_req_handler},
    01006     {ME_TRAFFIC_IND_REQ, (ke_msg_func_t)me_traffic_ind_req_handler},
    01007     {ME_SET_ACTIVE_CFM, ke_msg_discard},
    01008     {MM_SET_IDLE_CFM, (ke_msg_func_t)mm_set_idle_cfm_handler},
    01009     #if NX_POWERSAVE
    01010     {ME_SET_PS_MODE_REQ, (ke_msg_func_t)me_set_ps_mode_req_handler},
    01011     {MM_SET_PS_MODE_CFM, (ke_msg_func_t)mm_set_ps_mode_cfm_handler},
    01012     #endif
    01013     {MM_STA_DEL_CFM, ke_msg_discard},
    01014     {MM_CHAN_CTXT_UPDATE_CFM, ke_msg_discard},
    01015     {MM_TIM_UPDATE_CFM, ke_msg_discard},
    01016     {MM_SET_EDCA_CFM, ke_msg_discard},
    01017     {MM_SET_MU_EDCA_CFM, ke_msg_discard},
    01018     {MM_SET_UORA_CFM, ke_msg_discard},
    01019     {MM_SET_TXOP_RTS_THRES_CFM, ke_msg_discard},
    01020     {MM_SET_BSS_COLOR_CFM, ke_msg_discard},
    01021     {ME_RC_STATS_REQ, (ke_msg_func_t)me_rc_stats_req_handler},
    01022     {ME_RC_SET_RATE_REQ, (ke_msg_func_t)me_rc_set_rate_req_handler},
    01023     {ME_CONFIG_MONITOR_REQ, (ke_msg_func_t)me_config_monitor_req_handler},
    01024 };
    01025
    01026
    01028 const struct ke_state_handler me_default_handler = KE_STATE_HANDLER(me_default_state);
    01029
    01030
    01032 ke_state_t me_state[ME_IDX_MAX];
    01033
    01034