diff options
author | Benjamin Beichler <benjamin.beichler@uni-rostock.de> | 2018-01-10 11:42:55 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2018-01-15 07:18:42 -0500 |
commit | 6e3d6ca16319d461206d0e348be3dab8c165f7f8 (patch) | |
tree | 5b46915bd36cb0f6d979c010ccaf9afe12fda785 | |
parent | c6509cc3b3e84b6b0a640280981d60090ad7871e (diff) |
mac80211_hwsim: add hwsim_tx_rate_flags to netlink attributes
For correct interpretation of a tx rate, the corresponding rate flags are
needed (e.g. whether a HT-MCS rate or a legacy rate) and moreover for more
correct simulation the other infos of the flags are important (like
short-GI). Keeping compatibility, the flags are not integrated into the
existing hwsim_tx_rate, but transmitted as an additional netlink attribute.
Signed-off-by: Benjamin Beichler <benjamin.beichler@uni-rostock.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.h | 68 |
2 files changed, 107 insertions, 2 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 9339615a46d3..6bf063adcbde 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1018,6 +1018,36 @@ static int hwsim_unicast_netgroup(struct mac80211_hwsim_data *data, | |||
1018 | return res; | 1018 | return res; |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate) | ||
1022 | { | ||
1023 | u16 result = 0; | ||
1024 | |||
1025 | if (rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
1026 | result |= MAC80211_HWSIM_TX_RC_USE_RTS_CTS; | ||
1027 | if (rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | ||
1028 | result |= MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT; | ||
1029 | if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
1030 | result |= MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE; | ||
1031 | if (rate->flags & IEEE80211_TX_RC_MCS) | ||
1032 | result |= MAC80211_HWSIM_TX_RC_MCS; | ||
1033 | if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD) | ||
1034 | result |= MAC80211_HWSIM_TX_RC_GREEN_FIELD; | ||
1035 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
1036 | result |= MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH; | ||
1037 | if (rate->flags & IEEE80211_TX_RC_DUP_DATA) | ||
1038 | result |= MAC80211_HWSIM_TX_RC_DUP_DATA; | ||
1039 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
1040 | result |= MAC80211_HWSIM_TX_RC_SHORT_GI; | ||
1041 | if (rate->flags & IEEE80211_TX_RC_VHT_MCS) | ||
1042 | result |= MAC80211_HWSIM_TX_RC_VHT_MCS; | ||
1043 | if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) | ||
1044 | result |= MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH; | ||
1045 | if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) | ||
1046 | result |= MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH; | ||
1047 | |||
1048 | return result; | ||
1049 | } | ||
1050 | |||
1021 | static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | 1051 | static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, |
1022 | struct sk_buff *my_skb, | 1052 | struct sk_buff *my_skb, |
1023 | int dst_portid) | 1053 | int dst_portid) |
@@ -1030,6 +1060,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | |||
1030 | unsigned int hwsim_flags = 0; | 1060 | unsigned int hwsim_flags = 0; |
1031 | int i; | 1061 | int i; |
1032 | struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; | 1062 | struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; |
1063 | struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES]; | ||
1033 | uintptr_t cookie; | 1064 | uintptr_t cookie; |
1034 | 1065 | ||
1035 | if (data->ps != PS_DISABLED) | 1066 | if (data->ps != PS_DISABLED) |
@@ -1081,7 +1112,11 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | |||
1081 | 1112 | ||
1082 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 1113 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
1083 | tx_attempts[i].idx = info->status.rates[i].idx; | 1114 | tx_attempts[i].idx = info->status.rates[i].idx; |
1115 | tx_attempts_flags[i].idx = info->status.rates[i].idx; | ||
1084 | tx_attempts[i].count = info->status.rates[i].count; | 1116 | tx_attempts[i].count = info->status.rates[i].count; |
1117 | tx_attempts_flags[i].flags = | ||
1118 | trans_tx_rate_flags_ieee2hwsim( | ||
1119 | &info->status.rates[i]); | ||
1085 | } | 1120 | } |
1086 | 1121 | ||
1087 | if (nla_put(skb, HWSIM_ATTR_TX_INFO, | 1122 | if (nla_put(skb, HWSIM_ATTR_TX_INFO, |
@@ -1089,6 +1124,11 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | |||
1089 | tx_attempts)) | 1124 | tx_attempts)) |
1090 | goto nla_put_failure; | 1125 | goto nla_put_failure; |
1091 | 1126 | ||
1127 | if (nla_put(skb, HWSIM_ATTR_TX_INFO_FLAGS, | ||
1128 | sizeof(struct hwsim_tx_rate_flag) * IEEE80211_TX_MAX_RATES, | ||
1129 | tx_attempts_flags)) | ||
1130 | goto nla_put_failure; | ||
1131 | |||
1092 | /* We create a cookie to identify this skb */ | 1132 | /* We create a cookie to identify this skb */ |
1093 | data->pending_cookie++; | 1133 | data->pending_cookie++; |
1094 | cookie = data->pending_cookie; | 1134 | cookie = data->pending_cookie; |
@@ -2983,7 +3023,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, | |||
2983 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 3023 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
2984 | txi->status.rates[i].idx = tx_attempts[i].idx; | 3024 | txi->status.rates[i].idx = tx_attempts[i].idx; |
2985 | txi->status.rates[i].count = tx_attempts[i].count; | 3025 | txi->status.rates[i].count = tx_attempts[i].count; |
2986 | /*txi->status.rates[i].flags = 0;*/ | ||
2987 | } | 3026 | } |
2988 | 3027 | ||
2989 | txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); | 3028 | txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); |
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 3f5eda591dba..a96a79c1eff5 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h | |||
@@ -64,7 +64,8 @@ enum hwsim_tx_control_flags { | |||
64 | * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to | 64 | * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to |
65 | * kernel, uses: | 65 | * kernel, uses: |
66 | * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, | 66 | * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, |
67 | * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE | 67 | * %HWSIM_ATTR_TX_INFO, %WSIM_ATTR_TX_INFO_FLAGS, |
68 | * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE | ||
68 | * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters, | 69 | * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters, |
69 | * returns the radio ID (>= 0) or negative on errors, if successful | 70 | * returns the radio ID (>= 0) or negative on errors, if successful |
70 | * then multicast the result | 71 | * then multicast the result |
@@ -123,6 +124,8 @@ enum { | |||
123 | * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 | 124 | * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 |
124 | * @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio. | 125 | * @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio. |
125 | * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. | 126 | * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. |
127 | * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding | ||
128 | * rates of %HWSIM_ATTR_TX_INFO | ||
126 | * @__HWSIM_ATTR_MAX: enum limit | 129 | * @__HWSIM_ATTR_MAX: enum limit |
127 | */ | 130 | */ |
128 | 131 | ||
@@ -149,6 +152,7 @@ enum { | |||
149 | HWSIM_ATTR_NO_VIF, | 152 | HWSIM_ATTR_NO_VIF, |
150 | HWSIM_ATTR_FREQ, | 153 | HWSIM_ATTR_FREQ, |
151 | HWSIM_ATTR_PAD, | 154 | HWSIM_ATTR_PAD, |
155 | HWSIM_ATTR_TX_INFO_FLAGS, | ||
152 | __HWSIM_ATTR_MAX, | 156 | __HWSIM_ATTR_MAX, |
153 | }; | 157 | }; |
154 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) | 158 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) |
@@ -171,4 +175,66 @@ struct hwsim_tx_rate { | |||
171 | u8 count; | 175 | u8 count; |
172 | } __packed; | 176 | } __packed; |
173 | 177 | ||
178 | /** | ||
179 | * enum hwsim_tx_rate_flags - per-rate flags set by the rate control algorithm. | ||
180 | * Inspired by structure mac80211_rate_control_flags. New flags may be | ||
181 | * appended, but old flags not deleted, to keep compatibility for | ||
182 | * userspace. | ||
183 | * | ||
184 | * These flags are set by the Rate control algorithm for each rate during tx, | ||
185 | * in the @flags member of struct ieee80211_tx_rate. | ||
186 | * | ||
187 | * @MAC80211_HWSIM_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate. | ||
188 | * @MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required. | ||
189 | * This is set if the current BSS requires ERP protection. | ||
190 | * @MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE: Use short preamble. | ||
191 | * @MAC80211_HWSIM_TX_RC_MCS: HT rate. | ||
192 | * @MAC80211_HWSIM_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is | ||
193 | * split into a higher 4 bits (Nss) and lower 4 bits (MCS number) | ||
194 | * @MAC80211_HWSIM_TX_RC_GREEN_FIELD: Indicates whether this rate should be used | ||
195 | * in Greenfield mode. | ||
196 | * @MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be | ||
197 | * 40 MHz. | ||
198 | * @MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission | ||
199 | * @MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission | ||
200 | * (80+80 isn't supported yet) | ||
201 | * @MAC80211_HWSIM_TX_RC_DUP_DATA: The frame should be transmitted on both of | ||
202 | * the adjacent 20 MHz channels, if the current channel type is | ||
203 | * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS. | ||
204 | * @MAC80211_HWSIM_TX_RC_SHORT_GI: Short Guard interval should be used for this | ||
205 | * rate. | ||
206 | */ | ||
207 | enum hwsim_tx_rate_flags { | ||
208 | MAC80211_HWSIM_TX_RC_USE_RTS_CTS = BIT(0), | ||
209 | MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT = BIT(1), | ||
210 | MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE = BIT(2), | ||
211 | |||
212 | /* rate index is an HT/VHT MCS instead of an index */ | ||
213 | MAC80211_HWSIM_TX_RC_MCS = BIT(3), | ||
214 | MAC80211_HWSIM_TX_RC_GREEN_FIELD = BIT(4), | ||
215 | MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH = BIT(5), | ||
216 | MAC80211_HWSIM_TX_RC_DUP_DATA = BIT(6), | ||
217 | MAC80211_HWSIM_TX_RC_SHORT_GI = BIT(7), | ||
218 | MAC80211_HWSIM_TX_RC_VHT_MCS = BIT(8), | ||
219 | MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH = BIT(9), | ||
220 | MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH = BIT(10), | ||
221 | }; | ||
222 | |||
223 | /** | ||
224 | * struct hwsim_tx_rate - rate selection/status | ||
225 | * | ||
226 | * @idx: rate index to attempt to send with | ||
227 | * @count: number of tries in this rate before going to the next rate | ||
228 | * | ||
229 | * A value of -1 for @idx indicates an invalid rate and, if used | ||
230 | * in an array of retry rates, that no more rates should be tried. | ||
231 | * | ||
232 | * When used for transmit status reporting, the driver should | ||
233 | * always report the rate and number of retries used. | ||
234 | * | ||
235 | */ | ||
236 | struct hwsim_tx_rate_flag { | ||
237 | s8 idx; | ||
238 | u16 flags; | ||
239 | } __packed; | ||
174 | #endif /* __MAC80211_HWSIM_H */ | 240 | #endif /* __MAC80211_HWSIM_H */ |