00001
00013 #include "tpc.h"
00014
00015 void tpc_update_tx_power(int8_t pwr)
00016 {
00017 uint8_t idx = 0;
00018
00019 phy_get_rf_gain_idx(&pwr, &idx);
00020
00021 nxmac_dsss_max_pwr_level_setf(idx);
00022 nxmac_ofdm_max_pwr_level_setf(idx);
00023 }
00024
00025 void tpc_get_vif_tx_power(struct vif_info_tag *vif, int8_t *pwr, uint8_t *idx)
00026 {
00027 int8_t _pwr = vif->tx_power;
00028 uint8_t _idx;
00029
00030 if ( _pwr == VIF_UNDEF_POWER)
00031 _idx = nxmac_ofdm_max_pwr_level_getf();
00032 else
00033 phy_get_rf_gain_idx(&_pwr, &_idx);
00034
00035 if (pwr)
00036 *pwr = _pwr;
00037 if (idx)
00038 *idx = _idx;
00039 }
00040
00041 void tpc_set_vif_tx_power(struct vif_info_tag *vif, int8_t req_pwr)
00042 {
00043 int8_t prev_pwr = vif->tx_power;
00044 int8_t pwr = req_pwr;
00045 uint8_t idx;
00046
00047 if (req_pwr == VIF_UNDEF_POWER)
00048 return;
00049
00050 phy_get_rf_gain_idx(&pwr, &idx);
00051 vif->tx_power = pwr;
00052
00053 if (prev_pwr != pwr)
00054 {
00055 #if NX_UMAC_PRESENT
00056
00057
00058 struct co_list_hdr *sta_hdr;
00059 sta_hdr = co_list_pick(&vif->sta_list);
00060 while (sta_hdr != NULL)
00061 {
00062 struct sta_info_tag *sta;
00063 struct sta_pol_tbl_cntl *rc;
00064
00065 sta = (struct sta_info_tag *)sta_hdr;
00066 rc = &sta->pol_tbl;
00067 rc->upd_field |= CO_BIT(STA_MGMT_POL_UPD_TX_POWER);
00068 sta_hdr = co_list_next(sta_hdr);
00069 }
00070 #endif
00071
00072 #if NX_CHNL_CTXT
00073 if (vif->chan_ctxt)
00074 chan_update_tx_power(vif->chan_ctxt);
00075 #else
00076
00077 int i;
00078
00079 for (i = 0; i < NX_VIRT_DEV_MAX; i++) {
00080 if (vif_info_tab[i].active && vif_info_tab[i].tx_power < pwr)
00081 pwr = vif_info_tab[i].tx_power;
00082 }
00083
00084 tpc_update_tx_power(pwr);
00085 #endif // NX_CHNL_CTXT
00086 }
00087 }
00088
00089 #if NX_TX_FRAME
00090 void tpc_update_frame_tx_power(struct vif_info_tag *vif, struct txl_frame_desc_tag *frame)
00091 {
00092 struct tx_policy_tbl *pol;
00093 uint8_t idx;
00094
00095 tpc_get_vif_tx_power(vif, NULL, &idx);
00096 pol = HW2CPU(frame->txdesc.lmac.hw_desc->thd.policyentryaddr);
00097 pol->powercntrlinfo[0] = TX_PWR_LEVEL_SET(idx);
00098 }
00099 #endif // NX_TX_FRAME
00100
00101 #if NX_UMAC_PRESENT
00102 void tpc_update_vif_tx_power(struct vif_info_tag *vif)
00103 {
00104 int8_t pwr;
00105
00106 pwr = vif->bss_info.chan.tx_power - vif->bss_info.power_constraint;
00107 if ((vif->user_tx_power != VIF_UNDEF_POWER) && (vif->user_tx_power < pwr))
00108 pwr = vif->user_tx_power;
00109
00110
00111 vif->tx_power = VIF_UNDEF_POWER;
00112
00113 tpc_set_vif_tx_power(vif, pwr);
00114 TRACE_LMAC(TPC, "{VIF-%d} set TX power to %ddBm (regulatory=%ddBm, local_constraint=%ddBm, user=%ddBm)",
00115 vif->index, vif->tx_power, vif->bss_info.chan.tx_power, vif->bss_info.power_constraint,
00116 vif->user_tx_power);
00117 }
00118 #endif // NX_UMAC_PRESENT