From f82ec4d432168b9d20ecc4c51252f31ceddf7945 Mon Sep 17 00:00:00 2001 From: Bartosz Markowski Date: Wed, 29 Feb 2012 15:15:36 +0100 Subject: cw1200: Handle WSM_EVENT_RCPI_RSSI correctly After switch to RCPI based signal level reports a RCPI/RSSI EVNTS have been omitted. This patch fix this and also increse the average count of samples which are used to report signal change. A check has been also added to distinguish in receive indication handler if RCPI needs to be converted to RSSI. ST-Ericsson ID: 419276 ST-Ericsson FOSS-OUT ID: NA Change-Id: I9c0a27181a0d2057db4418878b4b0847f9671372 Signed-off-by: Bartosz Markowski Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/49622 --- drivers/staging/cw1200/ap.c | 2 +- drivers/staging/cw1200/cw1200.h | 1 + drivers/staging/cw1200/sta.c | 25 +++++++++++++++++++++---- drivers/staging/cw1200/wsm.c | 7 ++++++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/staging/cw1200/ap.c b/drivers/staging/cw1200/ap.c index b30afe0ce98..55096cf0e2c 100644 --- a/drivers/staging/cw1200/ap.c +++ b/drivers/staging/cw1200/ap.c @@ -560,7 +560,7 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev, } if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) { struct wsm_rcpi_rssi_threshold threshold = { - .rollingAverageCount = 1, + .rollingAverageCount = 8, }; #if 0 diff --git a/drivers/staging/cw1200/cw1200.h b/drivers/staging/cw1200/cw1200.h index 3ae1b915566..46b8087eaa6 100644 --- a/drivers/staging/cw1200/cw1200.h +++ b/drivers/staging/cw1200/cw1200.h @@ -141,6 +141,7 @@ struct cw1200_common { unsigned cqm_rssi_hyst; unsigned cqm_tx_failure_thold; unsigned cqm_tx_failure_count; + bool cqm_use_rssi; int cqm_link_loss_count; int cqm_beacon_loss_count; int channel_switch_in_progress; diff --git a/drivers/staging/cw1200/sta.c b/drivers/staging/cw1200/sta.c index edce5b436cf..90988e69ce2 100644 --- a/drivers/staging/cw1200/sta.c +++ b/drivers/staging/cw1200/sta.c @@ -997,11 +997,19 @@ void cw1200_event_handler(struct work_struct *work) break; case WSM_EVENT_RCPI_RSSI: { - int rssi = (int)(s8)(event->evt.eventData & 0xFF); - int cqm_evt = (rssi <= priv->cqm_rssi_thold) ? + /* RSSI: signed Q8.0, RCPI: unsigned Q7.1 + * RSSI = RCPI / 2 - 110 */ + int rcpiRssi = (int)(event->evt.eventData & 0xFF); + int cqm_evt; + if (priv->cqm_use_rssi) + rcpiRssi = (s8)rcpiRssi; + else + rcpiRssi = rcpiRssi / 2 - 110; + + cqm_evt = (rcpiRssi <= priv->cqm_rssi_thold) ? NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW : NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; - sta_printk(KERN_DEBUG "[CQM] RSSI event: %d", rssi); + sta_printk(KERN_DEBUG "[CQM] RSSI event: %d", rcpiRssi); ieee80211_cqm_rssi_notify(priv->vif, cqm_evt, GFP_KERNEL); break; @@ -1158,16 +1166,25 @@ static int cw1200_parse_SDD_file(struct cw1200_common *priv) int cw1200_setup_mac(struct cw1200_common *priv) { + int ret = 0; + /* NOTE: There is a bug in FW: it reports signal * as RSSI if RSSI subscription is enabled. * It's not enough to set WSM_RCPI_RSSI_USE_RSSI. */ + /* NOTE2: RSSI based reports have been switched to RCPI, since + * FW has a bug and RSSI reported values are not stable, + * what can leads to signal level oscilations in user-end applications */ struct wsm_rcpi_rssi_threshold threshold = { .rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE | WSM_RCPI_RSSI_DONT_USE_UPPER | WSM_RCPI_RSSI_DONT_USE_LOWER, .rollingAverageCount = 16, }; - int ret = 0; + + /* Remember the decission here to make sure, we will handle + * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS */ + if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI) + priv->cqm_use_rssi = true; if (!priv->sdd) { const char *sdd_path = NULL; diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c index f47950f1d24..245a6400358 100644 --- a/drivers/staging/cw1200/wsm.c +++ b/drivers/staging/cw1200/wsm.c @@ -866,7 +866,7 @@ static int wsm_receive_indication(struct cw1200_common *priv, rx.status = WSM_GET32(buf); rx.channelNumber = WSM_GET16(buf); rx.rxedRate = WSM_GET8(buf); - rx.rcpiRssi = (WSM_GET8(buf) / 2 - 110); + rx.rcpiRssi = WSM_GET8(buf); rx.flags = WSM_GET32(buf); /* FW Workaround: Drop probe resp or @@ -878,6 +878,11 @@ static int wsm_receive_indication(struct cw1200_common *priv, ieee80211_is_beacon(hdr->frame_control))) return 0; + /* If no RSSI subscription has been made, + * convert RCPI to RSSI here */ + if (!priv->cqm_use_rssi) + rx.rcpiRssi = rx.rcpiRssi / 2 - 110; + rx.link_id = link_id; fctl = *(__le16 *)buf->data; hdr_len = buf->data - buf->begin; -- cgit v1.2.3