libertas: Don't sleep inside get_wireless_stats
Marcelo Tosatti
mtosatti at redhat.unroutablecom
Sun Dec 24 04:30:49 EST 2006
Commit: cd0665ce1df6fdcc0034b202ff7d8b45ddaa1d66
Parent: c911ada952d9aaf29309a69edc29a063413fa956
commit cd0665ce1df6fdcc0034b202ff7d8b45ddaa1d66
Author: Marcelo Tosatti <mtosatti at redhat.com>
AuthorDate: Fri Dec 22 18:47:46 2006 -0200
Commit: Marcelo Tosatti <mtosatti at redhat.com>
CommitDate: Fri Dec 22 18:47:46 2006 -0200
libertas: Don't sleep inside get_wireless_stats
get_wireless_stats holds either dev_base_lock (from dev_seq_start,
/proc path) or rtnl_lock (from net ioctl path).
Call RSSI/GET_LOG during association, and use such cached stats. Also
update them by sending RSSI/GET_LOG commands asynchronously.
Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
---
drivers/net/wireless/libertas/wlan_assoc.c | 7 +++
drivers/net/wireless/libertas/wlan_wext.c | 57 +++++++++++++---------------
2 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/drivers/net/wireless/libertas/wlan_assoc.c b/drivers/net/wireless/libertas/wlan_assoc.c
index 485b1e7..f37180d 100644
--- a/drivers/net/wireless/libertas/wlan_assoc.c
+++ b/drivers/net/wireless/libertas/wlan_assoc.c
@@ -506,6 +506,13 @@ dprintk(1, "ASSOC(:%d) wpa_keys: ret = %
dprintk(1, "ASSOC: association attempt successful. "
"Associated to '%s' (" MAC_FMT ")\n",
assoc_req->ssid.Ssid, MAC_ARG(assoc_req->bssid));
+ libertas_prepare_and_send_command(priv,
+ HostCmd_CMD_802_11_RSSI,
+ 0, HostCmd_OPTION_WAITFORRSP, 0, NULL);
+
+ libertas_prepare_and_send_command(priv,
+ HostCmd_CMD_802_11_GET_LOG,
+ 0, HostCmd_OPTION_WAITFORRSP, 0, NULL);
} else {
ret = WLAN_STATUS_FAILURE;
diff --git a/drivers/net/wireless/libertas/wlan_wext.c b/drivers/net/wireless/libertas/wlan_wext.c
index f7c07db..1e25dcc 100644
--- a/drivers/net/wireless/libertas/wlan_wext.c
+++ b/drivers/net/wireless/libertas/wlan_wext.c
@@ -1692,12 +1692,12 @@ static struct iw_statistics *wlan_get_wi
};
wlan_private *priv = dev->priv;
wlan_adapter *Adapter = priv->adapter;
- int ret = WLAN_STATUS_SUCCESS;
u32 rssi_qual;
u32 tx_qual;
u32 quality = 0;
int stats_valid = 0;
u8 rssi;
+ u32 tx_retries;
ENTER();
@@ -1707,13 +1707,6 @@ static struct iw_statistics *wlan_get_wi
if (Adapter->MediaConnectStatus != WlanMediaStateConnected)
goto out;
- /* send RSSI command to get beacon RSSI/NF, valid only if associated */
- ret = libertas_prepare_and_send_command(priv,
- HostCmd_CMD_802_11_RSSI,
- 0, HostCmd_OPTION_WAITFORRSP, 0, NULL);
- if (ret)
- goto out;
-
/* Quality by RSSI */
priv->wstats.qual.level =
CAL_RSSI(Adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
@@ -1746,36 +1739,38 @@ static struct iw_statistics *wlan_get_wi
/* Quality by TX errors */
priv->wstats.discard.retries = priv->stats.tx_errors;
- ret = libertas_prepare_and_send_command(priv, HostCmd_CMD_802_11_GET_LOG,
- 0, HostCmd_OPTION_WAITFORRSP, 0, NULL);
- if (!ret) {
- u32 tx_retries = Adapter->LogMsg.retry;
-
- if (tx_retries > 75)
- tx_qual = (90 - tx_retries) * POOR / 15;
- else if (tx_retries > 70)
- tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
- else if (tx_retries > 65)
- tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
- else if (tx_retries > 50)
- tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
- 15 + GOOD;
- else
- tx_qual = (50 - tx_retries) *
- (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
- quality = min(quality, tx_qual);
- priv->wstats.discard.code = Adapter->LogMsg.wepundecryptable;
- priv->wstats.discard.fragment = Adapter->LogMsg.fcserror;
- priv->wstats.discard.retries = tx_retries;
- priv->wstats.discard.misc = Adapter->LogMsg.ackfailure;
- }
+ tx_retries = Adapter->LogMsg.retry;
+
+ if (tx_retries > 75)
+ tx_qual = (90 - tx_retries) * POOR / 15;
+ else if (tx_retries > 70)
+ tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
+ else if (tx_retries > 65)
+ tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
+ else if (tx_retries > 50)
+ tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
+ 15 + GOOD;
+ else
+ tx_qual = (50 - tx_retries) *
+ (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
+ quality = min(quality, tx_qual);
+
+ priv->wstats.discard.code = Adapter->LogMsg.wepundecryptable;
+ priv->wstats.discard.fragment = Adapter->LogMsg.fcserror;
+ priv->wstats.discard.retries = tx_retries;
+ priv->wstats.discard.misc = Adapter->LogMsg.ackfailure;
/* Calculate quality */
priv->wstats.qual.qual = max(quality, (u32)100);
priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
stats_valid = 1;
+ /* update stats asynchronously for future calls */
+ libertas_prepare_and_send_command(priv, HostCmd_CMD_802_11_RSSI, 0,
+ 0, 0, NULL);
+ libertas_prepare_and_send_command(priv, HostCmd_CMD_802_11_GET_LOG, 0,
+ 0, 0, NULL);
out:
if (!stats_valid) {
priv->wstats.miss.beacon = 0;
More information about the Commits-kernel
mailing list