From: Kalle Valo <kvalo@qca.qualcomm.com>
To: ath10k@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 2/7] ath10k: fix add_interface failure handling
Date: Tue, 15 Oct 2013 21:46:50 +0300 [thread overview]
Message-ID: <20131015184650.14123.11865.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20131015184548.14123.56949.stgit@localhost6.localdomain6>
From: Michal Kazior <michal.kazior@tieto.com>
If something failed along add_interface() setup it
was possible to leak a vdev id, vdev and peer.
This could end up with leaked FW state or FW crash
(assuming add_interface() failure wasn't a result of
a crash).
kvalo: rebased, whitespace fixes
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/mac.c | 53 +++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index bc0e17b..16e55bd 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2043,18 +2043,17 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) {
ath10k_warn("Only one monitor interface allowed\n");
ret = -EBUSY;
- goto exit;
+ goto err;
}
bit = ffs(ar->free_vdev_map);
if (bit == 0) {
ret = -EBUSY;
- goto exit;
+ goto err;
}
arvif->vdev_id = bit - 1;
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
- ar->free_vdev_map &= ~(1 << arvif->vdev_id);
if (ar->p2p)
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
@@ -2090,27 +2089,33 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
arvif->vdev_subtype, vif->addr);
if (ret) {
ath10k_warn("WMI vdev create failed: ret %d\n", ret);
- goto exit;
+ goto err;
}
+ ar->free_vdev_map &= ~BIT(arvif->vdev_id);
+
vdev_param = ar->wmi.vdev_param->def_keyid;
ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param,
arvif->def_wep_key_idx);
- if (ret)
+ if (ret) {
ath10k_warn("Failed to set default keyid: %d\n", ret);
+ goto err_vdev_delete;
+ }
vdev_param = ar->wmi.vdev_param->tx_encap_type;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
ATH10K_HW_TXRX_NATIVE_WIFI);
/* 10.X firmware does not support this VDEV parameter. Do not warn */
- if (ret && ret != -EOPNOTSUPP)
+ if (ret && ret != -EOPNOTSUPP) {
ath10k_warn("Failed to set TX encap: %d\n", ret);
+ goto err_vdev_delete;
+ }
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
if (ret) {
ath10k_warn("Failed to create peer for AP: %d\n", ret);
- goto exit;
+ goto err_vdev_delete;
}
}
@@ -2119,39 +2124,61 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
param, value);
- if (ret)
+ if (ret) {
ath10k_warn("Failed to set RX wake policy: %d\n", ret);
+ goto err_peer_delete;
+ }
param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
param, value);
- if (ret)
+ if (ret) {
ath10k_warn("Failed to set TX wake thresh: %d\n", ret);
+ goto err_peer_delete;
+ }
param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
param, value);
- if (ret)
+ if (ret) {
ath10k_warn("Failed to set PSPOLL count: %d\n", ret);
+ goto err_peer_delete;
+ }
}
ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
- if (ret)
+ if (ret) {
ath10k_warn("failed to set rts threshold for vdev %d (%d)\n",
arvif->vdev_id, ret);
+ goto err_peer_delete;
+ }
ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
- if (ret)
+ if (ret) {
ath10k_warn("failed to set frag threshold for vdev %d (%d)\n",
arvif->vdev_id, ret);
+ goto err_peer_delete;
+ }
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
ar->monitor_present = true;
-exit:
mutex_unlock(&ar->conf_mutex);
+ return 0;
+
+err_peer_delete:
+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP)
+ ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
+
+err_vdev_delete:
+ ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
+ ar->free_vdev_map &= ~BIT(arvif->vdev_id);
+
+err:
+ mutex_unlock(&ar->conf_mutex);
+
return ret;
}
next prev parent reply other threads:[~2013-10-15 18:46 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-15 18:46 [PATCH 0/7] ath10k: fix WMI atomic usage Kalle Valo
2013-10-15 18:46 ` [PATCH 1/7] ath10k: use workqueue to set WEP TX key Kalle Valo
2013-10-15 18:46 ` Kalle Valo [this message]
2013-10-15 18:46 ` [PATCH 3/7] ath10k: track vif list internally Kalle Valo
2013-10-15 18:49 ` Kalle Valo
2013-10-15 19:37 ` Michal Kazior
2013-10-16 12:47 ` Kalle Valo
2013-10-15 18:47 ` [PATCH 4/7] ath10k: fix scheduling while atomic config bug Kalle Valo
2013-10-15 18:47 ` [PATCH 5/7] ath10k: remove unnecessary checks Kalle Valo
2013-10-15 18:47 ` [PATCH 6/7] ath10k: fix ath10k_bss_assoc() to not sleep in atomic context Kalle Valo
2013-10-15 18:47 ` [PATCH 7/7] ath10k: add might_sleep() to ath10k_wmi_cmd_send() Kalle Valo
2013-10-16 12:48 ` [PATCH 0/7] ath10k: fix WMI atomic usage Kalle Valo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131015184650.14123.11865.stgit@localhost6.localdomain6 \
--to=kvalo@qca.qualcomm.com \
--cc=ath10k@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox