aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c78
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 =