mac80211: store tx power value from user to station
This patch introduce a new driver callback drv_sta_set_txpwr. This API will copy the transmit power value passed from user space and call the driver callback to set the tx power for the station. Co-developed-by: Balaji Pothunoori <bpothuno@codeaurora.org> Signed-off-by: Ashok Raj Nagarajan <arnagara@codeaurora.org> Signed-off-by: Balaji Pothunoori <bpothuno@codeaurora.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Родитель
e96d1cd263
Коммит
ba905bf432
|
@ -1889,6 +1889,24 @@ struct ieee80211_sta_rates {
|
||||||
} rate[IEEE80211_TX_RATE_TABLE_SIZE];
|
} rate[IEEE80211_TX_RATE_TABLE_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ieee80211_sta_txpwr - station txpower configuration
|
||||||
|
*
|
||||||
|
* Used to configure txpower for station.
|
||||||
|
*
|
||||||
|
* @power: indicates the tx power, in dBm, to be used when sending data frames
|
||||||
|
* to the STA.
|
||||||
|
* @type: In particular if TPC %type is NL80211_TX_POWER_LIMITED then tx power
|
||||||
|
* will be less than or equal to specified from userspace, whereas if TPC
|
||||||
|
* %type is NL80211_TX_POWER_AUTOMATIC then it indicates default tx power.
|
||||||
|
* NL80211_TX_POWER_FIXED is not a valid configuration option for
|
||||||
|
* per peer TPC.
|
||||||
|
*/
|
||||||
|
struct ieee80211_sta_txpwr {
|
||||||
|
s16 power;
|
||||||
|
enum nl80211_tx_power_setting type;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct ieee80211_sta - station table entry
|
* struct ieee80211_sta - station table entry
|
||||||
*
|
*
|
||||||
|
@ -1975,6 +1993,7 @@ struct ieee80211_sta {
|
||||||
bool support_p2p_ps;
|
bool support_p2p_ps;
|
||||||
u16 max_rc_amsdu_len;
|
u16 max_rc_amsdu_len;
|
||||||
u16 max_tid_amsdu_len[IEEE80211_NUM_TIDS];
|
u16 max_tid_amsdu_len[IEEE80211_NUM_TIDS];
|
||||||
|
struct ieee80211_sta_txpwr txpwr;
|
||||||
|
|
||||||
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1];
|
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1];
|
||||||
|
|
||||||
|
@ -3800,6 +3819,9 @@ struct ieee80211_ops {
|
||||||
#endif
|
#endif
|
||||||
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
||||||
|
int (*sta_set_txpwr)(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_sta *sta);
|
||||||
int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
enum ieee80211_sta_state old_state,
|
enum ieee80211_sta_state old_state,
|
||||||
|
|
|
@ -1457,6 +1457,15 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||||
if (params->listen_interval >= 0)
|
if (params->listen_interval >= 0)
|
||||||
sta->listen_interval = params->listen_interval;
|
sta->listen_interval = params->listen_interval;
|
||||||
|
|
||||||
|
if (params->sta_modify_mask & STATION_PARAM_APPLY_STA_TXPOWER) {
|
||||||
|
sta->sta.txpwr.type = params->txpwr.type;
|
||||||
|
if (params->txpwr.type == NL80211_TX_POWER_LIMITED)
|
||||||
|
sta->sta.txpwr.power = params->txpwr.power;
|
||||||
|
ret = drv_sta_set_txpwr(local, sdata, sta);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (params->supported_rates) {
|
if (params->supported_rates) {
|
||||||
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
||||||
sband, params->supported_rates,
|
sband, params->supported_rates,
|
||||||
|
|
|
@ -138,6 +138,27 @@ int drv_sta_state(struct ieee80211_local *local,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__must_check
|
||||||
|
int drv_sta_set_txpwr(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct sta_info *sta)
|
||||||
|
{
|
||||||
|
int ret = -EOPNOTSUPP;
|
||||||
|
|
||||||
|
might_sleep();
|
||||||
|
|
||||||
|
sdata = get_bss_sdata(sdata);
|
||||||
|
if (!check_sdata_in_driver(sdata))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
trace_drv_sta_set_txpwr(local, sdata, &sta->sta);
|
||||||
|
if (local->ops->sta_set_txpwr)
|
||||||
|
ret = local->ops->sta_set_txpwr(&local->hw, &sdata->vif,
|
||||||
|
&sta->sta);
|
||||||
|
trace_drv_return_int(local, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void drv_sta_rc_update(struct ieee80211_local *local,
|
void drv_sta_rc_update(struct ieee80211_local *local,
|
||||||
struct ieee80211_sub_if_data *sdata,
|
struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_sta *sta, u32 changed)
|
struct ieee80211_sta *sta, u32 changed)
|
||||||
|
|
|
@ -529,6 +529,11 @@ int drv_sta_state(struct ieee80211_local *local,
|
||||||
enum ieee80211_sta_state old_state,
|
enum ieee80211_sta_state old_state,
|
||||||
enum ieee80211_sta_state new_state);
|
enum ieee80211_sta_state new_state);
|
||||||
|
|
||||||
|
__must_check
|
||||||
|
int drv_sta_set_txpwr(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct sta_info *sta);
|
||||||
|
|
||||||
void drv_sta_rc_update(struct ieee80211_local *local,
|
void drv_sta_rc_update(struct ieee80211_local *local,
|
||||||
struct ieee80211_sub_if_data *sdata,
|
struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_sta *sta, u32 changed);
|
struct ieee80211_sta *sta, u32 changed);
|
||||||
|
|
|
@ -828,6 +828,36 @@ TRACE_EVENT(drv_sta_state,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(drv_sta_set_txpwr,
|
||||||
|
TP_PROTO(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct ieee80211_sta *sta),
|
||||||
|
|
||||||
|
TP_ARGS(local, sdata, sta),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
LOCAL_ENTRY
|
||||||
|
VIF_ENTRY
|
||||||
|
STA_ENTRY
|
||||||
|
__field(s16, txpwr)
|
||||||
|
__field(u8, type)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
LOCAL_ASSIGN;
|
||||||
|
VIF_ASSIGN;
|
||||||
|
STA_ASSIGN;
|
||||||
|
__entry->txpwr = sta->txpwr.power;
|
||||||
|
__entry->type = sta->txpwr.type;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk(
|
||||||
|
LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " txpwr: %d type %d",
|
||||||
|
LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG,
|
||||||
|
__entry->txpwr, __entry->type
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
TRACE_EVENT(drv_sta_rc_update,
|
TRACE_EVENT(drv_sta_rc_update,
|
||||||
TP_PROTO(struct ieee80211_local *local,
|
TP_PROTO(struct ieee80211_local *local,
|
||||||
struct ieee80211_sub_if_data *sdata,
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче