diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index ba723d50939a..9ccec10bba16 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -90,6 +90,7 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, | |||
90 | { | 90 | { |
91 | struct iwl_mvm_mac_iface_iterator_data *data = _data; | 91 | struct iwl_mvm_mac_iface_iterator_data *data = _data; |
92 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 92 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
93 | u16 min_bi; | ||
93 | 94 | ||
94 | /* Skip the interface for which we are trying to assign a tsf_id */ | 95 | /* Skip the interface for which we are trying to assign a tsf_id */ |
95 | if (vif == data->vif) | 96 | if (vif == data->vif) |
@@ -114,42 +115,57 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, | |||
114 | switch (data->vif->type) { | 115 | switch (data->vif->type) { |
115 | case NL80211_IFTYPE_STATION: | 116 | case NL80211_IFTYPE_STATION: |
116 | /* | 117 | /* |
117 | * The new interface is client, so if the existing one | 118 | * The new interface is a client, so if the one we're iterating |
118 | * we're iterating is an AP, and both interfaces have the | 119 | * is an AP, and the beacon interval of the AP is a multiple or |
119 | * same beacon interval, the same TSF should be used to | 120 | * divisor of the beacon interval of the client, the same TSF |
120 | * avoid drift between the new client and existing AP, | 121 | * should be used to avoid drift between the new client and |
121 | * the existing AP will get drift updates from the new | 122 | * existing AP. The existing AP will get drift updates from the |
122 | * client context in this case | 123 | * new client context in this case. |
123 | */ | 124 | */ |
124 | if (vif->type == NL80211_IFTYPE_AP) { | 125 | if (vif->type != NL80211_IFTYPE_AP || |
125 | if (data->preferred_tsf == NUM_TSF_IDS && | 126 | data->preferred_tsf != NUM_TSF_IDS || |
126 | test_bit(mvmvif->tsf_id, data->available_tsf_ids) && | 127 | !test_bit(mvmvif->tsf_id, data->available_tsf_ids)) |
127 | (vif->bss_conf.beacon_int == | 128 | break; |
128 | data->vif->bss_conf.beacon_int)) { | 129 | |
129 | data->preferred_tsf = mvmvif->tsf_id; | 130 | min_bi = min(data->vif->bss_conf.beacon_int, |
130 | return; | 131 | vif->bss_conf.beacon_int); |
131 | } | 132 | |
133 | if (!min_bi) | ||
134 | break; | ||
135 | |||
136 | if ((data->vif->bss_conf.beacon_int - | ||
137 | vif->bss_conf.beacon_int) % min_bi == 0) { | ||
138 | data->preferred_tsf = mvmvif->tsf_id; | ||
139 | return; | ||
132 | } | 140 | } |
133 | break; | 141 | break; |
142 | |||
134 | case NL80211_IFTYPE_AP: | 143 | case NL80211_IFTYPE_AP: |
135 | /* | 144 | /* |
136 | * The new interface is AP/GO, so in case both interfaces | 145 | * The new interface is AP/GO, so if its beacon interval is a |
137 | * have the same beacon interval, it should get drift | 146 | * multiple or a divisor of the beacon interval of an existing |
138 | * updates from an existing client or use the same | 147 | * interface, it should get drift updates from an existing |
139 | * TSF as an existing GO. There's no drift between | 148 | * client or use the same TSF as an existing GO. There's no |
140 | * TSFs internally but if they used different TSFs | 149 | * drift between TSFs internally but if they used different |
141 | * then a new client MAC could update one of them | 150 | * TSFs then a new client MAC could update one of them and |
142 | * and cause drift that way. | 151 | * cause drift that way. |
143 | */ | 152 | */ |
144 | if (vif->type == NL80211_IFTYPE_STATION || | 153 | if ((vif->type != NL80211_IFTYPE_AP && |
145 | vif->type == NL80211_IFTYPE_AP) { | 154 | vif->type != NL80211_IFTYPE_STATION) || |
146 | if (data->preferred_tsf == NUM_TSF_IDS && | 155 | data->preferred_tsf != NUM_TSF_IDS || |
147 | test_bit(mvmvif->tsf_id, data->available_tsf_ids) && | 156 | !test_bit(mvmvif->tsf_id, data->available_tsf_ids)) |
148 | (vif->bss_conf.beacon_int == | 157 | break; |
149 | data->vif->bss_conf.beacon_int)) { | 158 | |
150 | data->preferred_tsf = mvmvif->tsf_id; | 159 | min_bi = min(data->vif->bss_conf.beacon_int, |
151 | return; | 160 | vif->bss_conf.beacon_int); |
152 | } | 161 | |
162 | if (!min_bi) | ||
163 | break; | ||
164 | |||
165 | if ((data->vif->bss_conf.beacon_int - | ||
166 | vif->bss_conf.beacon_int) % min_bi == 0) { | ||
167 | data->preferred_tsf = mvmvif->tsf_id; | ||
168 | return; | ||
153 | } | 169 | } |
154 | break; | 170 | break; |
155 | default: | 171 | default: |
@@ -936,7 +952,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, | |||
936 | TX_CMD_FLG_TSF); | 952 | TX_CMD_FLG_TSF); |
937 | 953 | ||
938 | mvm->mgmt_last_antenna_idx = | 954 | mvm->mgmt_last_antenna_idx = |
939 | iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), | 955 | iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, |
940 | mvm->mgmt_last_antenna_idx); | 956 | mvm->mgmt_last_antenna_idx); |
941 | 957 | ||
942 | beacon_cmd.tx.rate_n_flags = | 958 | beacon_cmd.tx.rate_n_flags = |