This patch adds support to set transmit power setting type and transmit power level attributes to NL80211_CMD_SET_STATION in order to facilitate adjusting the transmit power level of a station associated to the AP. The added attributes allow selection of automatic and limited transmit power level, with the level defined in dBm format.
Unified · Split
| @@ -975,6 +975,27 @@ enum station_parameters_apply_mask { · 974 unmodified lines | ||
| 975 | 975 | STATION_PARAM_APPLY_UAPSD = BIT(0), |
| 976 | 976 | STATION_PARAM_APPLY_CAPABILITY = BIT(1), |
| 977 | 977 | STATION_PARAM_APPLY_PLINK_STATE = BIT(2), |
| 978 | + STATION_PARAM_APPLY_STA_TXPOWER = BIT(3), | |
| 979 | +}; | |
| 980 | + | |
| 981 | +/** | |
| 982 | + * struct sta_txpwr - station txpower configuration | |
| 983 | + * | |
| 984 | + * Used to configure txpower for station. | |
| 985 | + * | |
| 986 | + * @power: tx power (in dBm) to be used for sending data traffic. If tx power | |
| 987 | + * is not provided, the default per-interface tx power setting will be | |
| 988 | + * overriding. Driver should be picking up the lowest tx power, either tx | |
| 989 | + * power per-interface or per-station. | |
| 990 | + * @type: In particular if TPC %type is NL80211_TX_POWER_LIMITED then tx power | |
| 991 | + * will be less than or equal to specified from userspace, whereas if TPC | |
| 992 | + * %type is NL80211_TX_POWER_AUTOMATIC then it indicates default tx power. | |
| 993 | + * NL80211_TX_POWER_FIXED is not a valid configuration option for | |
| 994 | + * per peer TPC. | |
| 995 | + */ | |
| 996 | +struct sta_txpwr { | |
| 997 | + s16 power; | |
| 998 | + enum nl80211_tx_power_setting type; | |
| 978 | 999 | }; |
| 979 | 1000 | |
| 980 | 1001 | /** |
| @@ -1049,6 +1070,7 @@ struct station_parameters { · 68 unmodified lines | ||
| 1049 | 1070 | const struct ieee80211_he_cap_elem *he_capa; |
| 1050 | 1071 | u8 he_capa_len; |
| 1051 | 1072 | u16 airtime_weight; |
| 1073 | + struct sta_txpwr txpwr; | |
| 1052 | 1074 | }; |
| 1053 | 1075 | |
| 1054 | 1076 | /** |
| @@ -2315,6 +2315,15 @@ enum nl80211_commands { · 2314 unmodified lines | ||
| 2315 | 2315 | * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime |
| 2316 | 2316 | * scheduler. |
| 2317 | 2317 | * |
| 2318 | + * @NL80211_ATTR_STA_TX_POWER_SETTING: Transmit power setting type (u8) for | |
| 2319 | + * station associated with the AP. See &enum nl80211_tx_power_setting for | |
| 2320 | + * possible values. | |
| 2321 | + * @NL80211_ATTR_STA_TX_POWER: Transmit power level (s16) in dBm units. This | |
| 2322 | + * allows to set Tx power for a station. If this attribute is not included, | |
| 2323 | + * the default per-interface tx power setting will be overriding. Driver | |
| 2324 | + * should be picking up the lowest tx power, either tx power per-interface | |
| 2325 | + * or per-station. | |
| 2326 | + * | |
| 2318 | 2327 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available |
| 2319 | 2328 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
| 2320 | 2329 | * @__NL80211_ATTR_AFTER_LAST: internal use |
| @@ -2765,6 +2774,8 @@ enum nl80211_attrs { · 444 unmodified lines | ||
| 2765 | 2774 | NL80211_ATTR_PEER_MEASUREMENTS, |
| 2766 | 2775 | |
| 2767 | 2776 | NL80211_ATTR_AIRTIME_WEIGHT, |
| 2777 | + NL80211_ATTR_STA_TX_POWER_SETTING, | |
| 2778 | + NL80211_ATTR_STA_TX_POWER, | |
| 2768 | 2779 | |
| 2769 | 2780 | /* add attributes here, update the policy in nl80211.c */ |
| 2770 | 2781 | |
| @@ -5391,6 +5402,9 @@ enum nl80211_feature_flags { · 2620 unmodified lines | ||
| 5391 | 5402 | * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports |
| 5392 | 5403 | * filtering of sched scan results using band specific RSSI thresholds. |
| 5393 | 5404 | * |
| 5405 | + * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power | |
| 5406 | + * to a station. | |
| 5407 | + * | |
| 5394 | 5408 | * @NUM_NL80211_EXT_FEATURES: number of extended features. |
| 5395 | 5409 | * @MAX_NL80211_EXT_FEATURES: highest extended feature index. |
| 5396 | 5410 | */ |
| @@ -5434,6 +5448,7 @@ enum nl80211_ext_feature_index { · 37 unmodified lines | ||
| 5434 | 5448 | NL80211_EXT_FEATURE_AP_PMKSA_CACHING, |
| 5435 | 5449 | NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, |
| 5436 | 5450 | NL80211_EXT_FEATURE_EXT_KEY_ID, |
| 5451 | + NL80211_EXT_FEATURE_STA_TX_PWR, | |
| 5437 | 5452 | |
| 5438 | 5453 | /* add new features before the definition below */ |
| 5439 | 5454 | NUM_NL80211_EXT_FEATURES, |
| @@ -331,6 +331,11 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { · 330 unmodified lines | ||
| 331 | 331 | .len = NL80211_MAX_SUPP_RATES }, |
| 332 | 332 | [NL80211_ATTR_STA_PLINK_ACTION] = |
| 333 | 333 | NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1), |
| 334 | + [NL80211_ATTR_STA_TX_POWER_SETTING] = | |
| 335 | + NLA_POLICY_RANGE(NLA_U8, | |
| 336 | + NL80211_TX_POWER_AUTOMATIC, | |
| 337 | + NL80211_TX_POWER_FIXED), | |
| 338 | + [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 }, | |
| 334 | 339 | [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, |
| 335 | 340 | [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, |
| 336 | 341 | [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, |
| @@ -5420,6 +5425,36 @@ static int nl80211_set_station_tdls(struct genl_info *info, · 5083 unmodified lines | ||
| 5420 | 5425 | return nl80211_parse_sta_wme(info, params); |
| 5421 | 5426 | } |
| 5422 | 5427 | |
| 5428 | +static int nl80211_parse_sta_txpower_setting(struct genl_info *info, | |
| 5429 | + struct station_parameters *params) | |
| 5430 | +{ | |
| 5431 | + struct cfg80211_registered_device *rdev = info->user_ptr[0]; | |
| 5432 | + int idx; | |
| 5433 | + | |
| 5434 | + if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) { | |
| 5435 | + if (!rdev->ops->set_tx_power || | |
| 5436 | + !wiphy_ext_feature_isset(&rdev->wiphy, | |
| 5437 | + NL80211_EXT_FEATURE_STA_TX_PWR)) | |
| 5438 | + return -EOPNOTSUPP; | |
| 5439 | + | |
| 5440 | + idx = NL80211_ATTR_STA_TX_POWER_SETTING; | |
| 5441 | + params->txpwr.type = nla_get_u8(info->attrs[idx]); | |
| 5442 | + | |
| 5443 | + if (params->txpwr.type == NL80211_TX_POWER_LIMITED) { | |
| 5444 | + idx = NL80211_ATTR_STA_TX_POWER; | |
| 5445 | + | |
| 5446 | + if (info->attrs[idx]) | |
| 5447 | + params->txpwr.power = | |
| 5448 | + nla_get_s16(info->attrs[idx]); | |
| 5449 | + else | |
| 5450 | + return -EINVAL; | |
| 5451 | + } | |
| 5452 | + params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER; | |
| 5453 | + } | |
| 5454 | + | |
| 5455 | + return 0; | |
| 5456 | +} | |
| 5457 | + | |
| 5423 | 5458 | static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) |
| 5424 | 5459 | { |
| 5425 | 5460 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| @@ -5513,6 +5548,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) · 87 unmodified lines | ||
| 5513 | 5548 | NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) |
| 5514 | 5549 | return -EOPNOTSUPP; |
| 5515 | 5550 | |
| 5551 | + err = nl80211_parse_sta_txpower_setting(info, ¶ms); | |
| 5552 | + if (err) | |
| 5553 | + return err; | |
| 5554 | + | |
| 5516 | 5555 | /* Include parameters for TDLS peer (will check later) */ |
| 5517 | 5556 | err = nl80211_set_station_tdls(info, ¶ms); |
| 5518 | 5557 | if (err) |
| @@ -5650,6 +5689,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) · 131 unmodified lines | ||
| 5650 | 5689 | NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) |
| 5651 | 5690 | return -EOPNOTSUPP; |
| 5652 | 5691 | |
| 5692 | + err = nl80211_parse_sta_txpower_setting(info, ¶ms); | |
| 5693 | + if (err) | |
| 5694 | + return err; | |
| 5695 | + | |
| 5653 | 5696 | err = nl80211_parse_sta_channel_info(info, ¶ms); |
| 5654 | 5697 | if (err) |
| 5655 | 5698 | return err; |