00001
00020
00021
00022
00023
00024
00025 #include "vif_mgmt.h"
00026 #include "mm.h"
00027 #include "chan.h"
00028 #include "mm_bcn.h"
00029 #include "co_utils.h"
00030 #include "co_status.h"
00031 #include "dbg.h"
00032
00033 #if (NX_CHNL_CTXT || NX_P2P)
00034 #include "txl_cntrl.h"
00035 #if (NX_P2P)
00036
00037 #include "p2p.h"
00038 #endif //(NX_P2P)
00039 #if (NX_POWERSAVE)
00040 #include "ps.h"
00041 #endif //(NX_POWERSAVE)
00042 #endif //(NX_CHNL_CTXT || NX_P2P)
00043
00044 #if (NX_TD)
00045
00046 #include "td.h"
00047 #endif //(NX_TD)
00048
00049 #if (RW_UMESH_EN)
00050 #include "mesh.h"
00051 #endif //(RW_UMESH_EN)
00052
00053 #if NX_UMAC_PRESENT
00054 #include "me_utils.h"
00055 #include "tpc.h"
00056 #endif
00057
00058
00059
00060
00061
00062 struct vif_mgmt_env_tag vif_mgmt_env;
00063 struct vif_info_tag vif_info_tab[NX_VIRT_DEV_MAX];
00064
00065
00066
00067
00068
00069
00070 #if (NX_P2P || NX_CHNL_CTXT)
00071
00078 static void vif_mgmt_bcn_to_evt(void *env)
00079 {
00080
00081 struct vif_info_tag *vif = (struct vif_info_tag *)env;
00082
00083 #if (NX_P2P)
00084
00085 if (vif->p2p)
00086 {
00087 p2p_bcn_evt_handle(vif);
00088 }
00089 #endif //(NX_P2P)
00090
00091 if (vif->chan_ctxt)
00092 {
00093 chan_bcn_to_evt(vif);
00094 }
00095 }
00096 #endif //(NX_P2P || NX_CHNL_CTXT)
00097
00105 static void vif_mgmt_entry_init(struct vif_info_tag *vif)
00106 {
00107
00108 memset(vif, 0, sizeof(*vif));
00109
00110 vif->type = VIF_UNKNOWN;
00111 vif->tx_power = VIF_UNDEF_POWER;
00112 #if NX_UMAC_PRESENT
00113 vif->user_tx_power = VIF_UNDEF_POWER;
00114 #endif
00115
00116 #if (NX_P2P || NX_CHNL_CTXT)
00117
00118 vif->tmr_bcn_to.cb = vif_mgmt_bcn_to_evt;
00119 vif->tmr_bcn_to.env = vif;
00120 #endif //(NX_P2P || NX_CHNL_CTXT)
00121 }
00122
00123 void vif_mgmt_init(void)
00124 {
00125 int i;
00126
00127
00128 memset(&vif_mgmt_env, 0, sizeof(vif_mgmt_env));
00129
00130
00131 co_list_init(&vif_mgmt_env.free_list);
00132 co_list_init(&vif_mgmt_env.used_list);
00133
00134
00135 for(i = 0; i < NX_VIRT_DEV_MAX ; i++)
00136 {
00137 struct vif_info_tag *vif = &vif_info_tab[i];
00138
00139 vif_mgmt_entry_init(vif);
00140
00141 co_list_push_back(&vif_mgmt_env.free_list, (struct co_list_hdr*)vif);
00142 }
00143
00144
00145 vif_mgmt_env.monitor_vif = INVALID_VIF_IDX;
00146 }
00147
00148 #if (NX_TX_FRAME)
00149 void vif_mgmt_reset(void)
00150 {
00151 struct vif_info_tag *vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00152
00153 while (vif)
00154 {
00155
00156 vif_mgmt_send_postponed_frame(vif);
00157
00158 vif = (struct vif_info_tag *)vif->list_hdr.next;
00159 }
00160 }
00161 #endif //(NX_TX_FRAME)
00162
00163 uint8_t vif_mgmt_register(struct mac_addr const *mac_addr, uint8_t vif_type, bool p2p,
00164 uint8_t *vif_idx)
00165 {
00166 struct vif_info_tag *vif;
00167
00168
00169 if (co_list_is_empty(&vif_mgmt_env.free_list))
00170
00171 return CO_FAIL;
00172
00173 #if (NX_P2P)
00174 if (p2p && (vif_type == VIF_AP))
00175 {
00176 #if (NX_P2P_GO)
00177 if (p2p_env.nb_p2p_go)
00178
00179 return CO_FAIL;
00180 #else
00181
00182 return CO_FAIL;
00183 #endif //(NX_P2P_GO)
00184 }
00185 #endif //(NX_P2P)
00186
00187
00188 if (co_list_is_empty(&vif_mgmt_env.used_list))
00189 {
00190 #if NX_MULTI_ROLE
00191
00192 mm_hw_info_set(mac_addr);
00193 #else
00194 #if NX_BEACONING && (NX_POWERSAVE || NX_CONNECTION_MONITOR || NX_UMAC_PRESENT)
00195
00196 if ((vif_type == VIF_AP) || (vif_type == VIF_IBSS))
00197 {
00198 mm_env.beaconing = true;
00199 }
00200 else
00201 {
00202 mm_env.beaconing = false;
00203 }
00204 #endif
00205
00206 mm_hw_interface_info_set(vif_type, mac_addr);
00207 #endif
00208 }
00209 else
00210 {
00211 uint32_t vif_addr_low, vif_addr_high;
00212
00213 #if (!NX_MULTI_ROLE)
00214 struct vif_info_tag *vif = (struct vif_info_tag *)
00215 co_list_pick(&vif_mgmt_env.used_list);
00216
00217
00218 if ((vif->type != VIF_AP) || (vif_type != VIF_AP))
00219 return CO_FAIL;
00220 #endif //(!NX_MULTI_ROLE)
00221
00222 #if (NX_P2P)
00223 if (p2p)
00224 {
00225
00226 if (vif_mgmt_env.nb_p2p_vifs == NX_P2P_VIF_MAX)
00227 return CO_FAIL;
00228 }
00229 #endif //(NX_P2P)
00230
00231
00232 vif_addr_low = mac_addr->array[0] | (((uint32_t)mac_addr->array[1]) << 16);
00233 vif_addr_high = mac_addr->array[2];
00234 if ((vif_addr_low != nxmac_mac_addr_low_get()) ||
00235 (((vif_addr_high ^ nxmac_mac_addr_hi_get()) & ~nxmac_mac_addr_hi_mask_get()) != 0))
00236 return CO_FAIL;
00237
00238 #if (NX_MULTI_ROLE)
00239
00240 mm_rx_filter_lmac_enable_set(NXMAC_ACCEPT_OTHER_BSSID_BIT);
00241 #endif //(NX_MULTI_ROLE)
00242 }
00243
00244
00245 vif = (struct vif_info_tag*)co_list_pop_front(&vif_mgmt_env.free_list);
00246
00247
00248 vif->type = vif_type;
00249 vif->mac_addr = *mac_addr;
00250 vif->index = CO_GET_INDEX(vif, vif_info_tab);
00251 vif->txq_params[AC_BK] = NXMAC_EDCA_AC_0_RESET;
00252 vif->txq_params[AC_BE] = NXMAC_EDCA_AC_1_RESET;
00253 vif->txq_params[AC_VI] = NXMAC_EDCA_AC_2_RESET;
00254 vif->txq_params[AC_VO] = NXMAC_EDCA_AC_3_RESET;
00255 vif->tx_power = VIF_UNDEF_POWER;
00256 #if NX_UMAC_PRESENT
00257 vif->user_tx_power = VIF_UNDEF_POWER;
00258 #endif
00259 #if (NX_CHNL_CTXT)
00260 vif->chan_ctxt = NULL;
00261 vif->tbtt_switch.vif_index = vif->index;
00262 #endif //(NX_CHNL_CTXT)
00263 #if NX_MAC_HE
00264 vif->txop_dur_rts_thres = MAC_HE_OPER_TXOP_DUR_RTS_THRES_DISABLED;
00265 #endif
00266 #if (NX_P2P)
00267 vif->p2p = p2p;
00268 vif->u.sta.sp_paused = false;
00269 #endif //(NX_P2P)
00270
00271 #if (NX_MULTI_ROLE || NX_BCN_AUTONOMOUS_TX || NX_REORD)
00272 switch (vif_type)
00273 {
00274 case (VIF_STA):
00275 {
00276 #if NX_MULTI_ROLE
00277
00278 vif_mgmt_env.vif_sta_cnt++;
00279
00280
00281 vif->tbtt_timer.cb = mm_sta_tbtt;
00282 vif->tbtt_timer.env = vif;
00283 #if !NX_UMAC_PRESENT
00284 vif->u.sta.ap_bcn_intv = 100;
00285 #endif
00286 #endif
00287
00288 vif->u.sta.ap_id = INVALID_STA_IDX;
00289
00290 #if NX_UMAC_PRESENT
00291 vif->u.sta.csa_count = 0;
00292 vif->u.sta.csa_occured = false;
00293 #endif
00294 } break;
00295
00296 #if (RW_MESH_EN)
00297 case (VIF_MESH_POINT):
00298 {
00299 #if (RW_UMESH_EN)
00300 vif->mvif_idx = MESH_INVALID_MESH_IDX;
00301 #endif //(RW_UMESH_EN)
00302
00303 vif_mgmt_env.vif_mp_cnt++;
00304
00305
00306 mm_rx_filter_lmac_enable_set(NXMAC_ACCEPT_OTHER_BSSID_BIT);
00307 }
00308 #endif //(RW_MESH_EN)
00309
00310 case (VIF_AP):
00311 {
00312 #if NX_MULTI_ROLE
00313
00314 if (!vif_mgmt_env.vif_ap_cnt)
00315 mm_hw_ap_info_set();
00316
00317
00318 vif_mgmt_env.vif_ap_cnt++;
00319 #endif
00320
00321 #if (!NX_UMAC_PRESENT && NX_BCN_AUTONOMOUS_TX)
00322
00323 vif->u.ap.bcn_int = 100;
00324 #endif //(!NX_UMAC_PRESENT)
00325
00326 #if (NX_P2P_GO && NX_POWERSAVE)
00327 if (vif->p2p)
00328 {
00329
00330 vif->tbtt_timer.cb = mm_ap_pre_tbtt;
00331 vif->tbtt_timer.env = vif;
00332 }
00333 #endif //(NX_P2P_GO && NX_POWERSAVE)
00334
00335 #if (NX_BCN_AUTONOMOUS_TX)
00336 mm_bcn_init_vif(vif);
00337 #endif
00338 } break;
00339
00340 case (VIF_MONITOR):
00341 {
00342 if (vif_mgmt_env.monitor_vif != INVALID_VIF_IDX)
00343 return CO_FAIL;
00344
00345
00346 vif_mgmt_env.monitor_vif = vif->index;
00347
00348 #if (NX_UMAC_PRESENT)
00349
00350 if (co_list_is_empty(&vif_mgmt_env.used_list))
00351 {
00352 struct mac_chan_op chan;
00353 uint8_t chan_idx;
00354
00355
00356 chan.band = PHY_BAND_2G4;
00357 chan.type = PHY_CHNL_BW_20;
00358 chan.prim20_freq = 2437;
00359 chan.center1_freq = 2437;
00360 chan.center2_freq = 0;
00361
00362
00363 hal_machw_monitor_mode();
00364
00365
00366 if (chan_ctxt_add(&chan, &chan_idx) != CO_OK)
00367 {
00368 return CO_FAIL;
00369 }
00370 #if NX_POWERSAVE
00371
00372 vif->prevent_sleep |= PS_VIF_MONITOR;
00373 #endif
00374
00375 chan_ctxt_link_monitor(chan_idx);
00376 }
00377 else
00378 #if NX_MON_DATA
00379 {
00380
00381 struct vif_info_tag *vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00382
00383
00384 mm_rx_filter_umac_set(MM_RX_FILTER_MONITOR);
00385
00386
00387 if (vif->chan_ctxt)
00388 {
00389 chan_ctxt_link_monitor(vif->chan_ctxt->idx);
00390 }
00391 }
00392 #else
00393 {
00394
00395 vif_mgmt_env.monitor_vif = INVALID_STA_IDX;
00396
00397 return CO_FAIL;
00398 }
00399 #endif
00400 #endif
00401 } break;
00402
00403 default:
00404 break;
00405 }
00406 #endif //(NX_MULTI_ROLE || NX_BCN_AUTONOMOUS_TX || NX_REORD)
00407
00408 #if (NX_P2P)
00409 if (p2p)
00410 {
00411
00412 vif_mgmt_env.nb_p2p_vifs++;
00413
00414
00415 vif->p2p_index = p2p_create(vif->index,
00416 (vif_type == VIF_STA) ? P2P_ROLE_CLIENT : P2P_ROLE_GO);
00417
00418
00419 ASSERT_ERR(vif->p2p_index != P2P_INVALID_IDX);
00420 }
00421 #endif //(NX_P2P)
00422
00423 #if (NX_TD)
00424 if (vif_type != VIF_MONITOR)
00425
00426 td_start(vif->index);
00427 #endif //(NX_TD)
00428
00429
00430 *vif_idx = vif->index;
00431
00432
00433 co_list_push_back(&vif_mgmt_env.used_list, &vif->list_hdr);
00434
00435 #if NX_MAC_HE
00436
00437 txl_he_tb_config();
00438 #endif
00439
00440
00441 vif_mgmt_set_bssid_mask();
00442
00443 return CO_OK;
00444 }
00445
00446 void vif_mgmt_unregister(uint8_t vif_idx)
00447 {
00448 struct vif_info_tag *vif = &vif_info_tab[vif_idx];
00449
00450
00451 co_list_extract(&vif_mgmt_env.used_list, &vif->list_hdr);
00452
00453 #if NX_MULTI_ROLE
00454
00455 switch (vif->type)
00456 {
00457 case (VIF_STA):
00458 {
00459
00460 vif_mgmt_env.vif_sta_cnt--;
00461 } break;
00462
00463 #if (RW_MESH_EN)
00464 case (VIF_MESH_POINT):
00465 {
00466 vif_mgmt_env.vif_mp_cnt--;
00467 }
00468 #endif //(RW_MESH_EN)
00469 case (VIF_AP):
00470 {
00471
00472 vif_mgmt_env.vif_ap_cnt--;
00473
00474
00475 if (!vif_mgmt_env.vif_ap_cnt)
00476 mm_hw_ap_info_reset();
00477 } break;
00478 case (VIF_MONITOR):
00479 {
00480 #if NX_UF_EN
00481
00482 if (phy_uf_supported())
00483 {
00484
00485 phy_uf_enable(false);
00486 }
00487 #endif
00488
00489 #if (NX_UMAC_PRESENT)
00490 {
00491 struct vif_info_tag *vif = &vif_info_tab[vif_mgmt_env.monitor_vif];
00492
00493 #if NX_POWERSAVE
00494
00495 vif->prevent_sleep &= ~PS_VIF_MONITOR;
00496 #endif
00497
00498 if (vif->chan_ctxt)
00499 {
00500
00501 chan_ctxt_unlink(vif_mgmt_env.monitor_vif);
00502 }
00503
00504 if (vif_mgmt_env.vif_ap_cnt)
00505 {
00506 mm_hw_ap_info_set();
00507 }
00508 else
00509 {
00510 mm_rx_filter_umac_set(MM_RX_FILTER_ACTIVE);
00511 }
00512 }
00513 #endif
00514
00515
00516 vif_mgmt_env.monitor_vif = INVALID_STA_IDX;
00517 } break;
00518
00519 default:
00520 {
00521
00522 } break;
00523 }
00524
00525
00526 if ((vif_mgmt_used_cnt() == 1)
00527 #if (RW_MESH_EN)
00528 && (!vif_mgmt_env.vif_mp_cnt)
00529 #endif
00530 )
00531 {
00532 struct vif_info_tag *vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00533
00534
00535 mm_rx_filter_lmac_enable_clear(NXMAC_ACCEPT_OTHER_BSSID_BIT);
00536
00537
00538 nxmac_bss_id_low_setf(vif->bssid.array[0] | (((uint32_t)vif->bssid.array[1]) << 16));
00539
00540
00541 nxmac_bss_id_high_setf(vif->bssid.array[2]);
00542 }
00543 #endif
00544
00545 #if (NX_MULTI_ROLE || NX_CHNL_CTXT || NX_P2P_GO)
00546
00547 mm_timer_clear(&vif->tbtt_timer);
00548 #endif //(NX_MULTI_ROLE || NX_CHNL_CTXT || NX_P2P_GO)
00549
00550 #if (NX_CHNL_CTXT || NX_P2P)
00551
00552 mm_timer_clear(&vif->tmr_bcn_to);
00553 #endif //(NX_CHNL_CTXT || NX_P2P)
00554
00555 #if (NX_P2P)
00556 if (vif->p2p)
00557 {
00558 p2p_cancel(vif->p2p_index, true);
00559
00560 #if (NX_CHNL_CTXT)
00561
00562 vif_mgmt_env.nb_p2p_vifs--;
00563 #endif //(NX_CHNL_CTXT)
00564 }
00565 #endif //(NX_P2P)
00566
00567 #if (NX_TD)
00568
00569 td_reset(vif->index);
00570 #endif //(NX_TD)
00571
00572 #if NX_MAC_HE
00573
00574 txl_he_tb_config();
00575 #endif
00576
00577
00578 vif_mgmt_set_bssid_mask();
00579
00580
00581 vif_mgmt_entry_init(vif);
00582
00583
00584 co_list_push_back(&vif_mgmt_env.free_list, (struct co_list_hdr*)vif);
00585 }
00586
00587 #if (NX_UMAC_PRESENT)
00588 void vif_mgmt_add_key(struct mm_key_add_req const *param, uint8_t hw_key_idx)
00589 {
00590 struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
00591 struct key_info_tag *key = &vif->key_info[param->key_idx];
00592
00593
00594 key->hw_key_idx = hw_key_idx;
00595 key->cipher = param->cipher_suite;
00596 key->key_idx = param->key_idx;
00597
00598
00599 memset(key->rx_pn, 0, TID_MAX * sizeof(uint64_t));
00600
00601
00602 switch(key->cipher)
00603 {
00604 case MAC_CIPHER_WEP40:
00605 case MAC_CIPHER_WEP104:
00606 key->tx_pn = co_rand_word() & 0xFFFFFF;
00607 break;
00608 case MAC_CIPHER_TKIP:
00609 key->tx_pn = 0;
00610 key->u.mic.tx_key[0] = param->key.array[4];
00611 key->u.mic.tx_key[1] = param->key.array[5];
00612 key->u.mic.rx_key[0] = param->key.array[6];
00613 key->u.mic.rx_key[1] = param->key.array[7];
00614 break;
00615 #if RW_WAPI_EN
00616 case MAC_CIPHER_WPI_SMS4:
00617 key->tx_pn = 0x5c365c365c365c36ULL;
00618 break;
00619 #endif
00620 #if NX_MFP
00621 case MAC_CIPHER_BIP_CMAC_128:
00622 memcpy(key->u.mfp.key, param->key.array, sizeof(key->u.mfp.key));
00623 key->tx_pn = 0;
00624 break;
00625 #endif
00626 default:
00627 key->tx_pn = 0;
00628 break;
00629 }
00630
00631
00632 key->valid = true;
00633
00634 #if NX_MFP
00635 if (key->cipher == MAC_CIPHER_BIP_CMAC_128)
00636 vif->default_mgmt_key = key;
00637 else
00638 #endif
00639
00640 vif->default_key = key;
00641 }
00642
00643 void vif_mgmt_del_key(struct vif_info_tag *vif, uint8_t keyid)
00644 {
00645 int i;
00646 struct key_info_tag *key = &vif->key_info[keyid];
00647
00648
00649 key->valid = false;
00650
00651
00652 if (vif->default_key == key)
00653 {
00654 vif->default_key = NULL;
00655 for (i = 0; i < MAC_DEFAULT_KEY_COUNT; i++)
00656 {
00657 key = &vif->key_info[i];
00658 if (key->valid)
00659 {
00660 vif->default_key = key;
00661 return;
00662 }
00663 }
00664 }
00665 #if NX_MFP
00666 if (vif->default_mgmt_key == key)
00667 {
00668 vif->default_mgmt_key = NULL;
00669 for (i = MAC_DEFAULT_KEY_COUNT; i < MAC_DEFAULT_MFP_KEY_COUNT; i++)
00670 {
00671 key = &vif->key_info[i];
00672 if (key->valid)
00673 {
00674 vif->default_mgmt_key = key;
00675 return;
00676 }
00677 }
00678 }
00679 #endif
00680 }
00681
00682 uint8_t vif_mgmt_get_staid(const struct vif_info_tag *vif, const struct mac_addr *sta_addr)
00683 {
00684 struct co_list_hdr *list_hdr = co_list_pick(&vif->sta_list);
00685
00686
00687 while (list_hdr != NULL)
00688 {
00689 struct sta_info_tag *sta = (struct sta_info_tag *)list_hdr;
00690 if (MAC_ADDR_CMP(&sta->mac_addr, sta_addr))
00691 return sta->staid;
00692 list_hdr = co_list_next(list_hdr);
00693 }
00694 return INVALID_STA_IDX;
00695 }
00696 #endif
00697
00698 #if (NX_TX_FRAME)
00699 void vif_mgmt_send_postponed_frame(struct vif_info_tag *vif)
00700 {
00701
00702 struct sta_info_tag *sta;
00703
00704 #if (NX_UMAC_PRESENT || NX_TD_STA)
00705
00706 sta = (struct sta_info_tag *)co_list_pick(&vif->sta_list);
00707
00708 while (sta != NULL)
00709 {
00710 sta_mgmt_send_postponed_frame(vif, sta, 0);
00711
00712
00713 sta = (struct sta_info_tag *)sta->list_hdr.next;
00714 }
00715 #else
00716
00717 uint8_t cnt;
00718
00719
00720 for (cnt = 0; cnt < STA_MAX; cnt++)
00721 {
00722 sta = &sta_info_tab[cnt];
00723
00724
00725 if (sta->inst_nbr != vif->index)
00726 {
00727
00728 continue;
00729 }
00730
00731 sta_mgmt_send_postponed_frame(vif, sta, 0);
00732 }
00733 #endif //(NX_UMAC_PRESENT || NX_TD_STA)
00734 }
00735 #endif //(NX_TX_FRAME)
00736
00737 #if (NX_CHNL_CTXT || NX_P2P)
00738 void vif_mgmt_bcn_to_prog(struct vif_info_tag *vif)
00739 {
00740 mm_timer_set(&vif->tmr_bcn_to, ke_time() + VIF_MGMT_BCN_TO_DUR);
00741 }
00742
00743 void vif_mgmt_bcn_recv(struct vif_info_tag *vif)
00744 {
00745 do
00746 {
00747 #if (NX_POWERSAVE)
00748
00749 if (!ps_env.ps_on)
00750 {
00751 break;
00752 }
00753
00754
00755 if (ps_env.prevent_sleep & PS_PSM_PAUSED)
00756 {
00757 break;
00758 }
00759
00760
00761 if (vif->prevent_sleep)
00762 {
00763 break;
00764 }
00765 #endif //(NX_POWERSAVE)
00766
00767
00768 mm_timer_clear(&vif->tmr_bcn_to);
00769
00770
00771 vif_mgmt_bcn_to_evt((void *)vif);
00772 } while (0);
00773 }
00774 #endif //(NX_CHNL_CTXT || NX_P2P)
00775
00776 void vif_mgmt_set_ap_bcn_int(struct vif_info_tag *vif, uint16_t bcn_int)
00777 {
00778
00779 uint16_t set_bcn_int = bcn_int;
00780
00781 #if NX_BCN_AUTONOMOUS_TX
00782
00783 vif->u.ap.bcn_int = bcn_int;
00784 #endif
00785
00786 #if (NX_UMAC_PRESENT && NX_BEACONING)
00787
00788 GLOBAL_INT_DISABLE();
00789
00790
00791 if (vif_mgmt_env.vif_ap_cnt > 1)
00792 {
00793 struct vif_info_tag *rd_vif;
00794
00795 uint16_t lowest_bcn_int = vif_info_tab[vif_mgmt_env.low_bcn_int_idx].u.ap.bcn_int;
00796
00797 if (bcn_int < lowest_bcn_int)
00798 {
00799
00800 vif_mgmt_env.low_bcn_int_idx = vif->index;
00801 }
00802 else
00803 {
00804 set_bcn_int = lowest_bcn_int;
00805 }
00806
00807
00808 rd_vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00809
00810 while (rd_vif)
00811 {
00812
00813 uint8_t ratio = (uint8_t)(rd_vif->u.ap.bcn_int / set_bcn_int);
00814
00815
00816 rd_vif->u.ap.bcn_tbtt_ratio = ratio;
00817
00818 rd_vif->u.ap.bcn_tbtt_cnt = 1;
00819
00820
00821 rd_vif = (struct vif_info_tag *)(rd_vif->list_hdr.next);
00822 }
00823 }
00824 else
00825 {
00826
00827 vif_mgmt_env.low_bcn_int_idx = vif->index;
00828
00829 vif->u.ap.bcn_tbtt_ratio = 1;
00830 vif->u.ap.bcn_tbtt_cnt = 1;
00831 }
00832 #endif //(NX_UMAC_PRESENT)
00833
00834
00835 nxmac_beacon_int_setf(set_bcn_int);
00836
00837 #if (NX_UMAC_PRESENT && NX_BEACONING)
00838
00839 GLOBAL_INT_RESTORE();
00840 #endif //(NX_UMAC_PRESENT)
00841 }
00842
00843 #if NX_UMAC_PRESENT
00844 void vif_mgmt_switch_channel(struct vif_info_tag *vif)
00845 {
00846 struct mm_csa_finish_ind *ind = KE_MSG_ALLOC(MM_CSA_FINISH_IND, TASK_API,
00847 TASK_MM, mm_csa_finish_ind);
00848 struct me_bss_info *bss = &vif->bss_info;
00849 struct mac_chan_op *dest = &vif->csa_channel;
00850 uint8_t chan_idx = 0xFF;
00851 uint8_t res;
00852
00853
00854 chan_ctxt_unlink(vif->index);
00855
00856
00857 bss->chan = *dest;
00858 bss->power_constraint = 0;
00859 tpc_update_vif_tx_power(vif);
00860
00861
00862 res = chan_ctxt_add(dest, &chan_idx);
00863 ind->status = res;
00864 ind->chan_idx = chan_idx;
00865
00866 if (vif->type == VIF_STA)
00867 {
00868 vif->u.sta.csa_count = 0;
00869
00870 if (res == CO_OK)
00871 {
00872 struct sta_info_tag *sta = &sta_info_tab[vif->u.sta.ap_id];
00873
00874 chan_ctxt_link(vif->index, chan_idx);
00875
00876
00877
00878 mm_timer_clear(&vif->tmr_bcn_to);
00879 mm_timer_set(&vif->tbtt_timer, ke_time() + sta->bcn_int);
00880 vif->u.sta.beacon_loss_cnt = 0;
00881 vif->u.sta.csa_occured = true;
00882 }
00883 else
00884 {
00885 mm_send_connection_loss_ind(vif);
00886 }
00887 }
00888 #if NX_BCN_AUTONOMOUS_TX // if not defined this function is not called for AP itf
00889 else if (vif->type == VIF_AP)
00890 {
00891 vif->u.ap.csa_count = 0;
00892
00893 if (res == CO_OK)
00894 {
00895 chan_ctxt_link(vif->index, chan_idx);
00896
00897
00898 mm_bcn_env.update_ongoing = true;
00899 }
00900 }
00901 #endif
00902
00903 ke_msg_send(ind);
00904 }
00905 #endif
00906
00907 struct vif_info_tag *vif_mgmt_get_single_sta_vif(void)
00908 {
00909 struct vif_info_tag *vif;
00910
00911 #if NX_MULTI_ROLE
00912 if (vif_mgmt_used_cnt() != 1)
00913 return NULL;
00914 #endif
00915
00916 vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00917
00918 if (vif->type != VIF_STA)
00919 return NULL;
00920
00921 return vif;
00922 }
00923
00924 void vif_mgmt_set_bssid_mask(void)
00925 {
00926 struct vif_info_tag *vif;
00927
00928
00929
00930 nxmac_bss_id_hi_mask_set(0);
00931
00932 #if NX_MULTI_ROLE
00933 if (vif_mgmt_used_cnt() > 1)
00934 return;
00935 #endif
00936
00937 vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00938
00939
00940 if ((vif->type == VIF_STA) && vif->active && vif->u.sta.bssid_index &&
00941 (vif->u.sta.max_bssid_ind <= 8))
00942 nxmac_bss_id_hi_mask_set((CO_BIT(vif->u.sta.max_bssid_ind) - 1) << 8);
00943 }
00944