@@ -45,32 +45,24 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
45
45
te_data -> link_id = -1 ;
46
46
}
47
47
48
- void iwl_mvm_roc_done_wk (struct work_struct * wk )
48
+ static void iwl_mvm_cleanup_roc (struct iwl_mvm * mvm )
49
49
{
50
- struct iwl_mvm * mvm = container_of (wk , struct iwl_mvm , roc_done_wk );
51
-
52
50
/*
53
51
* Clear the ROC_RUNNING status bit.
54
52
* This will cause the TX path to drop offchannel transmissions.
55
53
* That would also be done by mac80211, but it is racy, in particular
56
- * in the case that the time event actually completed in the firmware
57
- * (which is handled in iwl_mvm_te_handle_notif).
58
- */
59
- clear_bit (IWL_MVM_STATUS_ROC_RUNNING , & mvm -> status );
60
-
61
- synchronize_net ();
62
-
63
- /*
64
- * Flush the offchannel queue -- this is called when the time
54
+ * in the case that the time event actually completed in the firmware.
55
+ *
56
+ * Also flush the offchannel queue -- this is called when the time
65
57
* event finishes or is canceled, so that frames queued for it
66
58
* won't get stuck on the queue and be transmitted in the next
67
59
* time event.
68
60
*/
69
-
70
- mutex_lock (& mvm -> mutex );
71
- if (test_and_clear_bit (IWL_MVM_STATUS_NEED_FLUSH_P2P , & mvm -> status )) {
61
+ if (test_and_clear_bit (IWL_MVM_STATUS_ROC_RUNNING , & mvm -> status )) {
72
62
struct iwl_mvm_vif * mvmvif ;
73
63
64
+ synchronize_net ();
65
+
74
66
/*
75
67
* NB: access to this pointer would be racy, but the flush bit
76
68
* can only be set when we had a P2P-Device VIF, and we have a
@@ -105,21 +97,16 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
105
97
}
106
98
}
107
99
108
- /*
109
- * Clear the ROC_AUX_RUNNING status bit.
110
- * This will cause the TX path to drop offchannel transmissions.
111
- * That would also be done by mac80211, but it is racy, in particular
112
- * in the case that the time event actually completed in the firmware
113
- * (which is handled in iwl_mvm_te_handle_notif).
114
- */
100
+ /* Do the same for AUX ROC */
115
101
if (test_and_clear_bit (IWL_MVM_STATUS_ROC_AUX_RUNNING , & mvm -> status )) {
116
- /* do the same in case of hot spot 2.0 */
102
+ synchronize_net ();
103
+
117
104
iwl_mvm_flush_sta (mvm , mvm -> aux_sta .sta_id ,
118
105
mvm -> aux_sta .tfd_queue_msk );
119
106
120
107
if (mvm -> mld_api_is_used ) {
121
108
iwl_mvm_mld_rm_aux_sta (mvm );
122
- goto out_unlock ;
109
+ return ;
123
110
}
124
111
125
112
/* In newer version of this command an aux station is added only
@@ -128,8 +115,14 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
128
115
if (iwl_mvm_has_new_station_api (mvm -> fw ))
129
116
iwl_mvm_rm_aux_sta (mvm );
130
117
}
118
+ }
131
119
132
- out_unlock :
120
+ void iwl_mvm_roc_done_wk (struct work_struct * wk )
121
+ {
122
+ struct iwl_mvm * mvm = container_of (wk , struct iwl_mvm , roc_done_wk );
123
+
124
+ mutex_lock (& mvm -> mutex );
125
+ iwl_mvm_cleanup_roc (mvm );
133
126
mutex_unlock (& mvm -> mutex );
134
127
}
135
128
@@ -294,18 +287,6 @@ static void iwl_mvm_te_check_trigger(struct iwl_mvm *mvm,
294
287
}
295
288
}
296
289
297
- static void iwl_mvm_p2p_roc_finished (struct iwl_mvm * mvm )
298
- {
299
- /*
300
- * If the IWL_MVM_STATUS_NEED_FLUSH_P2P is already set, then the
301
- * roc_done_wk is already scheduled or running, so don't schedule it
302
- * again to avoid a race where the roc_done_wk clears this bit after
303
- * it is set here, affecting the next run of the roc_done_wk.
304
- */
305
- if (!test_and_set_bit (IWL_MVM_STATUS_NEED_FLUSH_P2P , & mvm -> status ))
306
- iwl_mvm_roc_finished (mvm );
307
- }
308
-
309
290
/*
310
291
* Handles a FW notification for an event that is known to the driver.
311
292
*
@@ -357,7 +338,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
357
338
switch (te_data -> vif -> type ) {
358
339
case NL80211_IFTYPE_P2P_DEVICE :
359
340
ieee80211_remain_on_channel_expired (mvm -> hw );
360
- iwl_mvm_p2p_roc_finished (mvm );
341
+ iwl_mvm_roc_finished (mvm );
361
342
break ;
362
343
case NL80211_IFTYPE_STATION :
363
344
/*
@@ -782,7 +763,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
782
763
iwl_mvm_cancel_session_protection (mvm , vif , id ,
783
764
link_id );
784
765
if (iftype == NL80211_IFTYPE_P2P_DEVICE ) {
785
- iwl_mvm_p2p_roc_finished (mvm );
766
+ iwl_mvm_roc_finished (mvm );
786
767
}
787
768
}
788
769
return false;
@@ -972,7 +953,7 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
972
953
/* End TE, notify mac80211 */
973
954
mvmvif -> time_event_data .id = SESSION_PROTECT_CONF_MAX_ID ;
974
955
mvmvif -> time_event_data .link_id = -1 ;
975
- iwl_mvm_p2p_roc_finished (mvm );
956
+ iwl_mvm_roc_finished (mvm );
976
957
ieee80211_remain_on_channel_expired (mvm -> hw );
977
958
} else if (le32_to_cpu (notif -> start )) {
978
959
if (WARN_ON (mvmvif -> time_event_data .id !=
@@ -1244,17 +1225,13 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1244
1225
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD )) {
1245
1226
mvmvif = iwl_mvm_vif_from_mac80211 (vif );
1246
1227
1247
- if (vif -> type == NL80211_IFTYPE_P2P_DEVICE ) {
1228
+ if (vif -> type == NL80211_IFTYPE_P2P_DEVICE )
1248
1229
iwl_mvm_cancel_session_protection (mvm , vif ,
1249
1230
mvmvif -> time_event_data .id ,
1250
1231
mvmvif -> time_event_data .link_id );
1251
- iwl_mvm_p2p_roc_finished (mvm );
1252
- } else {
1232
+ else
1253
1233
iwl_mvm_roc_station_remove (mvm , mvmvif );
1254
- iwl_mvm_roc_finished (mvm );
1255
- }
1256
-
1257
- return ;
1234
+ goto cleanup_roc ;
1258
1235
}
1259
1236
1260
1237
te_data = iwl_mvm_get_roc_te (mvm );
@@ -1265,13 +1242,21 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1265
1242
1266
1243
mvmvif = iwl_mvm_vif_from_mac80211 (te_data -> vif );
1267
1244
1268
- if (te_data -> vif -> type == NL80211_IFTYPE_P2P_DEVICE ) {
1245
+ if (te_data -> vif -> type == NL80211_IFTYPE_P2P_DEVICE )
1269
1246
iwl_mvm_remove_time_event (mvm , mvmvif , te_data );
1270
- iwl_mvm_p2p_roc_finished (mvm );
1271
- } else {
1247
+ else
1272
1248
iwl_mvm_remove_aux_roc_te (mvm , mvmvif , te_data );
1273
- iwl_mvm_roc_finished (mvm );
1274
- }
1249
+
1250
+ cleanup_roc :
1251
+ /*
1252
+ * In case we get here before the ROC event started,
1253
+ * (so the status bit isn't set) set it here so iwl_mvm_cleanup_roc will
1254
+ * cleanup things properly
1255
+ */
1256
+ set_bit (vif -> type == NL80211_IFTYPE_P2P_DEVICE ?
1257
+ IWL_MVM_STATUS_ROC_RUNNING : IWL_MVM_STATUS_ROC_AUX_RUNNING ,
1258
+ & mvm -> status );
1259
+ iwl_mvm_cleanup_roc (mvm );
1275
1260
}
1276
1261
1277
1262
void iwl_mvm_remove_csa_period (struct iwl_mvm * mvm ,
0 commit comments