00001
00013
00014
00015
00016
00017 #include "me_utils.h"
00018 #include "co_math.h"
00019 #include "sta_mgmt.h"
00020 #include "vif_mgmt.h"
00021 #include "mac_ie.h"
00022 #include "hal_desc.h"
00023 #include "mac_frame.h"
00024 #include "me.h"
00025 #include "mm.h"
00026 #include "rc.h"
00027 #include "me_mgmtframe.h"
00028 #include "tpc.h"
00029 #include "txl_cfm.h"
00030 #include "txl_he.h"
00031 #if (RW_BFMER_EN)
00032 #include "bfr.h"
00033 #endif //(RW_BFMER_EN)
00034
00035
00036
00037
00038
00039 #if NX_HE
00041 #define ME_BSS_COLOR_MSK (MAC_HE_OPER_BSS_COLOR_DISABLED_BIT | \
00042 MAC_HE_OPER_BSS_COLOR_PARTIAL_BIT | MAC_HE_OPER_BSS_COLOR_MASK)
00043 #endif
00044
00045
00046
00047
00048
00059 static void me_chan_ctxt_update(struct vif_info_tag *vif)
00060 {
00061 struct me_bss_info *bss = &vif->bss_info;
00062 struct mm_chan_ctxt_update_req *req = KE_MSG_ALLOC(MM_CHAN_CTXT_UPDATE_REQ, TASK_MM,
00063 TASK_ME, mm_chan_ctxt_update_req);
00064
00065
00066
00067 ASSERT_ERR(vif->chan_ctxt != NULL);
00068
00069
00070 req->chan_index = vif->chan_ctxt->idx;
00071 req->chan = bss->chan;
00072
00073
00074 ke_msg_send(req);
00075 }
00076
00077 bool me_set_sta_ht_vht_param(struct sta_info_tag *sta, struct me_bss_info *bss)
00078 {
00079 struct sta_capa_info *info = &sta->info;
00080
00081 uint8_t local_supp_bw = me_env.phy_bw_max;
00082 uint8_t peer_supp_bw = PHY_CHNL_BW_20;
00083 uint8_t local_stbc_nss = me_env.stbc_nss;
00084 uint8_t peer_stbc_nss;
00085 bool smps = false;
00086
00087 #if NX_HE
00088 if (STA_CAPA(sta, HE))
00089 {
00090 uint8_t chan_width_set = HE_PHY_CAPA_VAL_GET(&info->he_cap, CHAN_WIDTH_SET);
00091 bool stbc_rx_under_80 = HE_PHY_CAPA_BIT_IS_SET(&info->he_cap, STBC_RX_UNDER_80MHZ);
00092 bool stbc_rx_above_80 = HE_PHY_CAPA_BIT_IS_SET(&info->he_cap, STBC_RX_ABOVE_80MHZ);
00093
00094
00095 if (chan_width_set & HE_PHY_CAPA_CHAN_WIDTH_SET_80PLUS80_MHZ_IN_5G)
00096 peer_supp_bw = PHY_CHNL_BW_80P80;
00097 else if (chan_width_set & HE_PHY_CAPA_CHAN_WIDTH_SET_160MHZ_IN_5G)
00098 peer_supp_bw = PHY_CHNL_BW_160;
00099 else if (chan_width_set & HE_PHY_CAPA_CHAN_WIDTH_SET_40MHZ_80MHZ_IN_5G)
00100 peer_supp_bw = PHY_CHNL_BW_80;
00101 else if (chan_width_set & HE_PHY_CAPA_CHAN_WIDTH_SET_40MHZ_IN_2G)
00102 peer_supp_bw = PHY_CHNL_BW_40;
00103
00104 if (peer_supp_bw > PHY_CHNL_BW_80)
00105 peer_stbc_nss = stbc_rx_under_80 & stbc_rx_above_80 ? 1 : 0;
00106 else
00107 peer_stbc_nss = stbc_rx_under_80 ? 1 : 0;
00108
00109 local_stbc_nss = me_env.he_stbc_nss;
00110 }
00111 else
00112 #endif
00113 #if NX_VHT
00114 if (STA_CAPA(sta, VHT))
00115 {
00116
00117 switch (info->vht_cap.vht_capa_info & MAC_VHTCAPA_SUPP_CHAN_WIDTH_MSK)
00118 {
00119 case MAC_VHTCAPA_SUPP_CHAN_WIDTH_160:
00120 peer_supp_bw = PHY_CHNL_BW_160;
00121 break;
00122 case MAC_VHTCAPA_SUPP_CHAN_WIDTH_160_80P80:
00123 peer_supp_bw = PHY_CHNL_BW_80P80;
00124 break;
00125 default:
00126 peer_supp_bw = PHY_CHNL_BW_80;
00127 break;
00128 }
00129 peer_stbc_nss = (info->vht_cap.vht_capa_info & MAC_VHTCAPA_RXSTBC_MSK) >>
00130 MAC_VHTCAPA_RXSTBC_OFT;
00131 peer_stbc_nss = (peer_stbc_nss <= 4) ? peer_stbc_nss : 0;
00132 }
00133 else
00134 #endif
00135 {
00136 peer_stbc_nss = (info->ht_cap.ht_capa_info & MAC_HTCAPA_RX_STBC_MSK) >>
00137 MAC_HTCAPA_RX_STBC_OFT;
00138
00139 if (info->ht_cap.ht_capa_info & MAC_HTCAPA_40_MHZ)
00140 peer_supp_bw = PHY_CHNL_BW_40;
00141 }
00142
00143 info->phy_bw_max = co_min(peer_supp_bw, local_supp_bw);
00144 info->bw_cur = me_phy2mac_bw(me_get_sta_bw(info->phy_bw_max, bss->chan.type));
00145 info->stbc_nss = co_min(peer_stbc_nss, local_stbc_nss);
00146
00147 if ((info->ht_cap.ht_capa_info & MAC_HTCAPA_SMPS_MSK) !=
00148 MAC_HTCAPA_SMPS_DISABLE)
00149 smps = true;
00150
00151 return (smps);
00152 }
00153
00154 uint8_t me_11ac_mcs_max(uint16_t mcs_map)
00155 {
00156 uint8_t mcs_max;
00157
00158 switch (mcs_map & MAC_VHT_MCS_MAP_MSK)
00159 {
00160 case MAC_VHT_MCS_MAP_0_7:
00161 mcs_max = 7;
00162 break;
00163 case MAC_VHT_MCS_MAP_0_8:
00164 mcs_max = 8;
00165 break;
00166 case MAC_VHT_MCS_MAP_0_9:
00167 mcs_max = 9;
00168 break;
00169 default:
00170 mcs_max = 7;
00171 break;
00172 }
00173
00174 return(mcs_max);
00175 }
00176
00177 uint8_t me_11ax_mcs_max(uint16_t mcs_map)
00178 {
00179 uint8_t mcs_max;
00180
00181 switch (mcs_map & MAC_HE_MCS_MAP_MSK)
00182 {
00183 case MAC_HE_MCS_MAP_0_7:
00184 mcs_max = 7;
00185 break;
00186 case MAC_HE_MCS_MAP_0_9:
00187 mcs_max = 9;
00188 break;
00189 case MAC_HE_MCS_MAP_0_11:
00190 mcs_max = 11;
00191 break;
00192 default:
00193 mcs_max = 7;
00194 break;
00195 }
00196
00197 return(mcs_max);
00198 }
00199
00200 uint8_t me_11ac_nss_max(uint16_t mcs_map)
00201 {
00202 uint8_t nss_max;
00203
00204
00205 for (nss_max = 7; nss_max > 0; nss_max--)
00206 {
00207 if (((mcs_map >> (2 * nss_max)) & MAC_VHT_MCS_MAP_MSK) != MAC_VHT_MCS_MAP_NONE)
00208 break;
00209 }
00210
00211 return(nss_max);
00212 }
00213
00214 uint8_t me_11n_nss_max(uint8_t *mcs_set)
00215 {
00216 uint8_t nss_max;
00217
00218
00219 for (nss_max = 3; nss_max > 0; nss_max--)
00220 {
00221 if (mcs_set[nss_max] != 0)
00222 break;
00223 }
00224
00225 return(nss_max);
00226 }
00227
00228 uint8_t me_legacy_ridx_min(uint16_t rate_map)
00229 {
00230 uint8_t i;
00231
00232 for (i = 0; i < MAC_RATESET_LEN; i++)
00233 {
00234 if (rate_map & (1 << i))
00235 {
00236 break;
00237 }
00238 }
00239
00240 return i;
00241 }
00242
00243 uint8_t me_legacy_ridx_max(uint16_t rate_map)
00244 {
00245 uint8_t i;
00246 uint8_t mcs_max;
00247
00248 if (rate_map != 0 )
00249 {
00250 for (i = 0; i < MAC_RATESET_LEN; i++)
00251 {
00252 if (rate_map & (1 << (HW_RATE_54MBPS - i)))
00253 {
00254 break;
00255 }
00256 }
00257 mcs_max = HW_RATE_54MBPS - i;
00258 }
00259 else
00260 {
00261 mcs_max = MAC_RATESET_LEN;
00262 }
00263
00264 return mcs_max;
00265 }
00266
00267 void me_get_ampdu_params(struct mac_htcapability const *ht_cap,
00268 struct mac_vhtcapability const *vht_cap,
00269 struct mac_hecapability const *he_cap,
00270 uint16_t *ampdu_size_max_ht,
00271 uint32_t *ampdu_size_max_vht,
00272 uint32_t *ampdu_size_max_he,
00273 uint8_t *ampdu_spacing_min)
00274 {
00275 *ampdu_size_max_ht = 0;
00276 *ampdu_size_max_vht = 0;
00277 *ampdu_size_max_he = 0;
00278
00279 if (ht_cap)
00280 {
00281 #if NX_VHT
00282 int vht_exp = 0;
00283 #endif
00284 int ht_exp = (ht_cap->a_mpdu_param & MAC_AMPDU_LEN_EXP_MSK) >>
00285 MAC_AMPDU_LEN_EXP_OFT;
00286 int min_spc = (ht_cap->a_mpdu_param & MAC_AMPDU_MIN_SPACING_MSK) >>
00287 MAC_AMPDU_MIN_SPACING_OFT;
00288 *ampdu_spacing_min = (min_spc < 3)?1:(0x01 << (min_spc - 3));
00289 *ampdu_size_max_ht = (1 << (MAC_HT_MAX_AMPDU_FACTOR + ht_exp)) - 1;
00290
00291 #if NX_VHT
00292 if (vht_cap)
00293 {
00294 vht_exp = (vht_cap->vht_capa_info & MAC_VHTCAPA_MAX_A_MPDU_LENGTH_EXP_MSK) >>
00295 MAC_VHTCAPA_MAX_A_MPDU_LENGTH_EXP_OFT;
00296 *ampdu_size_max_vht = (1 << (MAC_HT_MAX_AMPDU_FACTOR + vht_exp)) - 1;
00297 }
00298 #endif
00299
00300 #if NX_HE
00301 if (he_cap)
00302 {
00303 int he_exp_ext = HE_MAC_CAPA_VAL_GET(he_cap, MAX_A_AMPDU_LEN_EXP);
00304 if (vht_cap)
00305 {
00306 if (vht_exp == 7)
00307 *ampdu_size_max_he = (1 << (MAC_HT_MAX_AMPDU_FACTOR
00308 + 7 + he_exp_ext)) - 1;
00309 else
00310 *ampdu_size_max_he = *ampdu_size_max_vht;
00311 }
00312 else
00313 {
00314 if (ht_exp == 3)
00315 *ampdu_size_max_he = (1 << (MAC_HT_MAX_AMPDU_FACTOR
00316 + 3 + he_exp_ext)) - 1;
00317 else
00318 *ampdu_size_max_he = *ampdu_size_max_ht;
00319 }
00320 }
00321 #endif
00322 }
00323 }
00324
00333 static void me_erp_prot_check(uint32_t erp_addr, uint16_t *prot_status)
00334 {
00335
00336
00337
00338
00339
00340
00341 uint8_t erp_val = co_read8p(erp_addr + MAC_ERP_PARAM_OFT);
00342
00343
00344 *prot_status &= ~MAC_PROT_ERP_STATUS_MASK;
00345
00346 if (erp_val & MAC_ERP_NON_ERP_PRESENT)
00347 {
00348
00349 *prot_status |= MAC_PROT_NONERP_PRESENT_BIT;
00350 }
00351
00352 if (erp_val & MAC_ERP_USE_PROTECTION)
00353 {
00354
00355 *prot_status |= MAC_PROT_USE_PROTECTION_BIT;
00356 }
00357
00358 if (erp_val & MAC_ERP_BARKER_PREAMBLE_MODE)
00359 {
00360
00361 *prot_status |= MAC_PROT_BARKER_PREAMB_BIT;
00362 }
00363 }
00364
00373 static void me_pol_tbl_prot_upd(struct sta_info_tag *sta, uint16_t prot_status)
00374 {
00375
00376 struct sta_pol_tbl_cntl *pol_tbl = &sta->pol_tbl;
00377
00378 struct vif_info_tag *vif;
00379
00380
00381 pol_tbl->prot_cfg = 0;
00382
00383
00384 pol_tbl->upd_field |= CO_BIT(STA_MGMT_POL_UPD_PROT);
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 if (prot_status & MAC_PROT_USE_PROTECTION_BIT)
00395 {
00396
00397 pol_tbl->prot_cfg |= PROT_SELF_CTS;
00398
00399
00400 vif = &vif_info_tab[sta->inst_nbr];
00401
00402
00403 pol_tbl->prot_cfg |= ((vif->bss_info.high_11b_rate) << MCS_INDEX_PROT_TX_RCX_OFT);
00404 }
00405
00406
00407 pol_tbl->ppdu_tx_cfg = 0;
00408
00409
00410
00411
00412
00413
00414 if (!(prot_status & MAC_PROT_BARKER_PREAMB_BIT))
00415 {
00416 pol_tbl->ppdu_tx_cfg |= PRE_TYPE_TX_RCX_MASK;
00417 }
00418
00419 rc_update_preamble_type(sta->staid, (pol_tbl->ppdu_tx_cfg > 0));
00420 }
00421
00430 static void me_pol_tbl_bw_upd(struct sta_info_tag *sta, uint8_t new_phy_bw)
00431 {
00432
00433 struct sta_pol_tbl_cntl *pol_tbl = &sta->pol_tbl;
00434 uint8_t new_bw = me_phy2mac_bw(me_get_sta_bw(sta->info.phy_bw_max, new_phy_bw));
00435
00436
00437 if (new_bw != sta->info.bw_cur)
00438 {
00439 struct sta_capa_info *info = &sta->info;
00440 uint8_t local_supp_nss = 0;
00441 uint8_t peer_supp_nss = 0;
00442 uint8_t nss;
00443
00444 #if NX_HE
00445 if (STA_CAPA(sta, HE))
00446 {
00447 ASSERT_ERR(LOCAL_CAPA(HE));
00448
00449
00450 peer_supp_nss = me_11ac_nss_max(info->he_cap.mcs_supp.rx_mcs_80);
00451 local_supp_nss = me_11ac_nss_max(me_env.he_cap.mcs_supp.tx_mcs_80);
00452
00453 nss = co_min(local_supp_nss, peer_supp_nss);
00454 }
00455 else
00456 #endif
00457 #if NX_VHT
00458 if (STA_CAPA(sta, VHT))
00459 {
00460 ASSERT_ERR(LOCAL_CAPA(VHT));
00461
00462
00463 peer_supp_nss = me_11ac_nss_max(info->vht_cap.rx_mcs_map);
00464 local_supp_nss = me_11ac_nss_max(me_env.vht_cap.tx_mcs_map);
00465
00466 nss = co_min(local_supp_nss, peer_supp_nss);
00467 }
00468 else
00469 #endif
00470 {
00471 ASSERT_ERR(LOCAL_CAPA(HT));
00472
00473 peer_supp_nss = me_11n_nss_max(info->ht_cap.mcs_rate);
00474 local_supp_nss = me_11n_nss_max(me_env.ht_cap.mcs_rate);
00475
00476 nss = co_min(local_supp_nss, peer_supp_nss);
00477 }
00478
00479 sta->info.bw_cur = new_bw;
00480
00481
00482 rc_update_bw_nss_max(sta->staid, sta->info.bw_cur, nss);
00483
00484
00485 pol_tbl->upd_field |= CO_BIT(STA_MGMT_POL_UPD_BW);
00486 }
00487 }
00488
00489 #if NX_HE
00490
00499 static void me_pol_tbl_bss_color_upd(struct sta_info_tag *sta)
00500 {
00501 if (STA_CAPA(sta, HE))
00502 {
00503 struct sta_pol_tbl_cntl *pol_tbl = &sta->pol_tbl;
00504 pol_tbl->upd_field |= CO_BIT(STA_MGMT_POL_UPD_BSS_COLOR);
00505 }
00506 }
00507 #endif
00508
00517 uint8_t me_rate_translate(uint8_t rate)
00518 {
00519 uint8_t hwrate = 0;
00520
00521 rate &= ~MAC_BASIC_RATE;
00522 switch(rate)
00523 {
00524 case MAC_RATE_1MBPS:
00525 hwrate = HW_RATE_1MBPS;
00526 break;
00527 case MAC_RATE_2MBPS:
00528 hwrate = HW_RATE_2MBPS;
00529 break;
00530 case MAC_RATE_5_5MBPS:
00531 hwrate = HW_RATE_5_5MBPS;
00532 break;
00533 case MAC_RATE_11MBPS:
00534 hwrate = HW_RATE_11MBPS;
00535 break;
00536 case MAC_RATE_48MBPS:
00537 hwrate = HW_RATE_48MBPS;
00538 break;
00539 case MAC_RATE_24MBPS:
00540 hwrate = HW_RATE_24MBPS;
00541 break;
00542 case MAC_RATE_12MBPS:
00543 hwrate = HW_RATE_12MBPS;
00544 break;
00545 case MAC_RATE_6MBPS:
00546 hwrate = HW_RATE_6MBPS;
00547 break;
00548 case MAC_RATE_54MBPS:
00549 hwrate = HW_RATE_54MBPS;
00550 break;
00551 case MAC_RATE_36MBPS:
00552 hwrate = HW_RATE_36MBPS;
00553 break;
00554 case MAC_RATE_18MBPS:
00555 hwrate = HW_RATE_18MBPS;
00556 break;
00557 case MAC_RATE_9MBPS:
00558 hwrate = HW_RATE_9MBPS;
00559 break;
00560 default:
00561 hwrate = 0xFF;
00562 }
00563 return(hwrate);
00564 }
00565
00566 uint16_t me_legacy_rate_bitfield_build(struct mac_rateset const *rateset, bool basic_only)
00567 {
00568 int i;
00569 uint16_t rates = 0;
00570
00571
00572 for (i = 0; i < rateset->length; i++)
00573 {
00574
00575 if (basic_only && !(rateset->array[i] & MAC_BASIC_RATE))
00576 continue;
00577
00578
00579 int bit_pos = me_rate_translate(rateset->array[i]);
00580
00581
00582 ASSERT_WARN(bit_pos < MAC_RATESET_LEN);
00583
00584
00585 if (bit_pos < MAC_RATESET_LEN)
00586 {
00587 rates |= CO_BIT(bit_pos);
00588 }
00589 }
00590
00591 return (rates);
00592 }
00593
00594 uint16_t me_rate_bitfield_vht_build(uint16_t mcs_map_1, uint16_t mcs_map_2)
00595 {
00596 uint8_t i;
00597 uint16_t mcs_map = 0xFFFF;
00598
00599 for (i = 0; i < 8; i++)
00600 {
00601 uint8_t mcs_cfg_1 = (mcs_map_1 >> (i << 1)) & MAC_VHT_MCS_MAP_MSK;
00602 uint8_t mcs_cfg_2 = (mcs_map_2 >> (i << 1)) & MAC_VHT_MCS_MAP_MSK;
00603 if ((mcs_cfg_1 == MAC_VHT_MCS_MAP_NONE) || (mcs_cfg_2 == MAC_VHT_MCS_MAP_NONE))
00604 {
00605 break;
00606 }
00607 else
00608 {
00609 mcs_map &= ~(MAC_VHT_MCS_MAP_MSK << (i << 1));
00610 mcs_map |= (co_min(mcs_cfg_1, mcs_cfg_2) & MAC_VHT_MCS_MAP_MSK) << (i << 1);
00611 }
00612 }
00613
00614 return mcs_map;
00615 }
00616
00617 uint16_t me_build_capability(uint8_t vif_idx)
00618 {
00619 uint16_t capa_info = 0;
00620 struct vif_info_tag *vif = &vif_info_tab[vif_idx];
00621
00622 capa_info |= MAC_CAPA_ESS;
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 capa_info &= ~MAC_CAPA_PRIVA;
00635
00636
00637 capa_info |= MAC_CAPA_SHORT_PREAMBLE;
00638
00639 capa_info |= MAC_CAPA_SHORT_SLOT;
00640
00641
00642
00643
00644 if (vif->bss_info.chan.band == PHY_BAND_5G)
00645 capa_info |= MAC_CAPA_SPECTRUM;
00646
00647
00648
00649
00650
00651 return capa_info;
00652 }
00653
00654 #if NX_HE
00655 uint32_t me_build_bss_color_reg(struct me_bss_info *bss)
00656 {
00657 uint32_t bss_color = bss->he_oper & MAC_HE_OPER_BSS_COLOR_MASK;
00658
00659
00660 bss_color = bss->he_oper & MAC_HE_OPER_BSS_COLOR_MASK;
00661 bss_color >>= MAC_HE_OPER_BSS_COLOR_OFT;
00662 bss_color <<= NXMAC_BSS_COLOR_LSB;
00663 bss_color |= NXMAC_BSS_COLOR_EN_BIT;
00664 if (!(bss->he_oper & MAC_HE_OPER_BSS_COLOR_DISABLED_BIT))
00665 bss_color |= NXMAC_BSS_COLOR_EN_BIT;
00666 if (bss->he_oper & MAC_HE_OPER_BSS_COLOR_PARTIAL_BIT)
00667 bss_color |= NXMAC_PARTIAL_BSS_COLOR_EN_BIT;
00668
00669 return bss_color;
00670 }
00671 #endif
00672
00673 void me_init_rate(struct sta_info_tag *sta)
00674 {
00675 rc_init(sta);
00676 me_update_buffer_control(sta);
00677 }
00678
00679
00680 void me_init_bcmc_rate(struct sta_info_tag *sta)
00681 {
00682 struct sta_pol_tbl_cntl *rc = &sta->pol_tbl;
00683 struct mac_rateset *rates = &sta->info.rate_set;
00684 uint8_t max_rate = 0;
00685 int i;
00686
00687 ASSERT_ERR(rates->length != 0);
00688 for (i = 0; i < rates->length; i++)
00689 {
00690 if ((rates->array[i] & ~MAC_BASIC_RATE) > max_rate)
00691 max_rate = rates->array[i] & ~MAC_BASIC_RATE;
00692 }
00693
00694 rc_init_bcmc_rate(sta, me_rate_translate(max_rate));
00695
00696 rc->upd_field = 0;
00697 }
00698
00699
00700 struct txl_buffer_control *me_update_buffer_control(struct sta_info_tag *sta)
00701 {
00702
00703 struct sta_pol_tbl_cntl *pol_tbl = &sta->pol_tbl;
00704 struct txl_buffer_control *buf_ctrl = pol_tbl->buf_ctrl;
00705
00706
00707 if (pol_tbl->upd_field)
00708 {
00709 int i;
00710 uint8_t stbc_nss = 0;
00711 uint8_t sta_stbc_nss = 0;
00712 int use_stbc = 0;
00713
00714 struct tx_policy_tbl *pol = &buf_ctrl->policy_tbl;
00715
00716 uint32_t rate_info[RATE_CONTROL_STEPS];
00717
00718 uint32_t pwr_info[RATE_CONTROL_STEPS];
00719
00720 uint32_t phycntrlinfo1, phycntrlinfo2;
00721
00722 uint32_t trial_rate;
00723 #if NX_HE
00724
00725 bool can_use_htc = (buf_ctrl->tx_flags & TX_SWDESC_UMAC_HTC_BIT) != 0;
00726 #else
00727 bool can_use_htc = false;
00728 #endif
00729 #if RW_BFMER_EN
00730
00731 bool can_use_bfm = (buf_ctrl->tx_flags & TX_SWDESC_UMAC_BEAMFORM_BIT) != 0;
00732
00733 uint8_t nc = bfr_get_last_nc(sta->staid);
00734
00735 uint8_t ntx = phy_get_ntx();
00736 can_use_bfm = (nc != BFR_INVALID_NC);
00737 #else
00738 bool can_use_bfm = false;
00739 uint8_t nc = 0, ntx = 0;
00740 #endif //(RW_BFMER_EN)
00741
00742
00743 phycntrlinfo1 = pol->phycntrlinfo1;
00744 phycntrlinfo2 = pol->phycntrlinfo2;
00745 for (i = 0; i < RATE_CONTROL_STEPS; i++)
00746 {
00747 rate_info[i] = pol->ratecntrlinfo[i];
00748 pwr_info[i] = pol->powercntrlinfo[i];
00749 }
00750
00751
00752 if (pol_tbl->upd_field & CO_BIT(STA_MGMT_POL_UPD_RATE))
00753 {
00754 PROF_RC_UPD_RETRY_CHAIN_SET();
00755
00756 struct rc_sta_stats *rc_ss = pol_tbl->sta_stats;
00757 sta_stbc_nss = sta->info.stbc_nss;
00758 #if NX_HE
00759 can_use_htc = true;
00760 #endif
00761 for (i = 0; i < RATE_CONTROL_STEPS; i++)
00762 {
00763 uint8_t nss = 0;
00764 uint16_t idx = rc_ss->retry_step_idx[i];
00765 uint32_t new_rate_info = (RC_MAX_NUM_RETRY << N_RETRY_RCX_OFT) |
00766 (rc_ss->rate_stats[idx].rate_config &
00767 (MCS_INDEX_TX_RCX_MASK | BW_TX_RCX_MASK |
00768 SHORT_GI_TX_RCX_MASK | PRE_TYPE_TX_RCX_MASK |
00769 FORMAT_MOD_TX_RCX_MASK));
00770 uint32_t format = (new_rate_info & FORMAT_MOD_TX_RCX_MASK) >>
00771 FORMAT_MOD_TX_RCX_OFT;
00772
00773
00774 if (format >= FORMATMOD_HT_MF)
00775 {
00776 uint32_t mcs_idx = (new_rate_info & MCS_INDEX_TX_RCX_MASK)
00777 >> MCS_INDEX_TX_RCX_OFT;
00778 #if NX_VHT
00779 if (format == FORMATMOD_VHT)
00780 {
00781
00782 nss = (mcs_idx & VHT_NSS_MASK) >> VHT_NSS_OFT;
00783 }
00784 else
00785 #endif
00786 #if NX_HE
00787 if (format == FORMATMOD_HE_SU)
00788 {
00789
00790 nss = (mcs_idx & VHT_NSS_MASK) >> VHT_NSS_OFT;
00791
00792
00793 txl_he_ltf_type_set(new_rate_info, &pwr_info[i]);
00794 }
00795 else
00796 #endif
00797 {
00798
00799 nss = (mcs_idx & HT_NSS_MASK) >> HT_NSS_OFT;
00800 }
00801
00802
00803 if (i == 0)
00804 {
00805 if (nss < sta_stbc_nss)
00806 {
00807 stbc_nss = nss;
00808 use_stbc = 1;
00809 }
00810 }
00811 else if (use_stbc && (nss != stbc_nss))
00812 {
00813 use_stbc = 0;
00814 }
00815 }
00816
00817
00818 rate_info[i] &= ~(N_RETRY_RCX_MASK | MCS_INDEX_TX_RCX_MASK |
00819 BW_TX_RCX_MASK | SHORT_GI_TX_RCX_MASK |
00820 PRE_TYPE_TX_RCX_MASK | FORMAT_MOD_TX_RCX_MASK);
00821
00822 rate_info[i] |= new_rate_info;
00823
00824
00825 #if RW_BFMER_EN
00826 if (can_use_bfm)
00827 {
00828 if ((format != FORMATMOD_VHT) || (nss > nc) || (nss == ntx))
00829 {
00830 can_use_bfm = false;
00831 }
00832 }
00833 #endif //(RW_BFMER_EN)
00834 #if NX_HE
00835 if (can_use_htc)
00836 {
00837 if (format < FORMATMOD_HT_MF)
00838 {
00839 can_use_htc = false;
00840 }
00841 }
00842 #endif
00843 }
00844
00845
00846 phycntrlinfo1 &= ~STBC_PT_MASK;
00847 if (use_stbc)
00848 {
00849 phycntrlinfo1 |= (stbc_nss + 1) << STBC_PT_OFT;
00850 }
00851
00852 #if RW_BFMER_EN
00853
00854 if (can_use_bfm)
00855 buf_ctrl->tx_flags |= TX_SWDESC_UMAC_BEAMFORM_BIT;
00856 else
00857 buf_ctrl->tx_flags &= ~TX_SWDESC_UMAC_BEAMFORM_BIT;
00858 #endif
00859 #if NX_HE
00860 if (can_use_htc)
00861 buf_ctrl->tx_flags |= TX_SWDESC_UMAC_HTC_BIT;
00862 else
00863 buf_ctrl->tx_flags &= ~TX_SWDESC_UMAC_HTC_BIT;
00864 #endif
00865
00866
00867
00868
00869 pol_tbl->upd_field |= CO_BIT(STA_MGMT_POL_UPD_PROT);
00870 PROF_RC_UPD_RETRY_CHAIN_CLR();
00871 }
00872
00873
00874 if (pol_tbl->upd_field & CO_BIT(STA_MGMT_POL_TRIAL_RATE))
00875 {
00876 PROF_RC_UPD_RETRY_CHAIN_TRIAL_SET();
00877
00878 struct rc_sta_stats *rc_ss = pol_tbl->sta_stats;
00879 uint8_t idx = rc_ss->trial_idx;
00880 uint32_t new_rate_info = (RC_MAX_NUM_RETRY << N_RETRY_RCX_OFT) |
00881 (rc_ss->rate_stats[idx].rate_config &
00882 (MCS_INDEX_TX_RCX_MASK | BW_TX_RCX_MASK |
00883 SHORT_GI_TX_RCX_MASK | PRE_TYPE_TX_RCX_MASK |
00884 FORMAT_MOD_TX_RCX_MASK));
00885
00886
00887 trial_rate = pol->ratecntrlinfo[0];
00888 trial_rate &= ~(N_RETRY_RCX_MASK | MCS_INDEX_TX_RCX_MASK |
00889 BW_TX_RCX_MASK | SHORT_GI_TX_RCX_MASK |
00890 PRE_TYPE_TX_RCX_MASK | FORMAT_MOD_TX_RCX_MASK);
00891
00892
00893 rc_ss->trial_rate = trial_rate | new_rate_info;
00894
00895 use_stbc = (phycntrlinfo1 & STBC_PT_MASK) != 0;
00896 stbc_nss = ((phycntrlinfo1 & STBC_PT_MASK) >> STBC_PT_OFT) - 1;
00897
00898
00899 rc_trial_check_bfm_stbc_htc(buf_ctrl, rc_ss->trial_rate,
00900 can_use_bfm, use_stbc, stbc_nss, nc, ntx,
00901 can_use_htc);
00902
00903 PROF_RC_UPD_RETRY_CHAIN_TRIAL_CLR();
00904 }
00905
00906 if (pol_tbl->upd_field & CO_BIT(STA_MGMT_POL_UPD_PROT))
00907 {
00908 for (i = 0; i < RATE_CONTROL_STEPS; i++)
00909 {
00910 uint8_t format = (rate_info[i] & FORMAT_MOD_TX_RCX_MASK) >>
00911 FORMAT_MOD_TX_RCX_OFT;
00912 uint8_t rate = (rate_info[i] & MCS_INDEX_TX_RCX_MASK) >>
00913 MCS_INDEX_TX_RCX_OFT;
00914
00915 if ((format >= FORMATMOD_NON_HT_DUP_OFDM) || (rate >= HW_RATE_6MBPS))
00916 {
00917
00918 rate_info[i] &= ~STA_MGMT_PROT_HW_MASK;
00919
00920
00921 rate_info[i] |= pol_tbl->prot_cfg;
00922 }
00923 }
00924 }
00925
00926
00927 if (pol_tbl->upd_field & CO_BIT(STA_MGMT_POL_UPD_TX_POWER))
00928 {
00929 struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
00930 uint8_t idx;
00931
00932 tpc_get_vif_tx_power(vif, NULL, &idx);
00933 for (i = 0; i < RATE_CONTROL_STEPS; i++)
00934 {
00935 pwr_info[i] &= ~TX_PWR_LEVEL_MASK;
00936 pwr_info[i] |= TX_PWR_LEVEL_SET(idx);
00937 }
00938 }
00939
00940 #if NX_HE
00941
00942 if (pol_tbl->upd_field & CO_BIT(STA_MGMT_POL_UPD_BSS_COLOR))
00943 {
00944 struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
00945 struct me_bss_info *bss = &vif->bss_info;
00946 uint8_t color = 0;
00947
00948 phycntrlinfo2 &= ~BSS_COLOR_MASK;
00949 if (!(bss->he_oper & MAC_HE_OPER_BSS_COLOR_DISABLED_BIT))
00950 color = (bss->he_oper & MAC_HE_OPER_BSS_COLOR_MASK) >>
00951 MAC_HE_OPER_BSS_COLOR_OFT;
00952 phycntrlinfo2 |= (color << BSS_COLOR_OFT);
00953 }
00954 #endif
00955
00956
00957
00958 GLOBAL_INT_DISABLE();
00959 pol->phycntrlinfo1 = phycntrlinfo1;
00960 pol->phycntrlinfo2 = phycntrlinfo2;
00961 for (i = 0; i < RATE_CONTROL_STEPS; i++)
00962 {
00963 pol->ratecntrlinfo[i] = rate_info[i];
00964 pol->powercntrlinfo[i] = pwr_info[i];
00965 }
00966 GLOBAL_INT_RESTORE();
00967
00968
00969 pol_tbl->upd_field = 0;
00970 }
00971
00972 return (buf_ctrl);
00973 }
00974
00975 void me_bw_check(uint32_t ht_op_addr, uint32_t vht_op_addr, struct me_bss_info *bss)
00976 {
00977 struct mac_chan_op *chan = &bss->chan;
00978
00979
00980 chan->type = PHY_CHNL_BW_20;
00981 chan->center1_freq = bss->chan.prim20_freq;
00982 chan->center2_freq = 0;
00983
00984
00985 if ((ht_op_addr != 0) && (me_env.phy_bw_max >= PHY_CHNL_BW_40))
00986 {
00987 uint8_t sec_ch_oft = co_read8p(ht_op_addr + MAC_HT_OPER_PRIM_CH_OFT + 1) & 3;
00988 if (sec_ch_oft != 0)
00989 {
00990
00991 int8_t freq_offset = (sec_ch_oft == 1) ? 10 : -10;
00992 chan->center1_freq += freq_offset;
00993 chan->type = PHY_CHNL_BW_40;
00994 }
00995 }
00996
00997
00998 #if NX_VHT
00999 if ((vht_op_addr != 0) && (me_env.phy_bw_max >= PHY_CHNL_BW_80))
01000 {
01001 uint8_t chan_width = co_read8p(vht_op_addr + MAC_VHT_CHAN_WIDTH_OFT) & 3;
01002 uint8_t center0 = co_read8p(vht_op_addr + MAC_VHT_CENTER_FREQ0_OFT);
01003 uint8_t center1 = co_read8p(vht_op_addr + MAC_VHT_CENTER_FREQ1_OFT);
01004 me_vht_bandwidth_parse(chan_width, center0, center1, chan);
01005 }
01006 #endif
01007 }
01008
01009 void me_beacon_check(uint8_t vif_idx, uint16_t length, uint32_t bcn_addr)
01010 {
01011
01012 uint32_t addr, ht_op_addr = 0, vht_op_addr = 0;
01013
01014 struct vif_info_tag *vif = &vif_info_tab[vif_idx];
01015 struct sta_info_tag *sta = (struct sta_info_tag *)co_list_pick(&vif->sta_list);
01016 struct me_bss_info *bss = &vif->bss_info;
01017
01018 uint16_t cur_prot_status = bss->prot_status;
01019 uint8_t cur_phy_bw = bss->chan.type;
01020 uint8_t cur_pwr_const = bss->power_constraint;
01021 #if NX_HE
01022 uint32_t cur_bss_color = bss->he_oper & ME_BSS_COLOR_MSK;
01023 #endif
01024 uint8_t csa_count, csa_mode;
01025 uint32_t var_part_addr = bcn_addr + MAC_BEACON_VARIABLE_PART_OFT;
01026 uint32_t var_part_len = length - MAC_BEACON_VARIABLE_PART_OFT;
01027
01028
01029 bss->prot_status = 0;
01030
01031
01032
01033
01034
01035
01036 if (bss->chan.band == PHY_BAND_2G4)
01037 {
01038 addr = mac_ie_erp_find(var_part_addr, var_part_len);
01039
01040 if (addr)
01041 {
01042 me_erp_prot_check(addr, &bss->prot_status);
01043 }
01044 }
01045
01046
01047
01048
01049
01050
01051 if (BSS_CAPA(bss, QOS) && (vif->type == VIF_STA))
01052 {
01053 bool changed;
01054
01055
01056 me_extract_edca_params(var_part_addr, var_part_len, &bss->edca_param, &changed);
01057
01058 if (changed)
01059 {
01060
01061 for (int i = 0; i < AC_MAX; i++)
01062 {
01063 struct mm_set_edca_req *edca = KE_MSG_ALLOC(MM_SET_EDCA_REQ, TASK_MM,
01064 TASK_ME, mm_set_edca_req);
01065 #if NX_UAPSD
01066 bool uapsd = (vif->u.sta.uapsd_queues & ~CO_BIT(i)) != 0;
01067 #else
01068 bool uapsd = false;
01069 #endif
01070
01071 edca->ac_param = bss->edca_param.ac_param[i];
01072 edca->hw_queue = i;
01073 edca->inst_nbr = vif->index;
01074 edca->uapsd = uapsd;
01075
01076 ke_msg_send(edca);
01077 }
01078 }
01079 }
01080
01081
01082
01083
01084
01085
01086
01087 if (LOCAL_CAPA(HT))
01088 {
01089 ht_op_addr = mac_ie_ht_oper_find(var_part_addr, var_part_len);
01090
01091 #if NX_VHT || NX_HE
01092
01093
01094
01095
01096
01097
01098 if (LOCAL_CAPA(VHT) || LOCAL_CAPA(HE))
01099 {
01100 vht_op_addr = mac_ie_vht_oper_find(var_part_addr, var_part_len);
01101
01102 if (vif->type == VIF_STA)
01103 {
01104 uint32_t op_mode_notif_addr = mac_ie_op_mode_notif_find(var_part_addr,
01105 var_part_len);
01106
01107 if (op_mode_notif_addr)
01108 {
01109 uint8_t opmode = co_read8p(op_mode_notif_addr + MAC_INFOELT_INFO_OFT);
01110 struct sta_info_tag *sta = &sta_info_tab[vif->u.sta.ap_id];
01111
01112
01113 if ((STA_CAPA(sta, VHT) || STA_CAPA(sta, HE)) &&
01114 !(opmode & MAC_OPMODE_RXNSS_TYPE_BIT))
01115 {
01116 uint8_t bw = (opmode & MAC_OPMODE_BW_MSK) >> MAC_OPMODE_BW_OFT;
01117 uint8_t nss = (opmode & MAC_OPMODE_RXNSS_MSK) >> MAC_OPMODE_RXNSS_OFT;
01118
01119
01120 me_sta_bw_nss_max_upd(vif->u.sta.ap_id, bw, nss);
01121 }
01122 }
01123
01124 #if NX_HE
01125 if (BSS_CAPA(bss, HE))
01126 {
01127 bool changed;
01128 struct mm_set_uora_req *req = KE_MSG_ALLOC(MM_SET_UORA_REQ, TASK_MM,
01129 TASK_ME, mm_set_uora_req);
01130
01131 me_extract_uora_params(var_part_addr, var_part_len, req);
01132
01133 ke_msg_send(req);
01134
01135 me_extract_mu_edca_params(var_part_addr, var_part_len,
01136 &bss->mu_edca_param, &changed);
01137
01138 if (changed)
01139 {
01140
01141 struct mm_set_mu_edca_req *req =
01142 KE_MSG_ALLOC(MM_SET_MU_EDCA_REQ, TASK_MM,
01143 TASK_ME, mm_set_mu_edca_req);
01144
01145 for (int i = 0; i < AC_MAX; i++)
01146 {
01147 req->param[i] = bss->mu_edca_param.ac_param[i];
01148 }
01149
01150 ke_msg_send(req);
01151 }
01152 }
01153 #endif
01154 }
01155 #if NX_HE
01156 if (LOCAL_CAPA(HE))
01157 {
01158 uint16_t txop_dur_rts_thres = MAC_HE_OPER_TXOP_DUR_RTS_THRES_DISABLED;
01159
01160 if (me_extract_he_oper(var_part_addr, var_part_len, bss))
01161 {
01162 txop_dur_rts_thres = (bss->he_oper & MAC_HE_OPER_TXOP_DUR_RTS_THRES_MSK)
01163 >> MAC_HE_OPER_TXOP_DUR_RTS_THRES_OFT;
01164 }
01165
01166 if (txop_dur_rts_thres)
01167 {
01168 struct mm_set_txop_rts_thres_req *req =
01169 KE_MSG_ALLOC(MM_SET_TXOP_RTS_THRES_REQ, TASK_MM,
01170 TASK_ME, mm_set_txop_rts_thres_req);
01171
01172 req->txop_dur_rts_thres = txop_dur_rts_thres;
01173 req->inst_nbr = vif->index;
01174
01175 ke_msg_send(req);
01176 }
01177
01178 if (cur_bss_color != (bss->he_oper & ME_BSS_COLOR_MSK))
01179 {
01180 struct mm_set_bss_color_req *req =
01181 KE_MSG_ALLOC(MM_SET_BSS_COLOR_REQ, TASK_MM,
01182 TASK_ME, mm_set_bss_color_req);
01183
01184 req->bss_color = me_build_bss_color_reg(bss);
01185
01186 ke_msg_send(req);
01187 }
01188 }
01189 #endif
01190 }
01191 #endif
01192 }
01193 me_bw_check(ht_op_addr, vht_op_addr, bss);
01194
01195
01196 csa_count = me_extract_csa(var_part_addr, var_part_len, &csa_mode, &vif->csa_channel);
01197 if (csa_count)
01198 {
01199 if (vif->type == VIF_STA)
01200 {
01201 if ((!vif->u.sta.csa_count) &&
01202 (csa_mode == MAC_SWITCH_MODE_TX_TRAFFIC_STOP))
01203 {
01204 mm_send_csa_traffic_ind(vif->index, false);
01205 }
01206 vif->u.sta.csa_count = csa_count;
01207 }
01208 #if NX_BCN_AUTONOMOUS_TX
01209 else if (vif->type == VIF_AP)
01210 {
01211 vif->u.ap.csa_count = csa_count;
01212 }
01213 #endif
01214 }
01215
01216
01217 me_extract_power_constraint(var_part_addr, var_part_len, bss);
01218
01219 if (cur_pwr_const != bss->power_constraint)
01220 tpc_update_vif_tx_power(vif);
01221
01222
01223 if (cur_phy_bw < bss->chan.type)
01224 {
01225 me_chan_ctxt_update(vif);
01226 }
01227
01228
01229 while (sta != NULL)
01230 {
01231 if (cur_prot_status != bss->prot_status)
01232 {
01233
01234 me_pol_tbl_prot_upd(sta, bss->prot_status);
01235 }
01236
01237 if (cur_phy_bw != bss->chan.type)
01238 {
01239 me_pol_tbl_bw_upd(sta, bss->chan.type);
01240 }
01241
01242 #if NX_HE
01243 if (cur_bss_color != (bss->he_oper & ME_BSS_COLOR_MSK))
01244 {
01245 me_pol_tbl_bss_color_upd(sta);
01246 }
01247 #endif
01248
01249 sta = (struct sta_info_tag *)co_list_next(&sta->list_hdr);
01250 }
01251 }
01252
01253 void me_sta_bw_nss_max_upd(uint8_t sta_idx, uint8_t bw, uint8_t nss)
01254 {
01255 struct sta_info_tag *sta = &sta_info_tab[sta_idx];
01256 struct sta_pol_tbl_cntl *pol_tbl = &sta->pol_tbl;
01257 struct sta_capa_info *info = &sta->info;
01258 struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
01259 uint8_t local_supp_nss = 0;
01260 uint8_t peer_supp_nss = 0;
01261
01262 #if NX_HE
01263 if (STA_CAPA(sta, HE))
01264 {
01265 ASSERT_ERR(LOCAL_CAPA(HE));
01266
01267
01268 peer_supp_nss = me_11ac_nss_max(info->he_cap.mcs_supp.rx_mcs_80);
01269 local_supp_nss = me_11ac_nss_max(me_env.he_cap.mcs_supp.tx_mcs_80);
01270
01271 nss = co_min(nss, co_min(local_supp_nss, peer_supp_nss));
01272 }
01273 else
01274 #endif
01275 #if NX_VHT
01276 if (STA_CAPA(sta, VHT))
01277 {
01278 ASSERT_ERR(LOCAL_CAPA(VHT));
01279
01280
01281 peer_supp_nss = me_11ac_nss_max(info->vht_cap.rx_mcs_map);
01282 local_supp_nss = me_11ac_nss_max(me_env.vht_cap.tx_mcs_map);
01283
01284 nss = co_min(nss, co_min(local_supp_nss, peer_supp_nss));
01285 }
01286 else
01287 #endif
01288 {
01289 ASSERT_ERR(LOCAL_CAPA(HT));
01290
01291
01292 peer_supp_nss = me_11n_nss_max(info->ht_cap.mcs_rate);
01293 local_supp_nss = me_11n_nss_max(me_env.ht_cap.mcs_rate);
01294
01295 nss = co_min(nss, co_min(local_supp_nss, peer_supp_nss));
01296 }
01297
01298 bw = co_min(bw, me_phy2mac_bw(info->phy_bw_max));
01299
01300 #if NX_TDLS
01301 if (sta_idx == vif->u.sta.tdls_chsw_sta_idx)
01302 {
01303 info->bw_cur = bw;
01304 }
01305 else
01306 #endif
01307 {
01308 info->bw_cur = co_min(bw, me_phy2mac_bw(vif->bss_info.chan.type));
01309 }
01310
01311
01312 rc_update_bw_nss_max(sta->staid, info->bw_cur, nss);
01313
01314
01315 pol_tbl->upd_field |= CO_BIT(STA_MGMT_POL_UPD_BW);
01316 }
01317
01318 uint16_t me_tx_cfm_amsdu(struct txdesc *txdesc)
01319 {
01320 struct hostdesc *host = &txdesc->host;
01321 struct sta_info_tag *sta = &sta_info_tab[host->staid];
01322
01323 if (host->tid == 0xff)
01324 return 0;
01325
01326 if (sta->inst_nbr == 0xFF)
01327 return 0;
01328
01329 #if NX_AMPDU_TX
01330
01331 if (sta->ba_info[host->tid].bam_idx_tx == BAM_INVALID_TASK_IDX)
01332 return 0;
01333
01334 if (!bam_env[sta->ba_info[host->tid].bam_idx_tx].amsdu)
01335 return 0;
01336 #endif
01337
01338
01339 return rc_get_max_amsdu_len(sta);
01340 }
01341
01342 void me_vht_bandwidth_parse(uint8_t width, uint8_t center0, uint8_t center1,
01343 struct mac_chan_op *chan)
01344 {
01345 int delta = 0;
01346
01347 if ((width == 0) || (width >= 4))
01348 return;
01349
01350 chan->center1_freq = phy_channel_to_freq(chan->band, center0);
01351 chan->center2_freq = phy_channel_to_freq(chan->band, center1);
01352
01353 switch (width)
01354 {
01355 case 1:
01356
01357
01358
01359
01360
01361 if (chan->center2_freq)
01362 {
01363 if (chan->center1_freq > chan->center2_freq)
01364 delta = chan->center1_freq - chan->center2_freq;
01365 else
01366 delta = chan->center2_freq - chan->center1_freq;
01367 }
01368
01369 if ((delta == 40) && (me_env.phy_bw_max >= PHY_CHNL_BW_160))
01370 {
01371 chan->type = PHY_CHNL_BW_160;
01372 chan->center1_freq = chan->center2_freq;
01373 chan->center2_freq = 0;
01374 }
01375 else if ((delta > 40) && (me_env.phy_bw_max == PHY_CHNL_BW_80P80))
01376 {
01377 chan->type = PHY_CHNL_BW_80P80;
01378 }
01379 else
01380 {
01381 chan->type = PHY_CHNL_BW_80;
01382 chan->center2_freq = 0;
01383 }
01384 break;
01385 case 2:
01386
01387
01388
01389 if (me_env.phy_bw_max >= PHY_CHNL_BW_160)
01390 {
01391 chan->type = PHY_CHNL_BW_160;
01392 }
01393 else
01394 {
01395
01396 chan->type = PHY_CHNL_BW_80;
01397 if (chan->center1_freq < chan->prim20_freq)
01398 chan->center1_freq += 40;
01399 else
01400 chan->center1_freq -= 40;
01401 }
01402 break;
01403 case 3:
01404
01405
01406
01407 if (me_env.phy_bw_max == PHY_CHNL_BW_80P80)
01408 {
01409 chan->type = PHY_CHNL_BW_80P80;
01410 }
01411 else
01412 {
01413
01414 chan->type = PHY_CHNL_BW_80;
01415 chan->center2_freq = 0;
01416 }
01417 break;
01418 default:
01419 break;
01420 }
01421 }
01422