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
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
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
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
00088 if (LOCAL_CAPA(HT))
00089 {
00090
00091 me_env.stbc_nss = (phy_get_nss()+1)/2;
00092
00093
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
00113 me_env.tx_lft = param->tx_lft;
00114
00115 #if NX_POWERSAVE
00116
00117 me_env.ps_on = param->ps_on;
00118 me_env.ps_mode = param->dpsm ? PS_MODE_ON_DYN : PS_MODE_ON;
00119
00120
00121 if (me_env.ps_on)
00122 {
00123
00124 me_env.requester_id = TASK_NONE;
00125
00126
00127 ps->new_state = me_env.ps_mode;
00128 ke_msg_send(ps);
00129
00130
00131 ke_state_set(TASK_ME, ME_BUSY);
00132 }
00133 #endif
00134
00135 #if (NX_ANT_DIV)
00136
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
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
00195 struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
00196
00197 struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
00198
00199
00200 sta->ctrl_port_state = param->control_port_open?PORT_OPEN:PORT_CONTROLED;
00201
00202
00203
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
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
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
00269 if (param->flags & STA_HT_CAPA)
00270 {
00271 struct mac_htcapability const *ht_cap = ¶m->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 = ¶m->vht_cap;
00279
00280 switch (vif->type)
00281 {
00282
00283 case VIF_STA:
00284 paid_gid = mac_paid_gid_ap_compute(&vif->bss_info.bssid,
00285 param->aid);
00286 break;
00287
00288 case VIF_MESH_POINT:
00289 paid_gid = mac_paid_gid_sta_compute(¶m->mac_addr);
00290 break;
00291
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 = ¶m->he_cap;
00305 }
00306 #endif
00307
00308 me_get_ampdu_params(ht_cap, vht_cap, he_cap, &du_size_max_ht,
00309 &du_size_max_vht, &du_size_max_he,
00310 &du_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
00328 rsp->status = mm_sta_add(&sta_add_req, &rsp->sta_idx, &hw_sta_idx);
00329
00330
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
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
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
00380 info->uapsd_queues = param->uapsd_queues;
00381 info->max_sp_len = param->max_sp_len;
00382 sta->aid = param->aid;
00383
00384
00385 me_init_rate(sta);
00386
00387
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
00394 me_sta_bw_nss_max_upd(sta->staid, bw, nss);
00395 }
00396
00397
00398 if (smps)
00399 {
00400
00401 me_sta_bw_nss_max_upd(sta->staid, 0xFF, 0);
00402 }
00403
00404
00405 sta->pol_tbl.upd_field |= CO_BIT(STA_MGMT_POL_UPD_TX_POWER);
00406
00407
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
00412 rsp->pm_state = pm_state;
00413
00414 if (rsp->pm_state)
00415 {
00416
00417 sta->ps_state = pm_state;
00418
00419
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
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
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
00466 bam_delete_all_ba_agg(param->sta_idx);
00467 #endif
00468
00469
00470 sta_del->sta_idx = param->sta_idx;
00471 ke_msg_send(sta_del);
00472
00473
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
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
00510 bool send_req = true;
00511
00512 if (param->uapsd)
00513 {
00514
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
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
00572 if (ke_state_get(TASK_ME) == ME_BUSY)
00573 return (KE_MSG_SAVED);
00574
00575
00576 if ((me_env.active_vifs && param->active) ||
00577 (!me_env.active_vifs && !param->active))
00578 {
00579
00580 if (param->active)
00581 me_env.active_vifs |= CO_BIT(param->vif_idx);
00582
00583
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
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
00598 me_env.requester_id = src_id;
00599
00600
00601 active->hw_idle = (me_env.active_vifs == 0);
00602 ke_msg_send(active);
00603
00604
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
00630 ASSERT_ERR(ke_state_get(dest_id) == ME_BUSY);
00631
00632
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
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
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
00671 if (!me_env.ps_on)
00672 {
00673
00674 ke_msg_send_basic(ME_SET_PS_DISABLE_CFM, src_id, dest_id);
00675
00676 return (KE_MSG_CONSUMED);
00677 }
00678
00679
00680 if (ke_state_get(TASK_ME) == ME_BUSY)
00681 return (KE_MSG_SAVED);
00682
00683
00684 if ((ps_disable_vifs && param->ps_disable) ||
00685 (!ps_disable_vifs && !param->ps_disable))
00686 {
00687
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
00696 me_env.requester_id = src_id;
00697
00698
00699 ps->new_state = (me_env.ps_disable_vifs == 0)?me_env.ps_mode:PS_MODE_OFF;
00700 ke_msg_send(ps);
00701
00702
00703 ke_state_set(dest_id, ME_BUSY);
00704 }
00705 #else
00706
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
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
00750 me_env.requester_id = TASK_NONE;
00751
00752
00753 ps->new_state = (me_env.ps_on) ? me_env.ps_mode : PS_MODE_OFF;
00754 ke_msg_send(ps);
00755
00756
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
00783 ASSERT_ERR(ke_state_get(dest_id) == ME_BUSY);
00784
00785
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
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
00815 struct me_rc_stats_cfm *rsp = KE_MSG_ALLOC(ME_RC_STATS_CFM, src_id, dest_id, me_rc_stats_cfm);
00816
00817
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
00824 rsp->sta_idx = param->sta_idx;
00825 if (rc_ss)
00826 {
00827
00828 rsp->no_samples = rc_ss->no_samples;
00829
00830 rsp->ampdu_len = rc_ss->ampdu_len;
00831
00832 rsp->ampdu_packets = rc_ss->ampdu_packets;
00833
00834 rsp->avg_ampdu_len = rc_ss->avg_ampdu_len;
00835
00836 rsp->sw_retry_step = rc_ss->sw_retry_step;
00837
00838 rsp->sample_wait = rc_ss->sample_wait;
00839
00840 memcpy(rsp->retry_step_idx, rc_ss->retry_step_idx, sizeof(rsp->retry_step_idx));
00841
00842 memcpy(&rsp->rate_stats[0], &rc_ss->rate_stats[0], sizeof(rsp->rate_stats) -
00843 NX_HE * sizeof(struct rc_rate_stats));
00844
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
00852
00853 rsp->rate_stats[RC_HE_STATS_IDX] = rc_ss->rate_stats[RC_HE_STATS_IDX];
00854
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
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
00899 rc_ss->fixed_rate_cfg = fixed_rate_cfg;
00900
00901 rc_ss->info &= ~RC_FIX_RATE_STATUS_MASK;
00902 rc_ss->info |= RC_FIX_RATE_REQ_MASK;
00903 }
00904 }
00905 else
00906 {
00907
00908 rc_ss->fixed_rate_cfg = fixed_rate_cfg;
00909 rc_ss->info &= ~RC_FIX_RATE_STATUS_MASK;
00910
00911 if (rc_ss->info & RC_FIX_RATE_UPD_SS_REQ_MASK)
00912 {
00913
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
00945 if (ke_state_get(TASK_ME) == ME_BUSY)
00946 return (KE_MSG_SAVED);
00947
00948
00949 rsp = KE_MSG_ALLOC(ME_CONFIG_MONITOR_CFM, src_id, dest_id, me_config_monitor_cfm);
00950
00951
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
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
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
00976 req->chan_index = vif->chan_ctxt->idx;
00977 req->chan = param->chan;
00978
00979
00980 ke_msg_send(req);
00981
00982
00983 rsp->chan = param->chan;
00984 }
00985 else
00986 {
00987
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