- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/lmac/src/mm/mm_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 "mm.h"
    00028 #include "ps.h"
    00029 #if NX_UMAC_PRESENT
    00030 #include "me.h"
    00031 #include "rxu_cntrl.h"
    00032 #endif
    00033 #include "mm_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_hwdesc.h"
    00043 #include "rxl_cntrl.h"
    00044 #include "txl_cntrl.h"
    00045
    00046 #include "sta_mgmt.h"
    00047 #include "vif_mgmt.h"
    00048
    00049 #include "version.h"
    00050
    00051 #include "ke_timer.h"
    00052
    00053 #include "chan.h"
    00054 #if (RW_BFMER_EN)
    00055 #include "bfr.h"
    00056 #endif //(RW_BFMER_EN)
    00057
    00058 #include "tpc.h"
    00059
    00060 /*
    00061  * MESSAGE HANDLERS
    00062  ****************************************************************************************
    00063  */
    00079 static int
    00080 mm_version_req_handler(ke_msg_id_t const msgid,
    00081                        void const *param,
    00082                        ke_task_id_t const dest_id,
    00083                        ke_task_id_t const src_id)
    00084 {
    00085     // Allocate the response message
    00086     struct mm_version_cfm *msg = KE_MSG_ALLOC(MM_VERSION_CFM, src_id, dest_id,
    00087                                               mm_version_cfm);
    00088
    00089     // Fill in the parameters
    00090     msg->version_lmac = NX_VERSION;
    00091     msg->version_machw_1 = nxmac_version_1_get();
    00092     msg->version_machw_2 = nxmac_version_2_get();
    00093     msg->max_sta_nb = NX_REMOTE_STA_MAX;
    00094     msg->max_vif_nb = NX_VIRT_DEV_MAX;
    00095     phy_get_version(&msg->version_phy_1, &msg->version_phy_2);
    00096
    00097     msg->features = (0
    00098     #if (NX_BEACONING)
    00099             | CO_BIT(MM_FEAT_BCN_BIT)
    00100     #endif //(NX_BEACONING)
    00101     #if (NX_BCN_AUTONOMOUS_TX)
    00102             | CO_BIT(MM_FEAT_AUTOBCN_BIT)
    00103     #endif //(NX_BCN_AUTONOMOUS_TX)
    00104     #if (NX_HW_SCAN)
    00105             | CO_BIT(MM_FEAT_HWSCAN_BIT)
    00106     #endif //(NX_HW_SCAN)
    00107     #if (NX_CONNECTION_MONITOR)
    00108             | CO_BIT(MM_FEAT_CMON_BIT)
    00109     #endif //(NX_CONNECTION_MONITOR)
    00110     #if (NX_MULTI_ROLE)
    00111             | CO_BIT(MM_FEAT_MROLE_BIT)
    00112     #endif //(NX_MULTI_ROLE)
    00113     #if (NX_RADAR_DETECT)
    00114             | CO_BIT(MM_FEAT_RADAR_BIT)
    00115     #endif //(NX_RADAR_DETECT)
    00116     #if (NX_POWERSAVE)
    00117             | CO_BIT(MM_FEAT_PS_BIT)
    00118     #endif //(NX_POWERSAVE)
    00119     #if (NX_UAPSD)
    00120             | CO_BIT(MM_FEAT_UAPSD_BIT)
    00121     #endif //(NX_UAPSD)
    00122     #if (NX_DPSM)
    00123             | CO_BIT(MM_FEAT_DPSM_BIT)
    00124     #endif //(NX_DPSM)
    00125     #if (NX_AMPDU_TX)
    00126             | CO_BIT(MM_FEAT_AMPDU_BIT)
    00127     #endif //(NX_AMPDU_TX)
    00128     #if (NX_AMSDU_TX)
    00129             | CO_BIT(MM_FEAT_AMSDU_BIT)
    00130     #endif //(NX_AMSDU_TX)
    00131     #if (NX_CHNL_CTXT)
    00132             | CO_BIT(MM_FEAT_CHNL_CTXT_BIT)
    00133     #endif //(NX_CHNL_CTXT)
    00134     #if (NX_P2P)
    00135             | CO_BIT(MM_FEAT_P2P_BIT)
    00136     #endif //(NX_P2P)
    00137     #if (NX_P2P_GO)
    00138             | CO_BIT(MM_FEAT_P2P_GO_BIT)
    00139     #endif //(NX_P2P_GO)
    00140     #if (NX_UMAC_PRESENT)
    00141             | CO_BIT(MM_FEAT_UMAC_BIT)
    00142     #endif //(NX_UMAC_PRESENT)
    00143     #if (NX_REORD)
    00144             | CO_BIT(MM_FEAT_REORD_BIT)
    00145     #endif //(NX_REORD)
    00146     #if (NX_MFP)
    00147             | CO_BIT(MM_FEAT_MFP_BIT)
    00148     #endif //(NX_MFP)
    00149     #if (RW_MESH_EN)
    00150             | CO_BIT(MM_FEAT_MESH_BIT)
    00151     #endif //(RW_MESH_EN)
    00152     #if (NX_TDLS)
    00153             | CO_BIT(MM_FEAT_TDLS_BIT)
    00154     #endif //(NX_TDLS)
    00155     #if (NX_ANT_DIV)
    00156             | CO_BIT(MM_FEAT_ANT_DIV_BIT)
    00157     #endif //(NX_ANT_DIV)
    00158         );
    00159
    00160     #if (RW_BFMEE_EN)
    00161     if (hal_machw_bfmee_support())
    00162         msg->features |= CO_BIT(MM_FEAT_BFMEE_BIT);
    00163     #endif //(RW_BFMEE_EN)
    00164
    00165     #if (RW_BFMER_EN)
    00166     msg->features |= CO_BIT(MM_FEAT_BFMER_BIT);
    00167     #endif //(RW_BFMER_EN)
    00168
    00169     #if (RW_MUMIMO_RX_EN)
    00170     if (hal_machw_mu_mimo_rx_support())
    00171         msg->features |= CO_BIT(MM_FEAT_MU_MIMO_RX_BIT);
    00172     #endif //(RW_MUMIMO_RX_EN)
    00173
    00174     #if (RW_MUMIMO_TX_EN)
    00175     msg->features |= CO_BIT(MM_FEAT_MU_MIMO_TX_BIT);
    00176     #endif //(RW_MUMIMO_TX_EN)
    00177
    00178     #if (RW_WAPI_EN)
    00179     if (nxmac_wapi_getf())
    00180         msg->features |= CO_BIT(MM_FEAT_WAPI_BIT);
    00181     #endif //(RW_WAPI_EN)
    00182
    00183     #if (!NX_UMAC_PRESENT) || (NX_VHT)
    00184     if (phy_vht_supported())
    00185         msg->features |= CO_BIT(MM_FEAT_VHT_BIT);
    00186     #endif
    00187
    00188     #if (!NX_UMAC_PRESENT) || (NX_HE)
    00189     if (hal_machw_he_support())
    00190         msg->features |= CO_BIT(MM_FEAT_HE_BIT);
    00191     #endif
    00192
    00193     #if (NX_UF_EN)
    00194     if (phy_uf_supported())
    00195         msg->features |=  CO_BIT(MM_FEAT_UF_BIT);
    00196     #endif
    00197
    00198     #if (NX_MON_DATA)
    00199     msg->features |=  CO_BIT(MM_FEAT_MON_DATA_BIT);
    00200     #endif
    00201
    00202     #if (RWNX_MAX_AMSDU_RX > 8192)
    00203     msg->features |=  2 << MM_AMSDU_MAX_SIZE_BIT0;
    00204     #elif (RWNX_MAX_AMSDU_RX > 4096)
    00205     msg->features |=  1 << MM_AMSDU_MAX_SIZE_BIT0;
    00206     #endif
    00207
    00208     // Send the response
    00209     ke_msg_send(msg);
    00210
    00211     //  Return the KE_MSG_CONSUMED status.
    00212     return (KE_MSG_CONSUMED);
    00213 }
    00214
    00234 static int
    00235 mm_reset_req_handler(ke_msg_id_t const msgid,
    00236                      void const *param,
    00237                      ke_task_id_t const dest_id,
    00238                      ke_task_id_t const src_id)
    00239 {
    00240     // For safety do all the reset procedure with interrupts disabled
    00241     GLOBAL_INT_DISABLE();
    00242
    00243     // Stop the MAC HW operation
    00244     hal_machw_stop();
    00245
    00246     // Stop the PHY operation
    00247     phy_stop();
    00248
    00249     // Reset the KE timer module
    00250     ke_timer_reset();
    00251
    00252     #if (NX_UMAC_PRESENT)
    00253     // Re-initialize the UMAC
    00254     me_init();
    00255     #endif //(NX_UMAC_PRESENT)
    00256
    00257     // Re-Initialize the SW
    00258     mm_init();
    00259
    00260     #if NX_SYS_STAT
    00261     // Reset the system statistic logging
    00262     dbg_sys_stat_reset();
    00263     #endif
    00264
    00265     // Reenable interrupts
    00266     GLOBAL_INT_RESTORE();
    00267
    00268     // Send the confirmation
    00269     ke_msg_send_basic(MM_RESET_CFM, src_id, dest_id);
    00270
    00271     // Go to the IDLE state
    00272     ke_state_set(TASK_MM, MM_IDLE);
    00273
    00274     //  Return the KE_MSG_CONSUMED status.
    00275     return (KE_MSG_CONSUMED);
    00276 }
    00277
    00294 static int
    00295 mm_start_req_handler(ke_msg_id_t const msgid,
    00296                      struct mm_start_req const *param,
    00297                      ke_task_id_t const dest_id,
    00298                      ke_task_id_t const src_id)
    00299 {
    00300     struct mac_chan_op chan;
    00301     // Sanity check: This message can be handled in IDLE state only
    00302     ASSERT_ERR(ke_state_get(dest_id) == MM_IDLE);
    00303
    00304     // Initialize the PHY
    00305     phy_init(&param->phy_cfg);
    00306
    00307     // Start the PHY on the default channel
    00308     chan.band = PHY_BAND_2G4;
    00309     chan.type = PHY_CHNL_BW_20;
    00310     chan.prim20_freq = 2484;
    00311     chan.center1_freq = 2484;
    00312     chan.center2_freq = 0;
    00313     chan.flags = 0;
    00314     phy_set_channel(&chan, PHY_PRIM);
    00315     tpc_update_tx_power(MM_DEFAULT_TX_POWER);
    00316
    00317     #if NX_UAPSD
    00318     // Set the U-APSD timeout
    00319     ps_env.uapsd_timeout = param->uapsd_timeout * MILLI2MICRO;
    00320     #endif
    00321
    00322     #if NX_POWERSAVE
    00324     mm_env.lp_clk_accuracy = param->lp_clk_accuracy;
    00325     #endif
    00326
    00327     // Send the confirmation
    00328     ke_msg_send_basic(MM_START_CFM, src_id, dest_id);
    00329
    00330     mm_active();
    00331     #if (NX_UMAC_PRESENT)
    00332     // Request to MAC HW to switch to IDLE state
    00333     hal_machw_idle_req();
    00334
    00335     // Adjust the MM state accordingly
    00336     ke_state_set(dest_id, MM_GOING_TO_IDLE);
    00337     #endif
    00338
    00339     //  Return the KE_MSG_CONSUMED status.
    00340     return (KE_MSG_CONSUMED);
    00341 }
    00342
    00364 #if (!NX_CHNL_CTXT)
    00365 static int
    00366 mm_set_channel_req_handler(ke_msg_id_t const msgid,
    00367                            struct mm_set_channel_req const *param,
    00368                            ke_task_id_t const dest_id,
    00369                            ke_task_id_t const src_id)
    00370 {
    00371      struct mm_set_channel_cfm *cfm;
    00372      struct mac_chan_op const *chan = &param->chan;
    00373
    00374     // Once in IDLE, handle the packets already in the RX queue to ensure that the
    00375     // channel information indicated to the upper MAC is correct. This has to be done with
    00376     // interrupts disabled, as the normal handling of the packets is done under interrupt
    00377     GLOBAL_INT_DISABLE();
    00378     rxl_mpdu_isr();
    00379     rxl_cntrl_evt(0);
    00380     GLOBAL_INT_RESTORE();
    00381
    00382     // Allocate confirmation message
    00383     cfm = KE_MSG_ALLOC(MM_SET_CHANNEL_CFM, src_id, dest_id, mm_set_channel_cfm);
    00384
    00385     // For profiling
    00386     PROF_MM_SET_CHANNEL_SET();
    00387
    00388     // Now we can move the PHY to the requested channel
    00389     phy_set_channel(chan, param->index);
    00390
    00391     if (param->index == PHY_PRIM)
    00392     {
    00393         TRACE_CHAN(INF, "switch to channel freq=%dMHz bw=%dMHz pwr=%ddBm",
    00394                    chan->prim20_freq, (1 <<  chan->type) * 20, chan->tx_power);
    00395         tpc_update_tx_power(chan->tx_power);
    00396         cfm->power = chan->tx_power;
    00397         phy_get_rf_gain_idx(&cfm->power, &cfm->radio_idx);
    00398     }
    00399
    00400     // For profiling
    00401     PROF_MM_SET_CHANNEL_CLR();
    00402
    00403     // Send the confirmation
    00404     ke_msg_send(cfm);
    00405
    00406     //  Return the KE_MSG_CONSUMED status.
    00407     return (KE_MSG_CONSUMED);
    00408 }
    00409
    00410 #else
    00411 static int
    00412 mm_set_channel_req_handler(ke_msg_id_t const msgid,
    00413                            struct mm_set_channel_req const *param,
    00414                            ke_task_id_t const dest_id,
    00415                            ke_task_id_t const src_id)
    00416 {
    00417     struct mm_set_channel_cfm *cfm;
    00418
    00419     // Allocate confirmation message
    00420     cfm = KE_MSG_ALLOC(MM_SET_CHANNEL_CFM, src_id, dest_id, mm_set_channel_cfm);
    00421
    00422     // For profiling
    00423     PROF_MM_SET_CHANNEL_SET();
    00424
    00425     if (param->index != PHY_PRIM)
    00426         phy_set_channel(&param->chan, param->index);
    00427
    00428     // For profiling
    00429     PROF_MM_SET_CHANNEL_CLR();
    00430
    00431      // Send the confirmation
    00432     ke_msg_send(cfm);
    00433
    00434     //  Return the KE_MSG_CONSUMED status.
    00435     return (KE_MSG_CONSUMED);
    00436 }
    00437 #endif //(!NX_CHNL_CTXT)
    00438
    00458 static int
    00459 mm_set_dtim_req_handler(ke_msg_id_t const msgid,
    00460                         struct mm_set_dtim_req const *param,
    00461                         ke_task_id_t const dest_id,
    00462                         ke_task_id_t const src_id)
    00463 {
    00464     // Set the DTIM period in the HW
    00465     nxmac_dtim_period_setf(param->dtim_period);
    00466     nxmac_dtim_updated_by_sw_setf(1);
    00467
    00468     // Send the confirmation
    00469     ke_msg_send_basic(MM_SET_DTIM_CFM, src_id, dest_id);
    00470
    00471     //  Return the KE_MSG_CONSUMED status.
    00472     return (KE_MSG_CONSUMED);
    00473 }
    00474
    00494 static int
    00495 mm_set_beacon_int_req_handler(ke_msg_id_t const msgid,
    00496                               struct mm_set_beacon_int_req const *param,
    00497                               ke_task_id_t const dest_id,
    00498                               ke_task_id_t const src_id)
    00499 {
    00500     struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
    00501
    00502     // Check if VIF is a AP or STA one
    00503     if (vif->type == VIF_STA)
    00504     {
    00505         #if (NX_MULTI_ROLE)
    00506         #if (!NX_UMAC_PRESENT)
    00507         if (vif->u.sta.ap_id == INVALID_STA_IDX)
    00508         {
    00509             vif->u.sta.ap_bcn_intv = param->beacon_int;
    00510         }
    00511         else
    00512         #endif //(!NX_UMAC_PRESENT)
    00513         {
    00514             // Get peer AP information
    00515             struct sta_info_tag *sta = &sta_info_tab[vif->u.sta.ap_id];
    00516
    00517             // For STA, the beacon interval is only used by the FW
    00518             sta->bcn_int = param->beacon_int * TU_DURATION;
    00519         }
    00520         #else //(NX_MULTI_ROLE)
    00521         nxmac_beacon_int_setf(param->beacon_int * TU_DURATION);
    00522         #endif //(NX_MULTI_ROLE)
    00523     }
    00524     else
    00525     {
    00526         // For AP or MP, set the beacon interval in the HW
    00527         vif_mgmt_set_ap_bcn_int(vif, param->beacon_int);
    00528     }
    00529
    00530     // Send the confirmation
    00531     ke_msg_send_basic(MM_SET_BEACON_INT_CFM, src_id, dest_id);
    00532
    00533     //  Return the KE_MSG_CONSUMED status.
    00534     return (KE_MSG_CONSUMED);
    00535 }
    00536
    00556 static int
    00557 mm_set_basic_rates_req_handler(ke_msg_id_t const msgid,
    00558                                struct mm_set_basic_rates_req const *param,
    00559                                ke_task_id_t const dest_id,
    00560                                ke_task_id_t const src_id)
    00561 {
    00562     #if NX_CHNL_CTXT
    00563     struct chan_ctxt_tag *ctxt = chan_env.current_ctxt;
    00564
    00565     // Get the new ones
    00566     mm_env.basic_rates[param->band] = param->rates;
    00567
    00568     // Check if we are currently on the band
    00569     if (ctxt && (ctxt->channel.band == param->band))
    00570         // Set the basic rates in HW
    00571         nxmac_rates_set(mm_env.basic_rates[param->band]);
    00572
    00573     #else
    00574     // Set the basic rates in the HW
    00575     nxmac_rates_set(param->rates);
    00576     #endif
    00577
    00578     // Send the confirmation
    00579     ke_msg_send_basic(MM_SET_BASIC_RATES_CFM, src_id, dest_id);
    00580
    00581     //  Return the KE_MSG_CONSUMED status.
    00582     return (KE_MSG_CONSUMED);
    00583 }
    00584
    00604 static int
    00605 mm_set_filter_req_handler(ke_msg_id_t const msgid,
    00606                           struct mm_set_filter_req const *param,
    00607                           ke_task_id_t const dest_id,
    00608                           ke_task_id_t const src_id)
    00609 {
    00610     // Set the UMAC RX filter
    00611     mm_rx_filter_umac_set(param->filter);
    00612
    00613     // Send the confirmation
    00614     ke_msg_send_basic(MM_SET_FILTER_CFM, src_id, dest_id);
    00615
    00616     //  Return the KE_MSG_CONSUMED status.
    00617     return (KE_MSG_CONSUMED);
    00618 }
    00619
    00639 static int
    00640 mm_set_bssid_req_handler(ke_msg_id_t const msgid,
    00641                          struct mm_set_bssid_req const *param,
    00642                          ke_task_id_t const dest_id,
    00643                          ke_task_id_t const src_id)
    00644 {
    00645     #if (NX_MULTI_ROLE || NX_TDLS)
    00646     struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
    00647
    00648     // Copy the BSSID in the VIF structure
    00649     memcpy(&vif->bssid, &param->bssid, sizeof(param->bssid));
    00650
    00651     #endif /* (NX_MULTI_ROLE || NX_TDLS ) */
    00652
    00653     #if (NX_MULTI_ROLE)
    00654     // Check if there is currently only one VIF created
    00655     if (vif_mgmt_used_cnt() == 1)
    00656     {
    00657         // Only one VIF created, so put the BSSID in the HW
    00658         // write lower 4 bytes of BSSID
    00659         nxmac_bss_id_low_setf(param->bssid.array[0] | (((uint32_t)param->bssid.array[1]) << 16));
    00660
    00661         // write higher 2 bytes of BSSID
    00662         nxmac_bss_id_high_setf(param->bssid.array[2]);
    00663     }
    00664     #else
    00665     // write lower 4 bytes of BSSID
    00666     nxmac_bss_id_low_setf(param->bssid.array[0] | (((uint32_t)param->bssid.array[1]) << 16));
    00667
    00668     // write higher 2 bytes of BSSID
    00669     nxmac_bss_id_high_setf(param->bssid.array[2]);
    00670     #endif /* (NX_MULTI_ROLE) */
    00671
    00672     // Send the confirmation
    00673     ke_msg_send_basic(MM_SET_BSSID_CFM, src_id, dest_id);
    00674
    00675     //  Return the KE_MSG_CONSUMED status.
    00676     return (KE_MSG_CONSUMED);
    00677 }
    00678
    00695 static int
    00696 mm_set_edca_req_handler(ke_msg_id_t const msgid,
    00697                          struct mm_set_edca_req const *param,
    00698                          ke_task_id_t const dest_id,
    00699                          ke_task_id_t const src_id)
    00700 {
    00701     struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
    00702
    00703     // Store the parameters in the VIF
    00704     vif->txq_params[param->hw_queue] = param->ac_param;
    00705
    00706     // If VIF is active, change the parameters immediately
    00707     if (vif->active)
    00708     {
    00709         // Put the EDCA parameters in the correct register according to the queue index
    00710         switch (param->hw_queue)
    00711         {
    00712             case AC_BK:
    00713                 nxmac_edca_ac_0_set(param->ac_param);
    00714                 break;
    00715             case AC_BE:
    00716                 nxmac_edca_ac_1_set(param->ac_param);
    00717                 break;
    00718             case AC_VI:
    00719                 nxmac_edca_ac_2_set(param->ac_param);
    00720                 break;
    00721             default:
    00722                 nxmac_edca_ac_3_set(param->ac_param);
    00723                 break;
    00724         }
    00725
    00726         // Store A-MPDU maximum duration parameters in environment for faster access by TX path
    00727         mm_env_max_ampdu_duration_set();
    00728     }
    00729
    00730     #if NX_UAPSD
    00731     // Store the information on UAPSD for the queue and interface index
    00732     if (vif->type == VIF_STA)
    00733     {
    00734         ps_uapsd_set(vif, param->hw_queue, param->uapsd);
    00735     }
    00736     #endif
    00737
    00738     // Send the confirmation
    00739     ke_msg_send_basic(MM_SET_EDCA_CFM, src_id, dest_id);
    00740
    00741     //  Return the KE_MSG_CONSUMED status.
    00742     return (KE_MSG_CONSUMED);
    00743 }
    00744
    00761 static int
    00762 mm_set_mu_edca_req_handler(ke_msg_id_t const msgid,
    00763                            struct mm_set_mu_edca_req const *param,
    00764                            ke_task_id_t const dest_id,
    00765                            ke_task_id_t const src_id)
    00766 {
    00767     #if NX_MAC_HE
    00768     // Call the TX HE module
    00769     txl_he_mu_edca_param_set(param);
    00770     #endif
    00771
    00772     // Send the confirmation
    00773     ke_msg_send_basic(MM_SET_MU_EDCA_CFM, src_id, dest_id);
    00774
    00775     //  Return the KE_MSG_CONSUMED status.
    00776     return (KE_MSG_CONSUMED);
    00777 }
    00778
    00795 static int
    00796 mm_set_uora_req_handler(ke_msg_id_t const msgid,
    00797                         struct mm_set_uora_req const *param,
    00798                         ke_task_id_t const dest_id,
    00799                         ke_task_id_t const src_id)
    00800 {
    00801     #if NX_MAC_HE
    00802     // Call the TX HE module
    00803     txl_he_uora_param_set(param);
    00804     #endif
    00805
    00806     // Send the confirmation
    00807     ke_msg_send_basic(MM_SET_UORA_CFM, src_id, dest_id);
    00808
    00809     //  Return the KE_MSG_CONSUMED status.
    00810     return (KE_MSG_CONSUMED);
    00811 }
    00828 static int
    00829 mm_set_bss_color_req_handler(ke_msg_id_t const msgid,
    00830                              struct mm_set_bss_color_req const *param,
    00831                              ke_task_id_t const dest_id,
    00832                              ke_task_id_t const src_id)
    00833 {
    00834     #if NX_MAC_HE
    00835     // Set the BSS color register
    00836     nxmac_bss_color_set(param->bss_color);
    00837     #endif
    00838
    00839     // Send the confirmation
    00840     ke_msg_send_basic(MM_SET_BSS_COLOR_CFM, src_id, dest_id);
    00841
    00842     //  Return the KE_MSG_CONSUMED status.
    00843     return (KE_MSG_CONSUMED);
    00844 }
    00845
    00862 static int
    00863 mm_set_txop_rts_thres_req_handler(ke_msg_id_t const msgid,
    00864                                   struct mm_set_txop_rts_thres_req const *param,
    00865                                   ke_task_id_t const dest_id,
    00866                                   ke_task_id_t const src_id)
    00867 {
    00868     #if NX_MAC_HE
    00869     struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
    00870
    00871     vif->txop_dur_rts_thres = param->txop_dur_rts_thres;
    00872     #endif
    00873
    00874     // Send the confirmation
    00875     ke_msg_send_basic(MM_SET_TXOP_RTS_THRES_CFM, src_id, dest_id);
    00876
    00877     //  Return the KE_MSG_CONSUMED status.
    00878     return (KE_MSG_CONSUMED);
    00879 }
    00880
    00900 static int
    00901 mm_set_slottime_req_handler(ke_msg_id_t const msgid,
    00902                             struct mm_set_slottime_req const *param,
    00903                             ke_task_id_t const dest_id,
    00904                             ke_task_id_t const src_id)
    00905 {
    00906     uint16_t mac_core_clk;
    00907
    00908     // Get MAC core clock value
    00909     mac_core_clk = nxmac_mac_core_clk_freq_getf();
    00910
    00911     // Set slot time
    00912     nxmac_timings_2_pack(mac_core_clk * param->slottime, param->slottime);
    00913
    00914     // Send the confirmation
    00915     ke_msg_send_basic(MM_SET_SLOTTIME_CFM, src_id, dest_id);
    00916
    00917     //  Return the KE_MSG_CONSUMED status.
    00918     return (KE_MSG_CONSUMED);
    00919 }
    00920
    00940 static int
    00941 mm_set_mode_req_handler(ke_msg_id_t const msgid,
    00942                         struct mm_set_mode_req const *param,
    00943                         ke_task_id_t const dest_id,
    00944                         ke_task_id_t const src_id)
    00945 {
    00946     // Set slot time
    00947     nxmac_abgn_mode_setf(param->abgnmode);
    00948
    00949     // Send the confirmation
    00950     ke_msg_send_basic(MM_SET_MODE_CFM, src_id, dest_id);
    00951
    00952     //  Return the KE_MSG_CONSUMED status.
    00953     return (KE_MSG_CONSUMED);
    00954 }
    00955
    00976 static int
    00977 mm_set_vif_state_req_handler(ke_msg_id_t const msgid,
    00978                              struct mm_set_vif_state_req const *param,
    00979                              ke_task_id_t const dest_id,
    00980                              ke_task_id_t const src_id)
    00981 {
    00982     struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
    00983
    00984     // Save the state of the VIF
    00985     vif->active = param->active;
    00986
    00987     // Check if the VIF is of STA type
    00988     if (vif->type == VIF_STA)
    00989     {
    00990         if (param->active)
    00991         {
    00992             // Get peer AP information
    00993             struct sta_info_tag *sta = &sta_info_tab[vif->u.sta.ap_id];
    00994             #if NX_POWERSAVE
    00995             uint32_t drift;
    00996             #endif
    00997             #if NX_MULTI_ROLE
    00998             // Compute default value of next TBTT based on current local time
    00999             uint32_t next_tbtt = ke_time() + sta->bcn_int;
    01000
    01001             // Program the next TBTT
    01002             mm_timer_set(&vif->tbtt_timer, next_tbtt);
    01003             #endif
    01004
    01005             // We save the AP index for later use
    01006             sta->aid = param->aid;
    01007
    01008             // Set the BSSID mask according to the registered VIFs
    01009             vif_mgmt_set_bssid_mask();
    01010
    01011             #if (RW_BFMEE_EN)
    01012             /*
    01013              * If we are STA and MU Beamformee Capable we have to keep the AID in a register so that when we receive
    01014              * a NDPA with several STA Info HW can detect the STA Info that is dedicated to us
    01015              * Note: We currently support to be only one time MU Beamformee as STA.
    01016              */
    01017             nxmac_aid_setf(param->aid);
    01018             #endif //(RW_BFMEE_EN)
    01019
    01020             #if NX_MAC_HE
    01021             if (hal_machw_he_support())
    01022             {
    01023                 phy_set_aid(param->aid);
    01024
    01025                 // Enable the HE TB operation
    01026                 txl_he_tb_enable();
    01027             }
    01028             #endif
    01029
    01030             #if NX_POWERSAVE
    01031             vif->u.sta.listen_interval = 0;
    01032             vif->u.sta.dont_wait_bcmc = false;
    01033             // Compute the maximum drift we could suffer due to the LP clock inaccuracy
    01034             drift = ((uint32_t)(mm_env.lp_clk_accuracy + MM_AP_CLK_ACCURACY) *
    01035                      (uint32_t)sta->bcn_int) / 1000000;
    01036             sta->drift = (uint16_t)drift;
    01037             #if NX_UAPSD
    01038             vif->u.sta.uapsd_last_rxtx = ke_time();
    01039             #endif
    01040             vif->prevent_sleep |= PS_VIF_WAITING_BCN;
    01041             #endif
    01042
    01043             #if NX_CONNECTION_MONITOR
    01044             // Reset the beacon loss count and keep-alive frame time
    01045             vif->u.sta.beacon_loss_cnt = 0;
    01046             vif->u.sta.mon_last_crc = 0;
    01047             vif->u.sta.mon_last_tx = ke_time();
    01048             #endif
    01049
    01050             #if (NX_CHNL_CTXT)
    01051             // Try to spend more time on channel in order to catch a beacon
    01052             chan_bcn_detect_start(vif);
    01053             #endif //(NX_CHNL_CTXT)
    01054         }
    01055         else
    01056         {
    01057             #if NX_MULTI_ROLE
    01058             // Clear the TBTT timer
    01059             mm_timer_clear(&vif->tbtt_timer);
    01060             #endif
    01061             #if NX_MAC_HE
    01062             // Enable the HE TB operation
    01063             txl_he_tb_disable();
    01064             #endif
    01065         }
    01066     }
    01067
    01068     #if (NX_P2P)
    01069     p2p_set_vif_state(vif, param->active);
    01070     #endif //(NX_P2P)
    01071
    01072     #if (NX_ANT_DIV)
    01073     mm_ant_div_restore(vif->active);
    01074     #endif //(NX_ANT_DIV)
    01075
    01076     // Put the EDCA parameters in the registers
    01077     if (param->active)
    01078     {
    01079         nxmac_edca_ac_0_set(vif->txq_params[AC_BK]);
    01080         nxmac_edca_ac_1_set(vif->txq_params[AC_BE]);
    01081         nxmac_edca_ac_2_set(vif->txq_params[AC_VI]);
    01082         nxmac_edca_ac_3_set(vif->txq_params[AC_VO]);
    01083
    01084         // Store A-MPDU maximum duration parameters in environment for faster access by TX path
    01085         mm_env_max_ampdu_duration_set();
    01086     }
    01087
    01088     // Send the confirmation
    01089     ke_msg_send_basic(MM_SET_VIF_STATE_CFM, src_id, dest_id);
    01090
    01091     //  Return the KE_MSG_CONSUMED status.
    01092     return (KE_MSG_CONSUMED);
    01093 }
    01094
    01112 static int
    01113 mm_set_power_req_handler(ke_msg_id_t const msgid,
    01114                          struct mm_set_power_req const *param,
    01115                          ke_task_id_t const dest_id,
    01116                          ke_task_id_t const src_id)
    01117 {
    01118     struct mm_set_power_cfm *cfm;
    01119     struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
    01120
    01121     // Allocate confirmation message
    01122     cfm = KE_MSG_ALLOC(MM_SET_POWER_CFM, src_id, dest_id, mm_set_power_cfm);
    01123
    01124     #if NX_UMAC_PRESENT
    01125     vif->user_tx_power = param->power;
    01126     tpc_update_vif_tx_power(vif);
    01127     #else
    01128     tpc_set_vif_tx_power(vif, param->power);
    01129     TRACE_LMAC(TPC, "{VIF-%d} host request TX power %ddBm set to %ddBm",
    01130                vif->index, param->power, vif->tx_power);
    01131     #endif /* NX_UMAC_PRESENT */
    01132     tpc_get_vif_tx_power(vif, &cfm->power, &cfm->radio_idx);
    01133
    01134     // Send the confirmation
    01135     ke_msg_send(cfm);
    01136
    01137     //  Return the KE_MSG_CONSUMED status.
    01138     return (KE_MSG_CONSUMED);
    01139 }
    01140
    01158 static int
    01159 mm_dbg_trigger_req_handler(ke_msg_id_t const msgid,
    01160                            struct mm_dbg_trigger_req const *param,
    01161                            ke_task_id_t const dest_id,
    01162                            ke_task_id_t const src_id)
    01163 {
    01164     // Call the platform function to force the trigger
    01165     dbg_force_trigger(param->error);
    01166
    01167     //  Return the KE_MSG_CONSUMED status.
    01168     return (KE_MSG_CONSUMED);
    01169 }
    01170
    01190 static int
    01191 mm_add_if_req_handler(ke_msg_id_t const msgid,
    01192                       struct mm_add_if_req const *param,
    01193                       ke_task_id_t const dest_id,
    01194                       ke_task_id_t const src_id)
    01195 {
    01196     struct mm_add_if_cfm *cfm;
    01197
    01198     // Allocate confirmation message
    01199     cfm = KE_MSG_ALLOC(MM_ADD_IF_CFM, src_id, dest_id, mm_add_if_cfm);
    01200
    01201     // Register the VIF
    01202     cfm->status = vif_mgmt_register(&param->addr, param->type, param->p2p, &cfm->inst_nbr);
    01203
    01204     // Send the confirmation
    01205     ke_msg_send(cfm);
    01206
    01207     //  Return the KE_MSG_CONSUMED status.
    01208     return (KE_MSG_CONSUMED);
    01209 }
    01210
    01230 static int
    01231 mm_remove_if_req_handler(ke_msg_id_t const msgid,
    01232                          struct mm_remove_if_req const *param,
    01233                          ke_task_id_t const dest_id,
    01234                          ke_task_id_t const src_id)
    01235 {
    01236     // Check if VIF index is valid
    01237     if (param->inst_nbr < NX_VIRT_DEV_MAX)
    01238         // Unregister the VIF
    01239         vif_mgmt_unregister(param->inst_nbr);
    01240
    01241     // Check if we have removed the last VIF
    01242     if (co_list_is_empty(&vif_mgmt_env.used_list))
    01243         // No more active VIFs, go back to monitor mode
    01244         hal_machw_monitor_mode();
    01245
    01246     // Send the confirmation
    01247     ke_msg_send_basic(MM_REMOVE_IF_CFM, src_id, dest_id);
    01248
    01249     //  Return the KE_MSG_CONSUMED status.
    01250     return (KE_MSG_CONSUMED);
    01251 }
    01252
    01269 static int
    01270 mm_set_idle_req_handler(ke_msg_id_t const msgid,
    01271                         struct mm_set_idle_req const *param,
    01272                         ke_task_id_t const dest_id,
    01273                         ke_task_id_t const src_id)
    01274 {
    01275     if ((ke_state_get(dest_id) == MM_HOST_BYPASSED) ||
    01276         (ke_state_get(dest_id) == MM_NO_IDLE))
    01277     {
    01278         // UMAC requests for IDLE or active are currently bypassed.
    01279         return (KE_MSG_SAVED);
    01280     }
    01281
    01282     // Save the state that is requested by the host
    01283     mm_env.host_idle = param->hw_idle;
    01284
    01285     // Check if HW has to be put in IDLE or ACTIVE state
    01286     if (param->hw_idle)
    01287     {
    01288         // Check if we are in IDLE state
    01289         switch (ke_state_get(dest_id))
    01290         {
    01291             case MM_IDLE:
    01292                 // Sanity check: As MM state is IDLE, HW state is also supposed to be IDLE
    01293                 ASSERT_ERR(nxmac_current_state_getf() == HW_IDLE);
    01294
    01295                 mm_env.prev_mm_state = MM_IDLE;
    01296                 mm_env.prev_hw_state = HW_IDLE;
    01297                 break;
    01298
    01299             case MM_GOING_TO_IDLE:
    01300                 // MAC is currently going to IDLE, so simply save the message. It will be
    01301                 // rescheduled once the MAC has switched to IDLE.
    01302                 return (KE_MSG_SAVED);
    01303
    01304             default:
    01305                 // Request to MAC HW to switch to IDLE state
    01306                 hal_machw_idle_req();
    01307
    01308                 // Adjust the MM state accordingly
    01309                 ke_state_set(dest_id, MM_GOING_TO_IDLE);
    01310
    01311                 // Save the message
    01312                 return (KE_MSG_SAVED);
    01313         }
    01314     }
    01315     else
    01316     {
    01317         if (ke_state_get(dest_id) == MM_GOING_TO_IDLE)
    01318         {
    01319             // We are currently going to IDLE, wait for this to be complete before
    01320             // accepting a new request from host
    01321             return (KE_MSG_SAVED);
    01322         }
    01323
    01324         mm_active();
    01325     }
    01326
    01327     // Send the confirmation
    01328     ke_msg_send_basic(MM_SET_IDLE_CFM, src_id, dest_id);
    01329
    01330     // Return the KE_MSG_CONSUMED status.
    01331     return (KE_MSG_CONSUMED);
    01332 }
    01333
    01349 static int
    01350 mm_force_idle_req_handler(ke_msg_id_t const msgid,
    01351                           struct mm_force_idle_req const *param,
    01352                           ke_task_id_t const dest_id,
    01353                           ke_task_id_t const src_id)
    01354 {
    01355     // Sanity check - The force IDLE procedure shall not be performed while the NO IDLE
    01356     // state is present for a beacon transmission. If this assertion is triggered it
    01357     // probably means that the scheduling of a channel switch is done at a bad time.
    01358     ASSERT_ERR(ke_state_get(dest_id) != MM_NO_IDLE);
    01359
    01360     // Check if we are in IDLE state
    01361     switch (ke_state_get(dest_id))
    01362     {
    01363         case MM_IDLE:
    01364             // Sanity check: As MM state is IDLE, HW state is also supposed to be IDLE
    01365             ASSERT_ERR(nxmac_current_state_getf() == HW_IDLE);
    01366             break;
    01367
    01368         case MM_GOING_TO_IDLE:
    01369             // MAC is currently going to IDLE, so simply save the message. It will be
    01370             // rescheduled once the MAC has switched to IDLE.
    01371             return (KE_MSG_SAVED);
    01372
    01373         default:
    01374             // Request to MAC HW to switch to IDLE state
    01375             hal_machw_idle_req();
    01376
    01377             // Adjust the MM state accordingly
    01378             ke_state_set(dest_id, MM_GOING_TO_IDLE);
    01379
    01380             // Save the message
    01381             return (KE_MSG_SAVED);
    01382     }
    01383
    01384     // IDLE requests from host are now bypassed
    01385     ke_state_set(dest_id, MM_HOST_BYPASSED);
    01386
    01387     // Call the callback function
    01388     param->cb();
    01389
    01390     // Return the KE_MSG_CONSUMED status.
    01391     return (KE_MSG_CONSUMED);
    01392 }
    01393
    01410 static int
    01411 mm_sta_add_req_handler(ke_msg_id_t const msgid,
    01412                        struct mm_sta_add_req const *param,
    01413                        ke_task_id_t const dest_id,
    01414                        ke_task_id_t const src_id)
    01415 {
    01416     // Allocate the response structure
    01417     struct mm_sta_add_cfm *rsp = KE_MSG_ALLOC(MM_STA_ADD_CFM, src_id, dest_id, mm_sta_add_cfm);
    01418
    01419     // Register the new station
    01420     rsp->status = mm_sta_add(param, &rsp->sta_idx, &rsp->hw_sta_idx);
    01421
    01422     // Send the confirmation
    01423     ke_msg_send(rsp);
    01424
    01425     return (KE_MSG_CONSUMED);
    01426 }
    01427
    01428
    01445 static int
    01446 mm_sta_del_req_handler(ke_msg_id_t const msgid,
    01447                        struct mm_sta_del_req const *param,
    01448                        ke_task_id_t const dest_id,
    01449                        ke_task_id_t const src_id)
    01450 {
    01451     // Delete the station
    01452     mm_sta_del(param->sta_idx);
    01453
    01454     // Send the confirmation to the upper MAC
    01455     ke_msg_send_basic(MM_STA_DEL_CFM, src_id, dest_id);
    01456
    01457     return (KE_MSG_CONSUMED);
    01458 }
    01459
    01476 static int
    01477 mm_key_add_req_handler(ke_msg_id_t const msgid,
    01478                        struct mm_key_add_req const *param,
    01479                        ke_task_id_t const dest_id,
    01480                        ke_task_id_t const src_id)
    01481 {
    01482     uint8_t hw_key_idx;
    01483     struct mm_key_add_cfm *keyadd_cfm_param =
    01484         KE_MSG_ALLOC(MM_KEY_ADD_CFM, src_id, dest_id, mm_key_add_cfm);
    01485
    01486     // Assert on invalid Key Index.
    01487     #if NX_MFP
    01488     ASSERT_ERR(param->key_idx < MAC_DEFAULT_MFP_KEY_COUNT);
    01489     #else
    01490     ASSERT_ERR(param->key_idx < MAC_DEFAULT_KEY_COUNT);
    01491     #endif
    01492
    01493     // Assert on invalid Key Length.
    01494     ASSERT_ERR(param->key.length <= MAC_SEC_KEY_LEN);
    01495
    01496     // Assert on invalid Key Length.
    01497     ASSERT_ERR(param->cipher_suite <= MAC_CIPHER_BIP_CMAC_128);
    01498
    01499     // Copy the key in the HW
    01500     hw_key_idx = mm_sec_machwkey_wr(param);
    01501
    01502     // KEY_ADD_CFM return Parameter.
    01503     keyadd_cfm_param->hw_key_idx = hw_key_idx;
    01504     keyadd_cfm_param->status = CO_OK;
    01505
    01506     // Post the MM_KEY_ADD_CFM message in QUEUE
    01507     ke_msg_send(keyadd_cfm_param);
    01508
    01509     // Return the KE_MSG_CONSUMED status.
    01510     return (KE_MSG_CONSUMED);
    01511 }
    01512
    01529 static int
    01530 mm_key_del_req_handler(ke_msg_id_t const msgid,
    01531                        struct mm_key_del_req const *param,
    01532                        ke_task_id_t const dest_id,
    01533                        ke_task_id_t const src_id)
    01534 {
    01535     // Assert on invalid Key Index.
    01536     #if NX_MFP
    01537     ASSERT_ERR(param->hw_key_idx <= MM_SEC_MAX_MFP_KEY_NBR);
    01538     #else
    01539     ASSERT_ERR(param->hw_key_idx <= MM_SEC_MAX_KEY_NBR);
    01540     #endif
    01541
    01542     // Disable the key in the HW
    01543     mm_sec_machwkey_del(param->hw_key_idx);
    01544
    01545     // Post the MM_KEY_DEL_CFM message in QUEUE
    01546     ke_msg_send_basic(MM_KEY_DEL_CFM, src_id, dest_id);
    01547
    01548     // Return the KE_MSG_CONSUMED status.
    01549     return (KE_MSG_CONSUMED);
    01550 }
    01551
    01569 static int
    01570 mm_ba_add_req_handler(ke_msg_id_t const msgid,
    01571                       struct mm_ba_add_req const *param,
    01572                       ke_task_id_t const dest_id,
    01573                       ke_task_id_t const src_id)
    01574 {
    01575     uint8_t status = BA_AGMT_ESTABLISHED;
    01576
    01577     do
    01578     {
    01579         // Check BA type
    01580         if (param->type == BA_AGMT_TX)
    01581         {
    01582             #if (NX_AMPDU_TX)
    01583             // Buffer Size
    01584             uint8_t bufsz;
    01585
    01586             #if (!NX_UMAC_PRESENT)
    01587             // Check if a BA agreement already exists
    01588             if (mm_ba_agmt_tx_exists(param->sta_idx, param->tid))
    01589             {
    01590                 status = BA_AGMT_ALREADY_EXISTS;
    01591                 break;
    01592             }
    01593             #endif //(!NX_UMAC_PRESENT)
    01594
    01595             // Limit the maximum number of MPDUs in the A-MPDU to the minimum of
    01596             // the half of the BA window and the half of the number of TX descriptors
    01597             // per queue
    01598             if (param->bufsz < nx_txdesc_cnt[mac_tid2ac[param->tid]])
    01599             {
    01600                 bufsz = param->bufsz / 2;
    01601             }
    01602             else
    01603             {
    01604                 bufsz = nx_txdesc_cnt[mac_tid2ac[param->tid]] / 2;
    01605             }
    01606
    01607             sta_mgmt_set_tx_buff_size(param->sta_idx, param->tid, bufsz);
    01608             sta_mgmt_set_tx_ssn(param->sta_idx, param->tid, param->ssn);
    01609             #else
    01610             status = BA_AGMT_NOT_SUPPORTED;
    01611             #endif //(NX_AMPDU_TX)
    01612         }
    01613         else
    01614         {
    01615             #if (NX_REORD)
    01616             // Create the reordering instance
    01617             if (!rxu_cntrl_reord_create(&sta_info_tab[param->sta_idx], param->tid,
    01618                                         param->ssn))
    01619             {
    01620                 status = BA_AGMT_NO_MORE_BA_AGMT;
    01621                 break;
    01622             }
    01623             #endif //(NX_REORD)
    01624
    01625             // Reset the MAC HW BlockAck bitmaps
    01626             // Currently it is not possible to reset per STA/TID, so reset all of them
    01627             nxmac_ba_ps_bitmap_reset_setf(1);
    01628         }
    01629     } while (0);
    01630
    01631     // Allocate kernel message space for the confirmation to send
    01632     struct mm_ba_add_cfm *cfm = KE_MSG_ALLOC(MM_BA_ADD_CFM, src_id, dest_id, mm_ba_add_cfm);
    01633
    01634     cfm->sta_idx = param->sta_idx;
    01635     cfm->tid     = param->tid;
    01636     cfm->status  = status;
    01637
    01638     // Post the MM_BA_ADD_CFM message in QUEUE
    01639     ke_msg_send(cfm);
    01640
    01641     // Return the KE_MSG_CONSUMED status.
    01642     return (KE_MSG_CONSUMED);
    01643 }
    01644
    01645
    01646 #if (NX_AMPDU_TX || NX_REORD)
    01647
    01663 static int
    01664 mm_ba_del_req_handler(ke_msg_id_t const msgid,
    01665                      struct mm_ba_del_req const *param,
    01666                      ke_task_id_t const dest_id,
    01667                      ke_task_id_t const src_id)
    01668 {
    01669     uint8_t status = BA_AGMT_DELETED;
    01670
    01671     do
    01672     {
    01673         // Check BA type
    01674         if (param->type == BA_AGMT_TX)
    01675         {
    01676             #if (NX_AMPDU_TX)
    01677             // Check if the specified BA agreement already exists
    01678             if (!mm_ba_agmt_tx_exists(param->sta_idx, param->tid))
    01679             {
    01680                 status = BA_AGMT_DOESNT_EXIST;
    01681                 break;
    01682             }
    01683
    01684             // Unregister BA agreement information from (STA, TID) -> invalidate bufsz
    01685             sta_mgmt_set_tx_buff_size(param->sta_idx, param->tid, 0);
    01686             sta_mgmt_set_tx_ssn(param->sta_idx, param->tid, 0);
    01687             #else
    01688             status = BA_AGMT_NOT_SUPPORTED;
    01689             #endif //(NX_AMPDU_TX)
    01690         }
    01691         else
    01692         {
    01693             #if (NX_REORD)
    01694             // Check if the specified BA agreement already exists
    01695             if (!mm_ba_agmt_rx_exists(param->sta_idx, param->tid))
    01696             {
    01697                 status = BA_AGMT_DOESNT_EXIST;
    01698                 break;
    01699             }
    01700
    01701             // Delete the reordering instance
    01702             rxu_cntrl_reord_delete(&sta_info_tab[param->sta_idx], param->tid);
    01703
    01704             #else
    01705             status = BA_AGMT_NOT_SUPPORTED;
    01706             #endif //(NX_REORD)
    01707         }
    01708     } while (0);
    01709
    01710     // Allocate kernel message space for the confirmation to send
    01711     struct mm_ba_del_cfm *cfm = KE_MSG_ALLOC(MM_BA_DEL_CFM, src_id, dest_id, mm_ba_del_cfm);
    01712
    01713     cfm->sta_idx = param->sta_idx;
    01714     cfm->tid     = param->tid;
    01715     cfm->status  = status;
    01716
    01717     // Post the MM_BA_DEL_CFM message in QUEUE
    01718     ke_msg_send(cfm);
    01719
    01720     // Return the KE_MSG_CONSUMED status.
    01721     return (KE_MSG_CONSUMED);
    01722 }
    01723 #endif //(NX_AMPDU_TX || NX_REORD)
    01724
    01725 #if NX_BEACONING
    01726
    01742 static int
    01743 mm_tbtt_move_req_handler(ke_msg_id_t const msgid,
    01744                          struct mm_tbtt_move_req const *param,
    01745                          ke_task_id_t const dest_id,
    01746                          ke_task_id_t const src_id)
    01747 {
    01748     // No more TBTT move ongoing after that
    01749     mm_env.tbtt_move_ongoing = false;
    01750
    01751     // Update the TSF
    01752     if (hal_machw_tsf_move(param->offset))
    01753     {
    01754         // Not a good time for the move, reprogram it
    01755         mm_ap_tbtt_move(param->offset);
    01756     }
    01757
    01758     //  Return the KE_MSG_CONSUMED status.
    01759     return (KE_MSG_CONSUMED);
    01760 }
    01761 #endif // NX_BEACONING
    01762
    01763 #if (NX_CHNL_CTXT)
    01764 #if (!NX_UMAC_PRESENT)
    01765
    01781 static int
    01782 mm_chan_ctxt_add_req_handler(ke_msg_id_t const msgid,
    01783                              struct mm_chan_ctxt_add_req const *param,
    01784                              ke_task_id_t const dest_id,
    01785                              ke_task_id_t const src_id)
    01786 {
    01787     // Allocate confirmation message
    01788     struct mm_chan_ctxt_add_cfm *cfm = KE_MSG_ALLOC(MM_CHAN_CTXT_ADD_CFM, src_id, dest_id, mm_chan_ctxt_add_cfm);
    01789
    01790     // Register the VIF
    01791     cfm->status = chan_ctxt_add(&(param->chan), &cfm->index);
    01792
    01793     // Send the confirmation
    01794     ke_msg_send(cfm);
    01795
    01796     //  Return the KE_MSG_CONSUMED status.
    01797     return (KE_MSG_CONSUMED);
    01798 }
    01799
    01816 static int
    01817 mm_chan_ctxt_del_req_handler(ke_msg_id_t const msgid,
    01818                              struct mm_chan_ctxt_del_req const *param,
    01819                              ke_task_id_t const dest_id,
    01820                              ke_task_id_t const src_id)
    01821 {
    01822     // Delete the channel context
    01823     chan_ctxt_del(param->index);
    01824
    01825     // Send the confirmation
    01826     ke_msg_send_basic(MM_CHAN_CTXT_DEL_CFM, src_id, dest_id);
    01827
    01828     //  Return the KE_MSG_CONSUMED status.
    01829     return (KE_MSG_CONSUMED);
    01830 }
    01831
    01848 static int
    01849 mm_chan_ctxt_link_req_handler(ke_msg_id_t const msgid,
    01850                               struct mm_chan_ctxt_link_req const *param,
    01851                               ke_task_id_t const dest_id,
    01852                               ke_task_id_t const src_id)
    01853 {
    01854     if (param->chan_switch)
    01855     {
    01856         // In case of channel switch unlink current ctxt first
    01857         chan_ctxt_unlink(param->vif_index);
    01858     }
    01859
    01860     // Link the channel context to the VIF
    01861     chan_ctxt_link(param->vif_index, param->chan_index);
    01862
    01863     // Send the confirmation
    01864     ke_msg_send_basic(MM_CHAN_CTXT_LINK_CFM, src_id, dest_id);
    01865
    01866     return (KE_MSG_CONSUMED);
    01867 }
    01868
    01883 static int
    01884 mm_chan_ctxt_sched_req_handler(ke_msg_id_t const msgid,
    01885                                struct mm_chan_ctxt_sched_req const *param,
    01886                                ke_task_id_t const dest_id,
    01887                                ke_task_id_t const src_id)
    01888 {
    01889     // Schedule the channel context
    01890     chan_ctxt_sched(param, src_id);
    01891
    01892     //  Return the status.
    01893     return (KE_MSG_CONSUMED);
    01894 }
    01895 #endif //(!NX_UMAC_PRESENT)
    01896
    01913 static int
    01914 mm_chan_ctxt_unlink_req_handler(ke_msg_id_t const msgid,
    01915                                 struct mm_chan_ctxt_unlink_req const *param,
    01916                                 ke_task_id_t const dest_id,
    01917                                 ke_task_id_t const src_id)
    01918 {
    01919     // Link the channel context to the VIF
    01920     chan_ctxt_unlink(param->vif_index);
    01921
    01922     // Send the confirmation
    01923     ke_msg_send_basic(MM_CHAN_CTXT_UNLINK_CFM, src_id, dest_id);
    01924
    01925     //  Return the status.
    01926     return (KE_MSG_CONSUMED);
    01927 }
    01928
    01945 static int
    01946 mm_chan_ctxt_update_req_handler(ke_msg_id_t const msgid,
    01947                                 struct mm_chan_ctxt_update_req const *param,
    01948                                 ke_task_id_t const dest_id,
    01949                                 ke_task_id_t const src_id)
    01950 {
    01951     // Link the channel context to the VIF
    01952     chan_ctxt_update(param);
    01953
    01954     // Send the confirmation
    01955     ke_msg_send_basic(MM_CHAN_CTXT_UPDATE_CFM, src_id, dest_id);
    01956
    01957     //  Return the KE_MSG_CONSUMED status.
    01958     return (KE_MSG_CONSUMED);
    01959 }
    01960
    01978 static int
    01979 mm_remain_on_channel_req_handler(ke_msg_id_t const msgid,
    01980                                  struct mm_remain_on_channel_req const *param,
    01981                                  ke_task_id_t const dest_id,
    01982                                  ke_task_id_t const src_id)
    01983 {
    01984     // Start RoC
    01985     uint8_t status = chan_roc_req(param, src_id);
    01986
    01987     #if (NX_TDLS)
    01988     if ((src_id != TASK_MM) && (src_id != TASK_TDLS))
    01989     #else
    01990     if (src_id != TASK_MM)
    01991     #endif
    01992     {
    01993         // Send back the confirmation
    01994         struct mm_remain_on_channel_cfm *cfm = KE_MSG_ALLOC(MM_REMAIN_ON_CHANNEL_CFM,
    01995                                                             src_id, dest_id,
    01996                                                             mm_remain_on_channel_cfm);
    01997
    01998         cfm->op_code         = param->op_code;
    01999         cfm->status          = status;
    02000         cfm->chan_ctxt_index = CHAN_ROC_CTXT_IDX;
    02001
    02002         ke_msg_send(cfm);
    02003     }
    02004
    02005     return (KE_MSG_CONSUMED);
    02006 }
    02007 #endif //(NX_CHNL_CTXT)
    02008
    02009 #if NX_BCN_AUTONOMOUS_TX
    02010
    02024 static int
    02025 mm_bcn_change_req_handler(ke_msg_id_t const msgid,
    02026                           struct mm_bcn_change_req const *param,
    02027                           ke_task_id_t const dest_id,
    02028                           ke_task_id_t const src_id)
    02029 {
    02030     // Schedule the channel context
    02031     mm_bcn_change(param);
    02032
    02033     //  Return the KE_MSG_CONSUMED status.
    02034     return (KE_MSG_NO_FREE);
    02035 }
    02036
    02051 static int
    02052 mm_tim_update_req_handler(ke_msg_id_t const msgid,
    02053                           struct mm_tim_update_req const *param,
    02054                           ke_task_id_t const dest_id,
    02055                           ke_task_id_t const src_id)
    02056 {
    02057     // Schedule the channel context
    02058     mm_tim_update(param);
    02059
    02060     //  Return the KE_MSG_CONSUMED status.
    02061     return (KE_MSG_NO_FREE);
    02062 }
    02063 #endif
    02064
    02065 #if (NX_ANT_DIV)
    02066
    02080 static int
    02081 mm_ant_div_init_req_handler(ke_msg_id_t const msgid,
    02082                             struct mm_ant_div_init_req const *param,
    02083                             ke_task_id_t const dest_id,
    02084                             ke_task_id_t const src_id)
    02085 {
    02086     // Initialize the parameters of antenna diversity
    02087     mm_ant_div_init(param->enable);
    02088
    02089     // Return the KE_MSG_CONSUMED status.
    02090     return (KE_MSG_CONSUMED);
    02091 }
    02092
    02107 static int
    02108 mm_ant_div_stop_req_handler(ke_msg_id_t const msgid,
    02109                             void const *param,
    02110                             ke_task_id_t const dest_id,
    02111                             ke_task_id_t const src_id)
    02112 {
    02113     // Switch antenna and stop the antenna diversity algorithm
    02114     mm_ant_div_switch_and_stop();
    02115
    02116     // Return the KE_MSG_CONSUMED status.
    02117     return (KE_MSG_CONSUMED);
    02118 }
    02119
    02120
    02135 static int
    02136 mm_ant_div_update_req_handler(ke_msg_id_t const msgid,
    02137                               void const *param,
    02138                               ke_task_id_t const dest_id,
    02139                               ke_task_id_t const src_id)
    02140 {
    02141     // Update the parameters of the antenna diversity
    02142     mm_ant_div_update();
    02143
    02144     // Return the KE_MSG_CONSUMED status.
    02145     return (KE_MSG_CONSUMED);
    02146 }
    02147
    02162 static int
    02163 mm_switch_antenna_req_handler(ke_msg_id_t const msgid,
    02164                               void const *param,
    02165                               ke_task_id_t const dest_id,
    02166                               ke_task_id_t const src_id)
    02167 {
    02168     // Switch antenna
    02169     mm_ant_div_switch_antenna();
    02170
    02171     // Return the KE_MSG_CONSUMED status.
    02172     return (KE_MSG_CONSUMED);
    02173 }
    02174 #endif
    02175
    02201 static int
    02202 mm_hw_config_handler(ke_msg_id_t const msgid,
    02203                      void const *param,
    02204                      ke_task_id_t const dest_id,
    02205                      ke_task_id_t const src_id)
    02206 {
    02207     int status = KE_MSG_SAVED;
    02208
    02209     // Check if we are in IDLE state
    02210     switch (ke_state_get(dest_id))
    02211     {
    02212         case MM_IDLE:
    02213             // Sanity check: As MM state is IDLE, HW state is also supposed to be IDLE
    02214             ASSERT_ERR(nxmac_current_state_getf() == HW_IDLE);
    02215
    02216             // Now that we are in IDLE state, handle the configuration request
    02217             switch (msgid)
    02218             {
    02219                 case MM_SET_CHANNEL_REQ:
    02220                     status = mm_set_channel_req_handler(msgid, param, dest_id, src_id);
    02221                     break;
    02222                 case MM_SET_FILTER_REQ:
    02223                     status = mm_set_filter_req_handler(msgid, param, dest_id, src_id);
    02224                     break;
    02225                 case MM_ADD_IF_REQ:
    02226                     status = mm_add_if_req_handler(msgid, param, dest_id, src_id);
    02227                     break;
    02228                 case MM_REMOVE_IF_REQ:
    02229                     status = mm_remove_if_req_handler(msgid, param, dest_id, src_id);
    02230                     break;
    02231                 case MM_SET_BASIC_RATES_REQ:
    02232                     status = mm_set_basic_rates_req_handler(msgid, param, dest_id, src_id);
    02233                     break;
    02234                 case MM_SET_BEACON_INT_REQ:
    02235                     status = mm_set_beacon_int_req_handler(msgid, param, dest_id, src_id);
    02236                     break;
    02237                 case MM_SET_DTIM_REQ:
    02238                     status = mm_set_dtim_req_handler(msgid, param, dest_id, src_id);
    02239                     break;
    02240                 case MM_SET_BSSID_REQ:
    02241                     status = mm_set_bssid_req_handler(msgid, param, dest_id, src_id);
    02242                     break;
    02243                 case MM_SET_SLOTTIME_REQ:
    02244                     status = mm_set_slottime_req_handler(msgid, param, dest_id, src_id);
    02245                     break;
    02246                 case MM_SET_MODE_REQ:
    02247                     status = mm_set_mode_req_handler(msgid, param, dest_id, src_id);
    02248                     break;
    02249                 case MM_SET_VIF_STATE_REQ:
    02250                     status = mm_set_vif_state_req_handler(msgid, param, dest_id, src_id);
    02251                     break;
    02252                 case MM_BA_ADD_REQ:
    02253                     status = mm_ba_add_req_handler(msgid, param, dest_id, src_id);
    02254                     break;
    02255                 #if (NX_CHNL_CTXT)
    02256                 case MM_CHAN_CTXT_UPDATE_REQ:
    02257                     status = mm_chan_ctxt_update_req_handler(msgid, param, dest_id, src_id);
    02258                     break;
    02259                 #endif //(NX_CHNL_CTXT)
    02260                 case MM_DBG_TRIGGER_REQ:
    02261                     status = mm_dbg_trigger_req_handler(msgid, param, dest_id, src_id);
    02262                     break;
    02263                 #if (NX_ANT_DIV)
    02264                 case MM_SWITCH_ANTENNA_REQ:
    02265                     status = mm_switch_antenna_req_handler(msgid, param, dest_id, src_id);
    02266                     break;
    02267                 #endif //(NX_ANT_DIV)
    02268                 #if NX_BEACONING
    02269                 case MM_TBTT_MOVE_REQ:
    02270                     status = mm_tbtt_move_req_handler(msgid, param, dest_id, src_id);
    02271                     break;
    02272                 #endif //NX_BEACONING
    02273
    02274                 default:
    02275                     ASSERT_ERR(0);
    02276                     break;
    02277             }
    02278
    02279             // Restore the HW state
    02280             nxmac_next_state_setf(mm_env.prev_hw_state);
    02281
    02282             // As well as the MM state
    02283             ke_state_set(dest_id, mm_env.prev_mm_state);
    02284             break;
    02285
    02286         case MM_GOING_TO_IDLE:
    02287         case MM_HOST_BYPASSED:
    02288         case MM_NO_IDLE:
    02289             // MAC is currently going to IDLE, or IDLE is disallowed, so simply save the
    02290             // message. It will be rescheduled once the MAC has switched to IDLE or once
    02291             // IDLE is allowed again.
    02292             break;
    02293
    02294         default:
    02295             // Store the current HW and MM states for later restoring
    02296             mm_env.prev_hw_state = nxmac_current_state_getf();
    02297             mm_env.prev_mm_state = ke_state_get(dest_id);
    02298
    02299             // Request to MAC HW to switch to IDLE state
    02300             hal_machw_idle_req();
    02301
    02302             // Adjust the MM state accordingly
    02303             ke_state_set(dest_id, MM_GOING_TO_IDLE);
    02304             break;
    02305     }
    02306
    02307     return (status);
    02308 }
    02309
    02310 #if NX_POWERSAVE
    02311
    02325 static int
    02326 mm_set_ps_mode_req_handler(ke_msg_id_t const msgid,
    02327                            struct mm_set_ps_mode_req const *param,
    02328                            ke_task_id_t const dest_id,
    02329                            ke_task_id_t const src_id)
    02330 {
    02331     // Ask the PS module to change the Power-save mode
    02332     ps_set_mode(param->new_state, src_id);
    02333
    02334     return (KE_MSG_CONSUMED);
    02335 }
    02336
    02353 static int
    02354 mm_set_ps_options_req_handler(ke_msg_id_t const msgid,
    02355                               struct mm_set_ps_options_req const *param,
    02356                               ke_task_id_t const dest_id,
    02357                               ke_task_id_t const src_id)
    02358 {
    02359     struct vif_info_tag *vif = &vif_info_tab[param->vif_index];
    02360
    02361     // Sanity check - These parameters apply only for a STA interface
    02362     ASSERT_ERR(vif->type == VIF_STA);
    02363
    02364     // Set the parameters
    02365     vif->u.sta.listen_interval = param->listen_interval;
    02366     vif->u.sta.dont_wait_bcmc = param->dont_listen_bc_mc;
    02367
    02368     // Send the confirmation
    02369     ke_msg_send_basic(MM_SET_PS_OPTIONS_CFM, src_id, dest_id);
    02370
    02371     return (KE_MSG_CONSUMED);
    02372 }
    02373 #endif
    02374
    02375 #if (NX_P2P_GO)
    02376
    02392 static int mm_set_p2p_noa_req_handler(ke_msg_id_t const msgid,
    02393                                       struct mm_set_p2p_noa_req const *param,
    02394                                       ke_task_id_t const dest_id,
    02395                                       ke_task_id_t const src_id)
    02396 {
    02397     // Allocate confirmation message
    02398     struct mm_set_p2p_noa_cfm *cfm = KE_MSG_ALLOC(MM_SET_P2P_NOA_CFM, TASK_API,
    02399                                                   TASK_MM, mm_set_p2p_noa_cfm);
    02400     struct vif_info_tag *vif;
    02401
    02402     cfm->status = CO_FAIL;
    02403
    02404     if ((param->vif_index <= NX_VIRT_DEV_MAX) &&
    02405         (vif = &vif_info_tab[param->vif_index]) && vif->p2p)
    02406     {
    02407         if (param->count)
    02408         {
    02409             // Compute next TBTT instant in order to deduce the NOA start time
    02410             uint32_t beacon_int = (uint32_t)vif->u.ap.bcn_int << 10;
    02411             uint32_t next_tbtt  = ((nxmac_tsf_lo_get() / beacon_int) + 1) * beacon_int;
    02412             uint8_t noa_idx;
    02413
    02414             // Next TBTT time is currently based on TSF value, as TSF counter and
    02415             // Monoatomic counter might have different values, we have to convert this
    02416             // value in local time in order to use internal timers.
    02417             // The NOA start time inserted in the beacon will be a TSF value.
    02418             next_tbtt += (ke_time() - nxmac_tsf_lo_get());
    02419
    02420             // Start NOA procedure and check if NOA has been successfully added
    02421             noa_idx = p2p_go_noa_start(vif, false, param->dyn_noa, param->count,
    02422                                        param->interval_us, param->duration_us,
    02423                                        next_tbtt + param->start_offset);
    02424             if (noa_idx != P2P_INVALID_IDX)
    02425             {
    02426                 cfm->status = CO_OK;
    02427             }
    02428         }
    02429         else
    02430         {
    02431             cfm->status = p2p_go_noa_stop(vif, param->noa_inst_nb, true);
    02432         }
    02433     }
    02434
    02435     // Send the message
    02436     ke_msg_send(cfm);
    02437
    02438     return (KE_MSG_CONSUMED);
    02439 }
    02440
    02457 static int mm_set_p2p_oppps_req_handler(ke_msg_id_t const msgid,
    02458                                         struct mm_set_p2p_oppps_req const *param,
    02459                                         ke_task_id_t const dest_id,
    02460                                         ke_task_id_t const src_id)
    02461 {
    02462     // Allocate confirmation message
    02463     struct mm_set_p2p_oppps_cfm *cfm = KE_MSG_ALLOC(MM_SET_P2P_OPPPS_CFM, TASK_API,
    02464                                                     TASK_MM, mm_set_p2p_oppps_cfm);
    02465     struct vif_info_tag *vif;
    02466
    02467     cfm->status = CO_FAIL;
    02468
    02469     if ((param->vif_index <= NX_VIRT_DEV_MAX) &&
    02470         (vif = &vif_info_tab[param->vif_index]) && vif->p2p)
    02471     {
    02472         cfm->status = CO_OK;
    02473
    02474         if (param->ctwindow)
    02475         {
    02476             // Start OPPPS procedure
    02477             p2p_go_oppps_start(vif, param->ctwindow);
    02478         }
    02479         else
    02480         {
    02481             p2p_go_oppps_stop(vif);
    02482         }
    02483     }
    02484
    02485     // Send the message
    02486     ke_msg_send(cfm);
    02487
    02488     return (KE_MSG_CONSUMED);
    02489 }
    02490 #endif //(NX_P2P_GO)
    02491
    02492 #if (RW_BFMER_EN)
    02493
    02507 static int mm_bfmer_enable_req_handler(ke_msg_id_t const msgid,
    02508                                        struct mm_bfmer_enable_req const *param,
    02509                                        ke_task_id_t const dest_id,
    02510                                        ke_task_id_t const src_id)
    02511 {
    02512     // Check that connection exists
    02513     if (bfr_is_enabled() && (sta_info_tab[param->sta_idx].staid != INVALID_STA_IDX))
    02514     {
    02515         bfr_add_sta_ind(param->sta_idx, param->vht_mu_bfmee, param->aid, param->host_bfr_addr,
    02516                         param->host_bfr_size, param->rx_nss);
    02517     }
    02518
    02519     return (KE_MSG_CONSUMED);
    02520 }
    02521 #endif //(RW_BFMER_EN)
    02522
    02523 #if (RW_MUMIMO_TX_EN)
    02524
    02538 static int mm_mu_group_update_req_handler(ke_msg_id_t const msgid,
    02539                                           struct mm_mu_group_update_req const *param,
    02540                                           ke_task_id_t const dest_id,
    02541                                           ke_task_id_t const src_id)
    02542 {
    02543     // Update the peer
    02544     bfr_group_update_req(param);
    02545
    02546     // Freeing done when the request is confirmed to the host
    02547     return (KE_MSG_NO_FREE);
    02548 }
    02549 #endif //(RW_MUMIMO_TX_EN)
    02550
    02565 static int mm_cfg_rssi_req_handler(ke_msg_id_t const msgid,
    02566                                    struct mm_cfg_rssi_req const *param,
    02567                                    ke_task_id_t const dest_id,
    02568                                    ke_task_id_t const src_id)
    02569 {
    02570     struct vif_info_tag *vif = &vif_info_tab[param->vif_index];
    02571
    02572     // Sanity check - These parameters apply only for a STA interface
    02573     ASSERT_ERR(vif->type == VIF_STA);
    02574
    02575     // Set the parameters
    02576     vif->u.sta.rssi_thold = param->rssi_thold;
    02577     vif->u.sta.rssi_hyst = param->rssi_hyst;
    02578     vif->u.sta.rssi_status = 0;
    02579
    02580     return (KE_MSG_CONSUMED);
    02581 }
    02582
    02583 /*
    02584  * TASK DESCRIPTOR DEFINITIONS
    02585  ****************************************************************************************
    02586  */
    02588 const struct ke_msg_handler mm_default_state[] =
    02589 {
    02590     // From UMAC
    02591     {MM_START_REQ, (ke_msg_func_t)mm_start_req_handler},
    02592     // From UMAC
    02593     {MM_VERSION_REQ, (ke_msg_func_t)mm_version_req_handler},
    02594     // From UMAC
    02595     {MM_ADD_IF_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02596     // From UMAC
    02597     {MM_REMOVE_IF_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02598     // From UMAC
    02599     {MM_RESET_REQ, (ke_msg_func_t)mm_reset_req_handler},
    02600     // From UMAC
    02601     {MM_SET_CHANNEL_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02602     // From UMAC
    02603     {MM_SET_BASIC_RATES_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02604     // From UMAC
    02605     {MM_SET_BEACON_INT_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02606     // From UMAC
    02607     {MM_SET_DTIM_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02608     // From UMAC
    02609     {MM_SET_FILTER_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02610     // From UMAC
    02611     {MM_SET_BSSID_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02612     // From UMAC
    02613     {MM_SET_EDCA_REQ, (ke_msg_func_t)mm_set_edca_req_handler},
    02614     // From UMAC
    02615     {MM_SET_MU_EDCA_REQ, (ke_msg_func_t)mm_set_mu_edca_req_handler},
    02616     // From UMAC
    02617     {MM_SET_UORA_REQ, (ke_msg_func_t)mm_set_uora_req_handler},
    02618     // From UMAC
    02619     {MM_SET_BSS_COLOR_REQ, (ke_msg_func_t)mm_set_bss_color_req_handler},
    02620     // From UMAC
    02621     {MM_SET_TXOP_RTS_THRES_REQ, (ke_msg_func_t)mm_set_txop_rts_thres_req_handler},
    02622     // From UMAC
    02623     {MM_SET_SLOTTIME_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02624     // From UMAC
    02625     {MM_SET_MODE_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02626     // From UMAC
    02627     {MM_SET_VIF_STATE_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02628     // From UMAC
    02629     {MM_DBG_TRIGGER_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02630     // From UMAC
    02631     {MM_SET_IDLE_REQ, (ke_msg_func_t)mm_set_idle_req_handler},
    02632     // From internal
    02633     {MM_FORCE_IDLE_REQ, (ke_msg_func_t)mm_force_idle_req_handler},
    02634     // From UMAC
    02635     {MM_SET_POWER_REQ, (ke_msg_func_t)mm_set_power_req_handler},
    02636     // From UMAC
    02637     {MM_KEY_ADD_REQ, (ke_msg_func_t)mm_key_add_req_handler},
    02638     // From UMAC
    02639     {MM_KEY_DEL_REQ, (ke_msg_func_t)mm_key_del_req_handler},
    02640     // From UMAC
    02641     {MM_STA_ADD_REQ, (ke_msg_func_t)mm_sta_add_req_handler},
    02642     // From UMAC
    02643     {MM_STA_DEL_REQ, (ke_msg_func_t)mm_sta_del_req_handler},
    02644
    02645     // From UMAC
    02646     {MM_BA_ADD_REQ,  (ke_msg_func_t)mm_hw_config_handler},
    02647     #if (NX_AMPDU_TX || NX_REORD)
    02648     // From UMAC
    02649     {MM_BA_DEL_REQ,  (ke_msg_func_t)mm_ba_del_req_handler},
    02650     #endif
    02651
    02652     #if (NX_CHNL_CTXT)
    02653     #if (!NX_UMAC_PRESENT)
    02654     // From UMAC
    02655     {MM_CHAN_CTXT_ADD_REQ, (ke_msg_func_t)mm_chan_ctxt_add_req_handler},
    02656     // From UMAC
    02657     {MM_CHAN_CTXT_DEL_REQ,  (ke_msg_func_t)mm_chan_ctxt_del_req_handler},
    02658     // From UMAC
    02659     {MM_CHAN_CTXT_LINK_REQ, (ke_msg_func_t)mm_chan_ctxt_link_req_handler},
    02660     // From UMAC
    02661     {MM_CHAN_CTXT_SCHED_REQ,  (ke_msg_func_t)mm_chan_ctxt_sched_req_handler},
    02662     #endif //(!NX_UMAC_PRESENT)
    02663     // From UMAC
    02664     {MM_CHAN_CTXT_UNLINK_REQ,  (ke_msg_func_t)mm_chan_ctxt_unlink_req_handler},
    02665     // From UMAC
    02666     {MM_CHAN_CTXT_UPDATE_REQ,  (ke_msg_func_t)mm_hw_config_handler},
    02667     // From UMAC
    02668     {MM_REMAIN_ON_CHANNEL_REQ,  (ke_msg_func_t)mm_remain_on_channel_req_handler},
    02669     #endif //(NX_CHNL_CTXT)
    02670
    02671     #if NX_BCN_AUTONOMOUS_TX
    02672     // From UMAC
    02673     {MM_BCN_CHANGE_REQ,  (ke_msg_func_t)mm_bcn_change_req_handler},
    02674     // From UMAC
    02675     {MM_TIM_UPDATE_REQ,  (ke_msg_func_t)mm_tim_update_req_handler},
    02676     #endif
    02677
    02678     #if NX_POWERSAVE
    02679     // From UMAC
    02680     {MM_SET_PS_MODE_REQ, (ke_msg_func_t)mm_set_ps_mode_req_handler},
    02681     // From UMAC
    02682     {MM_SET_PS_OPTIONS_REQ, (ke_msg_func_t)mm_set_ps_options_req_handler},
    02683     #endif
    02684
    02685     #if (NX_P2P_GO)
    02686     // From UMAC
    02687     {MM_SET_P2P_NOA_REQ,   (ke_msg_func_t)mm_set_p2p_noa_req_handler},
    02688     // From UMAC
    02689     {MM_SET_P2P_OPPPS_REQ, (ke_msg_func_t)mm_set_p2p_oppps_req_handler},
    02690     #endif //(NX_P2P_GO)
    02691
    02692     #if (RW_BFMER_EN)
    02693     // From UMAC
    02694     {MM_BFMER_ENABLE_REQ, (ke_msg_func_t)mm_bfmer_enable_req_handler},
    02695     #endif //(RW_BFMER_EN)
    02696     #if (RW_MUMIMO_TX_EN)
    02697     // From UMAC
    02698     {MM_MU_GROUP_UPDATE_REQ, (ke_msg_func_t)mm_mu_group_update_req_handler},
    02699     #endif //(RW_MUMIMO_TX_EN)
    02700
    02701     {MM_CFG_RSSI_REQ, (ke_msg_func_t)mm_cfg_rssi_req_handler},
    02702
    02703     #if (NX_ANT_DIV)
    02704     // From UMAC
    02705     {MM_ANT_DIV_INIT_REQ, (ke_msg_func_t)mm_ant_div_init_req_handler},
    02706     // From UMAC
    02707     {MM_ANT_DIV_STOP_REQ, (ke_msg_func_t)mm_ant_div_stop_req_handler},
    02708     // From UMAC
    02709     {MM_ANT_DIV_UPDATE_REQ, (ke_msg_func_t)mm_ant_div_update_req_handler},
    02710     // From UMAC or internal
    02711     {MM_SWITCH_ANTENNA_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02712     #endif //(NX_ANT_DIV)
    02713     #if NX_BEACONING
    02714     {MM_TBTT_MOVE_REQ, (ke_msg_func_t)mm_hw_config_handler},
    02715     #endif //(NX_BEACONING)
    02716 };
    02717
    02719 const struct ke_state_handler mm_state_handler[MM_STATE_MAX] =
    02720 {
    02722     [MM_IDLE] = KE_STATE_HANDLER_NONE,
    02724     [MM_ACTIVE] = KE_STATE_HANDLER_NONE,
    02725 };
    02726
    02728 const struct ke_state_handler mm_default_handler =
    02729     KE_STATE_HANDLER(mm_default_state);
    02730
    02732 ke_state_t mm_state[MM_IDX_MAX];
    02733