Skip to content

Commit

Permalink
iwlwifi: mvm: ROC - bug fixes around time events and locking
Browse files Browse the repository at this point in the history
Don't add the time event to the list. We added it several
times the same time event, which leads to an infinite loop
when walking the list.

Since we (currently) don't support more than one ROC for STA
vif at a time, enforce this and don't add the time event
to any list.

We were also missing the locking of the mutex which led to
a lockdep splat - fix that.

Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
  • Loading branch information
Matti Gottlieb authored and Emmanuel Grumbach committed Oct 23, 2014
1 parent 79b7a69 commit a6cc516
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
25 changes: 16 additions & 9 deletions drivers/net/wireless/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
}

if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
!test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
!test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status) &&
!test_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
goto drop;

/* treat non-bufferable MMPDUs as broadcast if sta is sleeping */
Expand Down Expand Up @@ -2374,14 +2375,19 @@ static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm,
/* Set the node address */
memcpy(aux_roc_req.node_addr, vif->addr, ETH_ALEN);

lockdep_assert_held(&mvm->mutex);

spin_lock_bh(&mvm->time_event_lock);

if (WARN_ON(te_data->id == HOT_SPOT_CMD)) {
spin_unlock_bh(&mvm->time_event_lock);
return -EIO;
}

te_data->vif = vif;
te_data->duration = duration;
te_data->id = HOT_SPOT_CMD;

lockdep_assert_held(&mvm->mutex);

spin_lock_bh(&mvm->time_event_lock);
list_add_tail(&te_data->list, &mvm->time_event_list);
spin_unlock_bh(&mvm->time_event_lock);

/*
Expand Down Expand Up @@ -2437,22 +2443,23 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
duration, type);

mutex_lock(&mvm->mutex);

switch (vif->type) {
case NL80211_IFTYPE_STATION:
/* Use aux roc framework (HS20) */
ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
vif, duration);
return ret;
goto out_unlock;
case NL80211_IFTYPE_P2P_DEVICE:
/* handle below */
break;
default:
IWL_ERR(mvm, "vif isn't P2P_DEVICE: %d\n", vif->type);
return -EINVAL;
ret = -EINVAL;
goto out_unlock;
}

mutex_lock(&mvm->mutex);

for (i = 0; i < NUM_PHY_CTX; i++) {
phy_ctxt = &mvm->phy_ctxts[i];
if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/mvm/time-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
te_data->running = false;
te_data->vif = NULL;
te_data->uid = 0;
te_data->id = TE_MAX;
} else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
te_data->running = true;
ieee80211_ready_on_channel(mvm->hw); /* Start TE */
Expand Down

0 comments on commit a6cc516

Please sign in to comment.