* [PATCH] libertas: convert RSSI to a direct command
@ 2008-03-13 9:59 Holger Schurig
2008-03-13 14:50 ` Dan Williams
0 siblings, 1 reply; 9+ messages in thread
From: Holger Schurig @ 2008-03-13 9:59 UTC (permalink / raw)
To: libertas-dev; +Cc: Dan Williams, linux-wireless, John W. Linville
Use __lbs_cmd() to get the RSSI values.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Index: wireless-testing/drivers/net/wireless/libertas/cmd.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/cmd.c 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cmd.c 2008-03-13 09:50:26.000000000 +0100
@@ -454,6 +454,65 @@ static int lbs_cmd_802_11_reset(struct l
return 0;
}
+static int lbs_get_rssi_callback(struct lbs_private *priv,
+ unsigned long dummy, struct cmd_header *resp)
+{
+ int ret;
+ struct cmd_ds_802_11_rssi_rsp *rssirsp = (void *) resp;
+
+ ret = le16_to_cpu(rssirsp->hdr.result);
+
+ /* store the non average value */
+ if (!ret) {
+ priv->SNR[TYPE_BEACON][TYPE_NOAVG] =
+ le16_to_cpu(rssirsp->SNR);
+ priv->NF[TYPE_BEACON][TYPE_NOAVG] =
+ le16_to_cpu(rssirsp->noisefloor);
+ priv->SNR[TYPE_BEACON][TYPE_AVG] =
+ le16_to_cpu(rssirsp->avgSNR);
+ priv->NF[TYPE_BEACON][TYPE_AVG] =
+ le16_to_cpu(rssirsp->avgnoisefloor);
+ priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = CAL_RSSI(
+ priv->SNR[TYPE_BEACON][TYPE_NOAVG],
+ priv->NF[TYPE_BEACON][TYPE_NOAVG]);
+ priv->RSSI[TYPE_BEACON][TYPE_AVG] = CAL_RSSI(
+ priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
+ priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
+ lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
+ priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
+ priv->RSSI[TYPE_BEACON][TYPE_AVG]);
+ }
+
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+ return ret;
+}
+
+int lbs_get_rssi(struct lbs_private *priv)
+{
+ struct cmd_ds_802_11_rssi cmd;
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_CMD);
+
+ memset(&cmd, sizeof(cmd), 0);
+ cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+ cmd.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
+
+ /* reset Beacon SNR/NF/RSSI values */
+ priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
+ priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
+ priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
+ priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
+ priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
+ priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
+
+ ret = __lbs_cmd(priv, CMD_802_11_RSSI, &cmd.hdr,
+ sizeof(struct cmd_ds_802_11_rssi_rsp),
+ lbs_get_rssi_callback, 0);
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+ return ret;
+}
+
static int lbs_get_log_callback(struct lbs_private *priv, unsigned long dummy,
struct cmd_header *resp)
{
@@ -484,7 +543,6 @@ int lbs_get_log(struct lbs_private *priv
return ret;
}
-
static int lbs_cmd_802_11_get_stat(struct lbs_private *priv,
struct cmd_ds_command *cmd)
{
@@ -868,27 +926,6 @@ out:
return ret;
}
-static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
- struct cmd_ds_command *cmd)
-{
-
- lbs_deb_enter(LBS_DEB_CMD);
- cmd->command = cpu_to_le16(CMD_802_11_RSSI);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
- cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
-
- /* reset Beacon SNR/NF/RSSI values */
- priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
- priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
- priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
- priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
- priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
- priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
static int lbs_cmd_reg_access(struct lbs_private *priv,
struct cmd_ds_command *cmdptr,
u8 cmd_action, void *pdata_buf)
@@ -1445,10 +1482,6 @@ int lbs_prepare_and_send_command(struct
ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
break;
- case CMD_802_11_RSSI:
- ret = lbs_cmd_802_11_rssi(priv, cmdptr);
- break;
-
case CMD_802_11_AD_HOC_STOP:
ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
break;
Index: wireless-testing/drivers/net/wireless/libertas/cmdresp.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/cmdresp.c 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cmdresp.c 2008-03-13 09:49:57.000000000 +0100
@@ -248,36 +248,6 @@ static int lbs_ret_802_11_rate_adapt_rat
return 0;
}
-static int lbs_ret_802_11_rssi(struct lbs_private *priv,
- struct cmd_ds_command *resp)
-{
- struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- /* store the non average value */
- priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
- priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
-
- priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
- priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
-
- priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
- CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
- priv->NF[TYPE_BEACON][TYPE_NOAVG]);
-
- priv->RSSI[TYPE_BEACON][TYPE_AVG] =
- CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
- priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
-
- lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
- priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
- priv->RSSI[TYPE_BEACON][TYPE_AVG]);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv,
struct cmd_ds_command *resp)
{
@@ -385,10 +355,6 @@ static inline int handle_cmd_response(st
ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
break;
- case CMD_RET(CMD_802_11_RSSI):
- ret = lbs_ret_802_11_rssi(priv, resp);
- break;
-
case CMD_RET(CMD_802_11_MAC_ADDRESS):
ret = lbs_ret_802_11_mac_address(priv, resp);
break;
Index: wireless-testing/drivers/net/wireless/libertas/assoc.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/assoc.c 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/assoc.c 2008-03-13 09:49:57.000000000 +0100
@@ -625,10 +625,7 @@ void lbs_association_worker(struct work_
if (success) {
lbs_deb_assoc("associated to %s\n",
print_mac(mac, priv->curbssparams.bssid));
- lbs_prepare_and_send_command(priv,
- CMD_802_11_RSSI,
- 0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
+ lbs_get_rssi(priv);
lbs_get_log(priv);
} else {
ret = -1;
Index: wireless-testing/drivers/net/wireless/libertas/cmd.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/cmd.h 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cmd.h 2008-03-13 09:49:57.000000000 +0100
@@ -34,6 +34,7 @@ int lbs_cmd_copyback(struct lbs_private
int lbs_update_hw_spec(struct lbs_private *priv);
+int lbs_get_rssi(struct lbs_private *priv);
int lbs_get_log(struct lbs_private *priv);
int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
Index: wireless-testing/drivers/net/wireless/libertas/hostcmd.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/hostcmd.h 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/hostcmd.h 2008-03-13 09:49:57.000000000 +0100
@@ -398,6 +398,8 @@ struct cmd_ds_802_11_rf_channel {
};
struct cmd_ds_802_11_rssi {
+ struct cmd_header hdr;
+
/* weighting factor */
__le16 N;
@@ -407,6 +409,8 @@ struct cmd_ds_802_11_rssi {
};
struct cmd_ds_802_11_rssi_rsp {
+ struct cmd_header hdr;
+
__le16 SNR;
__le16 noisefloor;
__le16 avgSNR;
@@ -700,8 +704,6 @@ struct cmd_ds_command {
struct cmd_ds_802_11_rate_adapt_rateset rateset;
struct cmd_ds_mac_multicast_adr madr;
struct cmd_ds_802_11_ad_hoc_join adj;
- struct cmd_ds_802_11_rssi rssi;
- struct cmd_ds_802_11_rssi_rsp rssirsp;
struct cmd_ds_802_11_disassociate dassociate;
struct cmd_ds_802_11_mac_address macadd;
struct cmd_ds_mac_reg_access macreg;
Index: wireless-testing/drivers/net/wireless/libertas/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/main.c 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/main.c 2008-03-13 09:49:57.000000000 +0100
@@ -487,9 +487,7 @@ static void lbs_tx_timeout(struct net_de
firmware has crapped itself -- rather than just a very
busy medium. So send a harmless command, and if/when
_that_ times out, we'll kick it in the head. */
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- 0, 0, NULL);
-
+ lbs_get_rssi(priv);
lbs_deb_leave(LBS_DEB_TX);
}
@@ -908,8 +906,7 @@ int lbs_resume(struct lbs_private *priv)
/* Firmware doesn't seem to give us RX packets any more
until we send it some command. Might as well update */
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- 0, 0, NULL);
+ lbs_get_rssi(priv);
netif_device_attach(priv->dev);
if (priv->mesh_dev)
Index: wireless-testing/drivers/net/wireless/libertas/scan.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/scan.c 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/scan.c 2008-03-13 09:49:57.000000000 +0100
@@ -1371,8 +1371,7 @@ int lbs_get_scan(struct net_device *dev,
/* Update RSSI if current BSS is a locally created ad-hoc BSS */
if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate)
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- CMD_OPTION_WAITFORRSP, 0, NULL);
+ lbs_get_rssi(priv);
mutex_lock(&priv->lock);
list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
Index: wireless-testing/drivers/net/wireless/libertas/wext.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/wext.c 2008-03-13 09:48:49.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/wext.c 2008-03-13 09:49:57.000000000 +0100
@@ -890,8 +890,7 @@ static struct iw_statistics *lbs_get_wir
stats_valid = 1;
/* update stats asynchronously for future calls */
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- 0, 0, NULL);
+ lbs_get_rssi(priv);
lbs_get_log(priv);
out:
if (!stats_valid) {
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-13 9:59 [PATCH] libertas: convert RSSI to a direct command Holger Schurig
@ 2008-03-13 14:50 ` Dan Williams
0 siblings, 0 replies; 9+ messages in thread
From: Dan Williams @ 2008-03-13 14:50 UTC (permalink / raw)
To: Holger Schurig; +Cc: libertas-dev, linux-wireless, John W. Linville
On Thu, 2008-03-13 at 10:59 +0100, Holger Schurig wrote:
> Use __lbs_cmd() to get the RSSI values.
>
> Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Good patch; one thing we might want to do in the near future is cut the
whole RSSI/NF/SNR mess in half by killing all the TYPE_BEACON bits of
it. The only places that TYPE_BEACON seem to be used are when getting
stats for 'iwconfig' and when returning scanned BSSs for the noise
value. The noise value can certainly be cached _on its own_ in priv->
since it's useful, but I think the rest of it is pretty pointless and we
could just grab it locally in lbs_get_wireless_stats() which is the only
place it's really used. That cleanup can come later of course.
Dan
> Index: wireless-testing/drivers/net/wireless/libertas/cmd.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/cmd.c 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/cmd.c 2008-03-13 09:50:26.000000000 +0100
> @@ -454,6 +454,65 @@ static int lbs_cmd_802_11_reset(struct l
> return 0;
> }
>
> +static int lbs_get_rssi_callback(struct lbs_private *priv,
> + unsigned long dummy, struct cmd_header *resp)
> +{
> + int ret;
> + struct cmd_ds_802_11_rssi_rsp *rssirsp = (void *) resp;
> +
> + ret = le16_to_cpu(rssirsp->hdr.result);
> +
> + /* store the non average value */
> + if (!ret) {
> + priv->SNR[TYPE_BEACON][TYPE_NOAVG] =
> + le16_to_cpu(rssirsp->SNR);
> + priv->NF[TYPE_BEACON][TYPE_NOAVG] =
> + le16_to_cpu(rssirsp->noisefloor);
> + priv->SNR[TYPE_BEACON][TYPE_AVG] =
> + le16_to_cpu(rssirsp->avgSNR);
> + priv->NF[TYPE_BEACON][TYPE_AVG] =
> + le16_to_cpu(rssirsp->avgnoisefloor);
> + priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = CAL_RSSI(
> + priv->SNR[TYPE_BEACON][TYPE_NOAVG],
> + priv->NF[TYPE_BEACON][TYPE_NOAVG]);
> + priv->RSSI[TYPE_BEACON][TYPE_AVG] = CAL_RSSI(
> + priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
> + priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
> + lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
> + priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
> + priv->RSSI[TYPE_BEACON][TYPE_AVG]);
> + }
> +
> + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
> + return ret;
> +}
> +
> +int lbs_get_rssi(struct lbs_private *priv)
> +{
> + struct cmd_ds_802_11_rssi cmd;
> + int ret;
> +
> + lbs_deb_enter(LBS_DEB_CMD);
> +
> + memset(&cmd, sizeof(cmd), 0);
> + cmd.hdr.size = cpu_to_le16(sizeof(cmd));
> + cmd.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
> +
> + /* reset Beacon SNR/NF/RSSI values */
> + priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
> + priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
> + priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
> + priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
> + priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
> + priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
> +
> + ret = __lbs_cmd(priv, CMD_802_11_RSSI, &cmd.hdr,
> + sizeof(struct cmd_ds_802_11_rssi_rsp),
> + lbs_get_rssi_callback, 0);
> + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
> + return ret;
> +}
> +
> static int lbs_get_log_callback(struct lbs_private *priv, unsigned long dummy,
> struct cmd_header *resp)
> {
> @@ -484,7 +543,6 @@ int lbs_get_log(struct lbs_private *priv
> return ret;
> }
>
> -
> static int lbs_cmd_802_11_get_stat(struct lbs_private *priv,
> struct cmd_ds_command *cmd)
> {
> @@ -868,27 +926,6 @@ out:
> return ret;
> }
>
> -static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
> - struct cmd_ds_command *cmd)
> -{
> -
> - lbs_deb_enter(LBS_DEB_CMD);
> - cmd->command = cpu_to_le16(CMD_802_11_RSSI);
> - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
> - cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
> -
> - /* reset Beacon SNR/NF/RSSI values */
> - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
> - priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
> - priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
> - priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
> - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
> - priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
> -
> - lbs_deb_leave(LBS_DEB_CMD);
> - return 0;
> -}
> -
> static int lbs_cmd_reg_access(struct lbs_private *priv,
> struct cmd_ds_command *cmdptr,
> u8 cmd_action, void *pdata_buf)
> @@ -1445,10 +1482,6 @@ int lbs_prepare_and_send_command(struct
> ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
> break;
>
> - case CMD_802_11_RSSI:
> - ret = lbs_cmd_802_11_rssi(priv, cmdptr);
> - break;
> -
> case CMD_802_11_AD_HOC_STOP:
> ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
> break;
> Index: wireless-testing/drivers/net/wireless/libertas/cmdresp.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/cmdresp.c 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/cmdresp.c 2008-03-13 09:49:57.000000000 +0100
> @@ -248,36 +248,6 @@ static int lbs_ret_802_11_rate_adapt_rat
> return 0;
> }
>
> -static int lbs_ret_802_11_rssi(struct lbs_private *priv,
> - struct cmd_ds_command *resp)
> -{
> - struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
> -
> - lbs_deb_enter(LBS_DEB_CMD);
> -
> - /* store the non average value */
> - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
> - priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
> -
> - priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
> - priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
> -
> - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
> - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
> - priv->NF[TYPE_BEACON][TYPE_NOAVG]);
> -
> - priv->RSSI[TYPE_BEACON][TYPE_AVG] =
> - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
> - priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
> -
> - lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
> - priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
> - priv->RSSI[TYPE_BEACON][TYPE_AVG]);
> -
> - lbs_deb_leave(LBS_DEB_CMD);
> - return 0;
> -}
> -
> static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv,
> struct cmd_ds_command *resp)
> {
> @@ -385,10 +355,6 @@ static inline int handle_cmd_response(st
> ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
> break;
>
> - case CMD_RET(CMD_802_11_RSSI):
> - ret = lbs_ret_802_11_rssi(priv, resp);
> - break;
> -
> case CMD_RET(CMD_802_11_MAC_ADDRESS):
> ret = lbs_ret_802_11_mac_address(priv, resp);
> break;
> Index: wireless-testing/drivers/net/wireless/libertas/assoc.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/assoc.c 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/assoc.c 2008-03-13 09:49:57.000000000 +0100
> @@ -625,10 +625,7 @@ void lbs_association_worker(struct work_
> if (success) {
> lbs_deb_assoc("associated to %s\n",
> print_mac(mac, priv->curbssparams.bssid));
> - lbs_prepare_and_send_command(priv,
> - CMD_802_11_RSSI,
> - 0, CMD_OPTION_WAITFORRSP, 0, NULL);
> -
> + lbs_get_rssi(priv);
> lbs_get_log(priv);
> } else {
> ret = -1;
> Index: wireless-testing/drivers/net/wireless/libertas/cmd.h
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/cmd.h 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/cmd.h 2008-03-13 09:49:57.000000000 +0100
> @@ -34,6 +34,7 @@ int lbs_cmd_copyback(struct lbs_private
>
> int lbs_update_hw_spec(struct lbs_private *priv);
>
> +int lbs_get_rssi(struct lbs_private *priv);
> int lbs_get_log(struct lbs_private *priv);
>
> int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
> Index: wireless-testing/drivers/net/wireless/libertas/hostcmd.h
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/hostcmd.h 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/hostcmd.h 2008-03-13 09:49:57.000000000 +0100
> @@ -398,6 +398,8 @@ struct cmd_ds_802_11_rf_channel {
> };
>
> struct cmd_ds_802_11_rssi {
> + struct cmd_header hdr;
> +
> /* weighting factor */
> __le16 N;
>
> @@ -407,6 +409,8 @@ struct cmd_ds_802_11_rssi {
> };
>
> struct cmd_ds_802_11_rssi_rsp {
> + struct cmd_header hdr;
> +
> __le16 SNR;
> __le16 noisefloor;
> __le16 avgSNR;
> @@ -700,8 +704,6 @@ struct cmd_ds_command {
> struct cmd_ds_802_11_rate_adapt_rateset rateset;
> struct cmd_ds_mac_multicast_adr madr;
> struct cmd_ds_802_11_ad_hoc_join adj;
> - struct cmd_ds_802_11_rssi rssi;
> - struct cmd_ds_802_11_rssi_rsp rssirsp;
> struct cmd_ds_802_11_disassociate dassociate;
> struct cmd_ds_802_11_mac_address macadd;
> struct cmd_ds_mac_reg_access macreg;
> Index: wireless-testing/drivers/net/wireless/libertas/main.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/main.c 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/main.c 2008-03-13 09:49:57.000000000 +0100
> @@ -487,9 +487,7 @@ static void lbs_tx_timeout(struct net_de
> firmware has crapped itself -- rather than just a very
> busy medium. So send a harmless command, and if/when
> _that_ times out, we'll kick it in the head. */
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - 0, 0, NULL);
> -
> + lbs_get_rssi(priv);
> lbs_deb_leave(LBS_DEB_TX);
> }
>
> @@ -908,8 +906,7 @@ int lbs_resume(struct lbs_private *priv)
>
> /* Firmware doesn't seem to give us RX packets any more
> until we send it some command. Might as well update */
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - 0, 0, NULL);
> + lbs_get_rssi(priv);
>
> netif_device_attach(priv->dev);
> if (priv->mesh_dev)
> Index: wireless-testing/drivers/net/wireless/libertas/scan.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/scan.c 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/scan.c 2008-03-13 09:49:57.000000000 +0100
> @@ -1371,8 +1371,7 @@ int lbs_get_scan(struct net_device *dev,
>
> /* Update RSSI if current BSS is a locally created ad-hoc BSS */
> if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate)
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - CMD_OPTION_WAITFORRSP, 0, NULL);
> + lbs_get_rssi(priv);
>
> mutex_lock(&priv->lock);
> list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
> Index: wireless-testing/drivers/net/wireless/libertas/wext.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/wext.c 2008-03-13 09:48:49.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/wext.c 2008-03-13 09:49:57.000000000 +0100
> @@ -890,8 +890,7 @@ static struct iw_statistics *lbs_get_wir
> stats_valid = 1;
>
> /* update stats asynchronously for future calls */
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - 0, 0, NULL);
> + lbs_get_rssi(priv);
> lbs_get_log(priv);
> out:
> if (!stats_valid) {
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] libertas: convert RSSI to a direct command
@ 2008-03-18 12:42 Holger Schurig
2008-03-19 14:31 ` Dan Williams
0 siblings, 1 reply; 9+ messages in thread
From: Holger Schurig @ 2008-03-18 12:42 UTC (permalink / raw)
To: libertas-dev; +Cc: Dan Williams, linux-wireless, John W. Linville
[PATCH] libertas: convert RSSI to a direct command
Besided the direct conversion of the CMD_802_11_RSSI command, this
patch also changes the following things:
* calls CMD_802_11_RSSI either asynchronously (in the background)
when main.c thinks the firmware is hosed and just want's to
get a command through
* calls CMD_802_11_RSSI synchronously when called to get wireless
statistics.
* don't do in-driver averaging anymore, this and the previous point
eliminates the need for any "struct lbs_private" values
* doesn't magically create a iwe.u.qual.level value in the adhoc
mode anymore. The old code access older SNR/NF values from
older RXPDs, but there that RXPDs could have been hours old.
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Index: wireless-testing/drivers/net/wireless/libertas/cmd.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/cmd.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cmd.c 2008-03-18 11:55:57.000000000 +0100
@@ -671,6 +671,44 @@ static int lbs_cmd_802_11_rate_adapt_rat
return 0;
}
+int lbs_get_rssi(struct lbs_private *priv, u16 *snr, u16 *nf)
+{
+ struct cmd_ds_802_11_rssi cmd;
+ struct cmd_ds_802_11_rssi_rsp rsp;
+ int ret;
+ u16 _snr, _nf;
+
+ lbs_deb_enter(LBS_DEB_CMD);
+
+ cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+ cmd.avg_factor = cpu_to_le16(1);
+ rsp.hdr.size = cpu_to_le16(sizeof(rsp));
+
+ /* main.c might have called us just to un-break a hanging firmware */
+ if (!snr && !nf) {
+ lbs_cmd_async(priv, CMD_802_11_RSSI, &cmd.hdr, sizeof(cmd));
+ return 0;
+ }
+
+ ret = lbs_cmd(priv, CMD_802_11_RSSI,
+ &cmd, lbs_cmd_copyback, (unsigned long) &rsp);
+
+ if (!ret) {
+ _snr = le16_to_cpu(rsp.SNR);
+ _nf = le16_to_cpu(rsp.NF);
+ } else {
+ _snr = 0;
+ _nf = abs(MRVDRV_NF_DEFAULT_SCAN_VALUE);
+ }
+
+ if (*snr) *snr = _snr;
+ if (*nf) *nf = _nf;
+
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+
+ return ret;
+}
+
/**
* @brief Get the current data rate
*
@@ -837,27 +875,6 @@ out:
return ret;
}
-static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
- struct cmd_ds_command *cmd)
-{
-
- lbs_deb_enter(LBS_DEB_CMD);
- cmd->command = cpu_to_le16(CMD_802_11_RSSI);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
- cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
-
- /* reset Beacon SNR/NF/RSSI values */
- priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
- priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
- priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
- priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
- priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
- priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
static int lbs_cmd_reg_access(struct lbs_private *priv,
struct cmd_ds_command *cmdptr,
u8 cmd_action, void *pdata_buf)
@@ -1413,10 +1430,6 @@ int lbs_prepare_and_send_command(struct
ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
break;
- case CMD_802_11_RSSI:
- ret = lbs_cmd_802_11_rssi(priv, cmdptr);
- break;
-
case CMD_802_11_AD_HOC_STOP:
ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
break;
Index: wireless-testing/drivers/net/wireless/libertas/cmdresp.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/cmdresp.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cmdresp.c 2008-03-18 11:52:42.000000000 +0100
@@ -51,15 +51,6 @@ void lbs_mac_event_disconnected(struct l
kfree_skb(priv->currenttxskb);
priv->currenttxskb = NULL;
priv->tx_pending_len = 0;
-
- /* reset SNR/NF/RSSI values */
- memset(priv->SNR, 0x00, sizeof(priv->SNR));
- memset(priv->NF, 0x00, sizeof(priv->NF));
- memset(priv->RSSI, 0x00, sizeof(priv->RSSI));
- memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
- memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
- priv->nextSNRNF = 0;
- priv->numSNRNF = 0;
priv->connect_status = LBS_DISCONNECTED;
/* Clear out associated SSID and BSSID since connection is
@@ -248,36 +239,6 @@ static int lbs_ret_802_11_rate_adapt_rat
return 0;
}
-static int lbs_ret_802_11_rssi(struct lbs_private *priv,
- struct cmd_ds_command *resp)
-{
- struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- /* store the non average value */
- priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
- priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
-
- priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
- priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
-
- priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
- CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
- priv->NF[TYPE_BEACON][TYPE_NOAVG]);
-
- priv->RSSI[TYPE_BEACON][TYPE_AVG] =
- CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
- priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
-
- lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
- priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
- priv->RSSI[TYPE_BEACON][TYPE_AVG]);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv,
struct cmd_ds_command *resp)
{
@@ -385,10 +346,6 @@ static inline int handle_cmd_response(st
ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
break;
- case CMD_RET(CMD_802_11_RSSI):
- ret = lbs_ret_802_11_rssi(priv, resp);
- break;
-
case CMD_RET(CMD_802_11_MAC_ADDRESS):
ret = lbs_ret_802_11_mac_address(priv, resp);
break;
Index: wireless-testing/drivers/net/wireless/libertas/hostcmd.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/hostcmd.h 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/hostcmd.h 2008-03-18 12:05:30.000000000 +0100
@@ -411,19 +411,21 @@ struct cmd_ds_802_11_rf_channel {
};
struct cmd_ds_802_11_rssi {
- /* weighting factor */
- __le16 N;
+ struct cmd_header hdr;
+ __le16 avg_factor;
__le16 reserved_0;
__le16 reserved_1;
__le16 reserved_2;
};
struct cmd_ds_802_11_rssi_rsp {
+ struct cmd_header hdr;
+
__le16 SNR;
- __le16 noisefloor;
+ __le16 NF;
__le16 avgSNR;
- __le16 avgnoisefloor;
+ __le16 avgNF;
};
struct cmd_ds_802_11_mac_address {
@@ -713,8 +715,6 @@ struct cmd_ds_command {
struct cmd_ds_802_11_rate_adapt_rateset rateset;
struct cmd_ds_mac_multicast_adr madr;
struct cmd_ds_802_11_ad_hoc_join adj;
- struct cmd_ds_802_11_rssi rssi;
- struct cmd_ds_802_11_rssi_rsp rssirsp;
struct cmd_ds_802_11_disassociate dassociate;
struct cmd_ds_802_11_mac_address macadd;
struct cmd_ds_mac_reg_access macreg;
Index: wireless-testing/drivers/net/wireless/libertas/assoc.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/assoc.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/assoc.c 2008-03-18 11:47:16.000000000 +0100
@@ -621,9 +621,6 @@ void lbs_association_worker(struct work_
if (success) {
lbs_deb_assoc("associated to %s\n",
print_mac(mac, priv->curbssparams.bssid));
- lbs_prepare_and_send_command(priv,
- CMD_802_11_RSSI,
- 0, CMD_OPTION_WAITFORRSP, 0, NULL);
} else {
ret = -1;
}
Index: wireless-testing/drivers/net/wireless/libertas/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/main.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/main.c 2008-03-18 11:47:16.000000000 +0100
@@ -487,8 +487,7 @@ static void lbs_tx_timeout(struct net_de
firmware has crapped itself -- rather than just a very
busy medium. So send a harmless command, and if/when
_that_ times out, we'll kick it in the head. */
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- 0, 0, NULL);
+ lbs_get_rssi(priv, NULL, NULL);
lbs_deb_leave(LBS_DEB_TX);
}
@@ -908,8 +907,7 @@ int lbs_resume(struct lbs_private *priv)
/* Firmware doesn't seem to give us RX packets any more
until we send it some command. Might as well update */
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- 0, 0, NULL);
+ lbs_get_rssi(priv, NULL, NULL);
netif_device_attach(priv->dev);
if (priv->mesh_dev)
Index: wireless-testing/drivers/net/wireless/libertas/scan.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/scan.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/scan.c 2008-03-18 12:10:40.000000000 +0100
@@ -1194,25 +1194,7 @@ static inline char *lbs_translate_scan(s
if (iwe.u.qual.qual > 100)
iwe.u.qual.qual = 100;
- if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
- iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
- } else {
- iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
- }
-
- /* Locally created ad-hoc BSSs won't have beacons if this is the
- * only station in the adhoc network; so get signal strength
- * from receive statistics.
- */
- if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate
- && !lbs_ssid_cmp(priv->curbssparams.ssid,
- priv->curbssparams.ssid_len,
- bss->ssid, bss->ssid_len)) {
- int snr, nf;
- snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
- nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
- iwe.u.qual.level = CAL_RSSI(snr, nf);
- }
+ iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
@@ -1369,11 +1351,6 @@ int lbs_get_scan(struct net_device *dev,
if (priv->scan_channel)
return -EAGAIN;
- /* Update RSSI if current BSS is a locally created ad-hoc BSS */
- if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate)
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- CMD_OPTION_WAITFORRSP, 0, NULL);
-
mutex_lock(&priv->lock);
list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
char *next_ev;
Index: wireless-testing/drivers/net/wireless/libertas/cmd.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/cmd.h 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cmd.h 2008-03-18 11:47:16.000000000 +0100
@@ -34,6 +34,8 @@ int lbs_update_hw_spec(struct lbs_privat
int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
struct cmd_ds_mesh_access *cmd);
+int lbs_get_rssi(struct lbs_private *priv, u16 *snr, u16 *nf);
+
int lbs_get_data_rate(struct lbs_private *priv);
int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
Index: wireless-testing/drivers/net/wireless/libertas/dev.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/dev.h 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/dev.h 2008-03-18 11:47:16.000000000 +0100
@@ -288,15 +288,6 @@ struct lbs_private {
u8 wpa_ie[MAX_WPA_IE_LEN];
u8 wpa_ie_len;
- /** Requested Signal Strength*/
- u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
- u16 NF[MAX_TYPE_B][MAX_TYPE_AVG];
- u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG];
- u8 rawSNR[DEFAULT_DATA_AVG_FACTOR];
- u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
- u16 nextSNRNF;
- u16 numSNRNF;
-
u8 radioon;
u32 preamble;
Index: wireless-testing/drivers/net/wireless/libertas/join.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/join.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/join.c 2008-03-18 11:52:45.000000000 +0100
@@ -752,14 +752,6 @@ int lbs_ret_80211_associate(struct lbs_p
priv->curbssparams.ssid_len = bss->ssid_len;
memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
- priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
- priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
-
- memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
- memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
- priv->nextSNRNF = 0;
- priv->numSNRNF = 0;
-
netif_carrier_on(priv->dev);
if (!priv->tx_pending_len)
netif_wake_queue(priv->dev);
Index: wireless-testing/drivers/net/wireless/libertas/wext.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/wext.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/wext.c 2008-03-18 12:34:39.000000000 +0100
@@ -821,6 +821,7 @@ static struct iw_statistics *lbs_get_wir
u8 rssi;
u32 tx_retries;
struct cmd_ds_802_11_get_log log;
+ u16 snr, nf;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -831,17 +832,11 @@ static struct iw_statistics *lbs_get_wir
(priv->mesh_connect_status != LBS_CONNECTED))
goto out;
- /* Quality by RSSI */
- priv->wstats.qual.level =
- CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
- priv->NF[TYPE_BEACON][TYPE_NOAVG]);
+ lbs_get_rssi(priv, &snr, &nf);
- if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
- priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
- } else {
- priv->wstats.qual.noise =
- CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
- }
+ /* Quality by RSSI */
+ priv->wstats.qual.level = CAL_RSSI(snr, nf);
+ priv->wstats.qual.noise = CAL_NF(nf);
lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise);
@@ -893,9 +888,6 @@ static struct iw_statistics *lbs_get_wir
priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
stats_valid = 1;
- /* update stats asynchronously for future calls */
- lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
- 0, 0, NULL);
out:
if (!stats_valid) {
priv->wstats.miss.beacon = 0;
Index: wireless-testing/drivers/net/wireless/libertas/rx.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/rx.c 2008-03-18 11:38:41.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/rx.c 2008-03-18 12:37:04.000000000 +0100
@@ -39,99 +39,6 @@ static int process_rxed_802_11_packet(st
struct sk_buff *skb);
/**
- * @brief This function computes the avgSNR .
- *
- * @param priv A pointer to struct lbs_private structure
- * @return avgSNR
- */
-static u8 lbs_getavgsnr(struct lbs_private *priv)
-{
- u8 i;
- u16 temp = 0;
- if (priv->numSNRNF == 0)
- return 0;
- for (i = 0; i < priv->numSNRNF; i++)
- temp += priv->rawSNR[i];
- return (u8) (temp / priv->numSNRNF);
-
-}
-
-/**
- * @brief This function computes the AvgNF
- *
- * @param priv A pointer to struct lbs_private structure
- * @return AvgNF
- */
-static u8 lbs_getavgnf(struct lbs_private *priv)
-{
- u8 i;
- u16 temp = 0;
- if (priv->numSNRNF == 0)
- return 0;
- for (i = 0; i < priv->numSNRNF; i++)
- temp += priv->rawNF[i];
- return (u8) (temp / priv->numSNRNF);
-
-}
-
-/**
- * @brief This function save the raw SNR/NF to our internel buffer
- *
- * @param priv A pointer to struct lbs_private structure
- * @param prxpd A pointer to rxpd structure of received packet
- * @return n/a
- */
-static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
-{
- if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR)
- priv->numSNRNF++;
- priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr;
- priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf;
- priv->nextSNRNF++;
- if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
- priv->nextSNRNF = 0;
- return;
-}
-
-/**
- * @brief This function computes the RSSI in received packet.
- *
- * @param priv A pointer to struct lbs_private structure
- * @param prxpd A pointer to rxpd structure of received packet
- * @return n/a
- */
-static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
-{
-
- lbs_deb_enter(LBS_DEB_RX);
-
- lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
- lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
- priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
- priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
-
- priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
- priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
- lbs_save_rawSNRNF(priv, p_rx_pd);
-
- priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE;
- priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE;
- lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
- priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
- priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
-
- priv->RSSI[TYPE_RXPD][TYPE_NOAVG] =
- CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG],
- priv->NF[TYPE_RXPD][TYPE_NOAVG]);
-
- priv->RSSI[TYPE_RXPD][TYPE_AVG] =
- CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
- priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
-
- lbs_deb_leave(LBS_DEB_RX);
-}
-
-/**
* @brief This function processes received packet and forwards it
* to kernel/upper layer
*
@@ -240,8 +147,6 @@ int lbs_process_rxed_packet(struct lbs_p
if (priv->auto_rate)
priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
- lbs_compute_rssi(priv, p_rx_pd);
-
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
@@ -359,7 +264,7 @@ static int process_rxed_802_11_packet(st
/* known values */
radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
/* XXX must check no carryout */
- radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
+ radiotap_hdr.antsignal = CAL_RSSI(prxpd->snr, prxpd->nf);
radiotap_hdr.rx_flags = 0;
if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
@@ -386,8 +291,6 @@ static int process_rxed_802_11_packet(st
if (priv->auto_rate)
priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
- lbs_compute_rssi(priv, prxpd);
-
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-18 12:42 Holger Schurig
@ 2008-03-19 14:31 ` Dan Williams
2008-03-19 15:14 ` Holger Schurig
2008-03-19 16:36 ` Holger Schurig
0 siblings, 2 replies; 9+ messages in thread
From: Dan Williams @ 2008-03-19 14:31 UTC (permalink / raw)
To: Holger Schurig; +Cc: libertas-dev, linux-wireless, John W. Linville
On Tue, 2008-03-18 at 13:42 +0100, Holger Schurig wrote:
> [PATCH] libertas: convert RSSI to a direct command
>
> Besided the direct conversion of the CMD_802_11_RSSI command, this
> patch also changes the following things:
>
> * calls CMD_802_11_RSSI either asynchronously (in the background)
> when main.c thinks the firmware is hosed and just want's to
> get a command through
> * calls CMD_802_11_RSSI synchronously when called to get wireless
> statistics.
> * don't do in-driver averaging anymore, this and the previous point
> eliminates the need for any "struct lbs_private" values
> * doesn't magically create a iwe.u.qual.level value in the adhoc
> mode anymore. The old code access older SNR/NF values from
> older RXPDs, but there that RXPDs could have been hours old.
We do need a qual.level for adhoc though. Unfortunately, there's no way
for userspace to know that the adhoc BSS the card is associated with is
created by the card, or if the card just joined the BSS. We should be
reporting 100% signal strength there or something. We should never be
reporting 0 as a signal strength, because BSSes with a 0 signal strength
don't exist and should never show up in scan results on drivers that
report strength. But of course our currently associated BSS should show
up in scan results, so we have to pick something. This patch would also
mean that even after other stations join, the reported signal strength
of this BSS would _always_ be 0, even though other stations may have
taken over the beaconing responsibility, meaning we could get RSSI for
this BSS.
Second, we really should be reporting the noise for scan results, _not_
the default noise value. We certainly can get the noise results
averaged from past beacons, providing those beacons are recent. That
was probably the intent of the beacon averaging stuff. I might have
been a bit too hasty in suggesting its removal.
I'm willing to let the second one slide at the moment (kill averaging)
because the fix is likely a workqueue that periodically asks the card
for RSSI and keeps a _single_ average instead of the big ugly array.
That's a larger patch though.
But I would like to see the adhoc thing changed before acking this
patch...
Dan
> Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
>
> Index: wireless-testing/drivers/net/wireless/libertas/cmd.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/cmd.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/cmd.c 2008-03-18 11:55:57.000000000 +0100
> @@ -671,6 +671,44 @@ static int lbs_cmd_802_11_rate_adapt_rat
> return 0;
> }
>
> +int lbs_get_rssi(struct lbs_private *priv, u16 *snr, u16 *nf)
> +{
> + struct cmd_ds_802_11_rssi cmd;
> + struct cmd_ds_802_11_rssi_rsp rsp;
> + int ret;
> + u16 _snr, _nf;
> +
> + lbs_deb_enter(LBS_DEB_CMD);
> +
> + cmd.hdr.size = cpu_to_le16(sizeof(cmd));
> + cmd.avg_factor = cpu_to_le16(1);
> + rsp.hdr.size = cpu_to_le16(sizeof(rsp));
> +
> + /* main.c might have called us just to un-break a hanging firmware */
> + if (!snr && !nf) {
> + lbs_cmd_async(priv, CMD_802_11_RSSI, &cmd.hdr, sizeof(cmd));
> + return 0;
> + }
> +
> + ret = lbs_cmd(priv, CMD_802_11_RSSI,
> + &cmd, lbs_cmd_copyback, (unsigned long) &rsp);
> +
> + if (!ret) {
> + _snr = le16_to_cpu(rsp.SNR);
> + _nf = le16_to_cpu(rsp.NF);
> + } else {
> + _snr = 0;
> + _nf = abs(MRVDRV_NF_DEFAULT_SCAN_VALUE);
> + }
> +
> + if (*snr) *snr = _snr;
> + if (*nf) *nf = _nf;
> +
> + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
> +
> + return ret;
> +}
> +
> /**
> * @brief Get the current data rate
> *
> @@ -837,27 +875,6 @@ out:
> return ret;
> }
>
> -static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
> - struct cmd_ds_command *cmd)
> -{
> -
> - lbs_deb_enter(LBS_DEB_CMD);
> - cmd->command = cpu_to_le16(CMD_802_11_RSSI);
> - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
> - cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
> -
> - /* reset Beacon SNR/NF/RSSI values */
> - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
> - priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
> - priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
> - priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
> - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
> - priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
> -
> - lbs_deb_leave(LBS_DEB_CMD);
> - return 0;
> -}
> -
> static int lbs_cmd_reg_access(struct lbs_private *priv,
> struct cmd_ds_command *cmdptr,
> u8 cmd_action, void *pdata_buf)
> @@ -1413,10 +1430,6 @@ int lbs_prepare_and_send_command(struct
> ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
> break;
>
> - case CMD_802_11_RSSI:
> - ret = lbs_cmd_802_11_rssi(priv, cmdptr);
> - break;
> -
> case CMD_802_11_AD_HOC_STOP:
> ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
> break;
> Index: wireless-testing/drivers/net/wireless/libertas/cmdresp.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/cmdresp.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/cmdresp.c 2008-03-18 11:52:42.000000000 +0100
> @@ -51,15 +51,6 @@ void lbs_mac_event_disconnected(struct l
> kfree_skb(priv->currenttxskb);
> priv->currenttxskb = NULL;
> priv->tx_pending_len = 0;
> -
> - /* reset SNR/NF/RSSI values */
> - memset(priv->SNR, 0x00, sizeof(priv->SNR));
> - memset(priv->NF, 0x00, sizeof(priv->NF));
> - memset(priv->RSSI, 0x00, sizeof(priv->RSSI));
> - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
> - memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
> - priv->nextSNRNF = 0;
> - priv->numSNRNF = 0;
> priv->connect_status = LBS_DISCONNECTED;
>
> /* Clear out associated SSID and BSSID since connection is
> @@ -248,36 +239,6 @@ static int lbs_ret_802_11_rate_adapt_rat
> return 0;
> }
>
> -static int lbs_ret_802_11_rssi(struct lbs_private *priv,
> - struct cmd_ds_command *resp)
> -{
> - struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
> -
> - lbs_deb_enter(LBS_DEB_CMD);
> -
> - /* store the non average value */
> - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
> - priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
> -
> - priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
> - priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
> -
> - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
> - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
> - priv->NF[TYPE_BEACON][TYPE_NOAVG]);
> -
> - priv->RSSI[TYPE_BEACON][TYPE_AVG] =
> - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
> - priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
> -
> - lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
> - priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
> - priv->RSSI[TYPE_BEACON][TYPE_AVG]);
> -
> - lbs_deb_leave(LBS_DEB_CMD);
> - return 0;
> -}
> -
> static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv,
> struct cmd_ds_command *resp)
> {
> @@ -385,10 +346,6 @@ static inline int handle_cmd_response(st
> ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
> break;
>
> - case CMD_RET(CMD_802_11_RSSI):
> - ret = lbs_ret_802_11_rssi(priv, resp);
> - break;
> -
> case CMD_RET(CMD_802_11_MAC_ADDRESS):
> ret = lbs_ret_802_11_mac_address(priv, resp);
> break;
> Index: wireless-testing/drivers/net/wireless/libertas/hostcmd.h
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/hostcmd.h 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/hostcmd.h 2008-03-18 12:05:30.000000000 +0100
> @@ -411,19 +411,21 @@ struct cmd_ds_802_11_rf_channel {
> };
>
> struct cmd_ds_802_11_rssi {
> - /* weighting factor */
> - __le16 N;
> + struct cmd_header hdr;
>
> + __le16 avg_factor;
> __le16 reserved_0;
> __le16 reserved_1;
> __le16 reserved_2;
> };
>
> struct cmd_ds_802_11_rssi_rsp {
> + struct cmd_header hdr;
> +
> __le16 SNR;
> - __le16 noisefloor;
> + __le16 NF;
> __le16 avgSNR;
> - __le16 avgnoisefloor;
> + __le16 avgNF;
> };
>
> struct cmd_ds_802_11_mac_address {
> @@ -713,8 +715,6 @@ struct cmd_ds_command {
> struct cmd_ds_802_11_rate_adapt_rateset rateset;
> struct cmd_ds_mac_multicast_adr madr;
> struct cmd_ds_802_11_ad_hoc_join adj;
> - struct cmd_ds_802_11_rssi rssi;
> - struct cmd_ds_802_11_rssi_rsp rssirsp;
> struct cmd_ds_802_11_disassociate dassociate;
> struct cmd_ds_802_11_mac_address macadd;
> struct cmd_ds_mac_reg_access macreg;
> Index: wireless-testing/drivers/net/wireless/libertas/assoc.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/assoc.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/assoc.c 2008-03-18 11:47:16.000000000 +0100
> @@ -621,9 +621,6 @@ void lbs_association_worker(struct work_
> if (success) {
> lbs_deb_assoc("associated to %s\n",
> print_mac(mac, priv->curbssparams.bssid));
> - lbs_prepare_and_send_command(priv,
> - CMD_802_11_RSSI,
> - 0, CMD_OPTION_WAITFORRSP, 0, NULL);
> } else {
> ret = -1;
> }
> Index: wireless-testing/drivers/net/wireless/libertas/main.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/main.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/main.c 2008-03-18 11:47:16.000000000 +0100
> @@ -487,8 +487,7 @@ static void lbs_tx_timeout(struct net_de
> firmware has crapped itself -- rather than just a very
> busy medium. So send a harmless command, and if/when
> _that_ times out, we'll kick it in the head. */
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - 0, 0, NULL);
> + lbs_get_rssi(priv, NULL, NULL);
>
> lbs_deb_leave(LBS_DEB_TX);
> }
> @@ -908,8 +907,7 @@ int lbs_resume(struct lbs_private *priv)
>
> /* Firmware doesn't seem to give us RX packets any more
> until we send it some command. Might as well update */
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - 0, 0, NULL);
> + lbs_get_rssi(priv, NULL, NULL);
>
> netif_device_attach(priv->dev);
> if (priv->mesh_dev)
> Index: wireless-testing/drivers/net/wireless/libertas/scan.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/scan.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/scan.c 2008-03-18 12:10:40.000000000 +0100
> @@ -1194,25 +1194,7 @@ static inline char *lbs_translate_scan(s
> if (iwe.u.qual.qual > 100)
> iwe.u.qual.qual = 100;
>
> - if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
> - iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
> - } else {
> - iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
> - }
> -
> - /* Locally created ad-hoc BSSs won't have beacons if this is the
> - * only station in the adhoc network; so get signal strength
> - * from receive statistics.
> - */
> - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate
> - && !lbs_ssid_cmp(priv->curbssparams.ssid,
> - priv->curbssparams.ssid_len,
> - bss->ssid, bss->ssid_len)) {
> - int snr, nf;
> - snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
> - nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
> - iwe.u.qual.level = CAL_RSSI(snr, nf);
> - }
> + iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
> start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
>
> /* Add encryption capability */
> @@ -1369,11 +1351,6 @@ int lbs_get_scan(struct net_device *dev,
> if (priv->scan_channel)
> return -EAGAIN;
>
> - /* Update RSSI if current BSS is a locally created ad-hoc BSS */
> - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate)
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - CMD_OPTION_WAITFORRSP, 0, NULL);
> -
> mutex_lock(&priv->lock);
> list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
> char *next_ev;
> Index: wireless-testing/drivers/net/wireless/libertas/cmd.h
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/cmd.h 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/cmd.h 2008-03-18 11:47:16.000000000 +0100
> @@ -34,6 +34,8 @@ int lbs_update_hw_spec(struct lbs_privat
> int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
> struct cmd_ds_mesh_access *cmd);
>
> +int lbs_get_rssi(struct lbs_private *priv, u16 *snr, u16 *nf);
> +
> int lbs_get_data_rate(struct lbs_private *priv);
> int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
>
> Index: wireless-testing/drivers/net/wireless/libertas/dev.h
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/dev.h 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/dev.h 2008-03-18 11:47:16.000000000 +0100
> @@ -288,15 +288,6 @@ struct lbs_private {
> u8 wpa_ie[MAX_WPA_IE_LEN];
> u8 wpa_ie_len;
>
> - /** Requested Signal Strength*/
> - u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
> - u16 NF[MAX_TYPE_B][MAX_TYPE_AVG];
> - u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG];
> - u8 rawSNR[DEFAULT_DATA_AVG_FACTOR];
> - u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
> - u16 nextSNRNF;
> - u16 numSNRNF;
> -
> u8 radioon;
> u32 preamble;
>
> Index: wireless-testing/drivers/net/wireless/libertas/join.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/join.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/join.c 2008-03-18 11:52:45.000000000 +0100
> @@ -752,14 +752,6 @@ int lbs_ret_80211_associate(struct lbs_p
> priv->curbssparams.ssid_len = bss->ssid_len;
> memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
>
> - priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
> - priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
> -
> - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
> - memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
> - priv->nextSNRNF = 0;
> - priv->numSNRNF = 0;
> -
> netif_carrier_on(priv->dev);
> if (!priv->tx_pending_len)
> netif_wake_queue(priv->dev);
> Index: wireless-testing/drivers/net/wireless/libertas/wext.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/wext.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/wext.c 2008-03-18 12:34:39.000000000 +0100
> @@ -821,6 +821,7 @@ static struct iw_statistics *lbs_get_wir
> u8 rssi;
> u32 tx_retries;
> struct cmd_ds_802_11_get_log log;
> + u16 snr, nf;
>
> lbs_deb_enter(LBS_DEB_WEXT);
>
> @@ -831,17 +832,11 @@ static struct iw_statistics *lbs_get_wir
> (priv->mesh_connect_status != LBS_CONNECTED))
> goto out;
>
> - /* Quality by RSSI */
> - priv->wstats.qual.level =
> - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
> - priv->NF[TYPE_BEACON][TYPE_NOAVG]);
> + lbs_get_rssi(priv, &snr, &nf);
>
> - if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
> - priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
> - } else {
> - priv->wstats.qual.noise =
> - CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
> - }
> + /* Quality by RSSI */
> + priv->wstats.qual.level = CAL_RSSI(snr, nf);
> + priv->wstats.qual.noise = CAL_NF(nf);
>
> lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
> lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise);
> @@ -893,9 +888,6 @@ static struct iw_statistics *lbs_get_wir
> priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
> stats_valid = 1;
>
> - /* update stats asynchronously for future calls */
> - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
> - 0, 0, NULL);
> out:
> if (!stats_valid) {
> priv->wstats.miss.beacon = 0;
> Index: wireless-testing/drivers/net/wireless/libertas/rx.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/libertas/rx.c 2008-03-18 11:38:41.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/libertas/rx.c 2008-03-18 12:37:04.000000000 +0100
> @@ -39,99 +39,6 @@ static int process_rxed_802_11_packet(st
> struct sk_buff *skb);
>
> /**
> - * @brief This function computes the avgSNR .
> - *
> - * @param priv A pointer to struct lbs_private structure
> - * @return avgSNR
> - */
> -static u8 lbs_getavgsnr(struct lbs_private *priv)
> -{
> - u8 i;
> - u16 temp = 0;
> - if (priv->numSNRNF == 0)
> - return 0;
> - for (i = 0; i < priv->numSNRNF; i++)
> - temp += priv->rawSNR[i];
> - return (u8) (temp / priv->numSNRNF);
> -
> -}
> -
> -/**
> - * @brief This function computes the AvgNF
> - *
> - * @param priv A pointer to struct lbs_private structure
> - * @return AvgNF
> - */
> -static u8 lbs_getavgnf(struct lbs_private *priv)
> -{
> - u8 i;
> - u16 temp = 0;
> - if (priv->numSNRNF == 0)
> - return 0;
> - for (i = 0; i < priv->numSNRNF; i++)
> - temp += priv->rawNF[i];
> - return (u8) (temp / priv->numSNRNF);
> -
> -}
> -
> -/**
> - * @brief This function save the raw SNR/NF to our internel buffer
> - *
> - * @param priv A pointer to struct lbs_private structure
> - * @param prxpd A pointer to rxpd structure of received packet
> - * @return n/a
> - */
> -static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
> -{
> - if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR)
> - priv->numSNRNF++;
> - priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr;
> - priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf;
> - priv->nextSNRNF++;
> - if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
> - priv->nextSNRNF = 0;
> - return;
> -}
> -
> -/**
> - * @brief This function computes the RSSI in received packet.
> - *
> - * @param priv A pointer to struct lbs_private structure
> - * @param prxpd A pointer to rxpd structure of received packet
> - * @return n/a
> - */
> -static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
> -{
> -
> - lbs_deb_enter(LBS_DEB_RX);
> -
> - lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
> - lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
> - priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
> - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
> -
> - priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
> - priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
> - lbs_save_rawSNRNF(priv, p_rx_pd);
> -
> - priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE;
> - priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE;
> - lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
> - priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
> - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
> -
> - priv->RSSI[TYPE_RXPD][TYPE_NOAVG] =
> - CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG],
> - priv->NF[TYPE_RXPD][TYPE_NOAVG]);
> -
> - priv->RSSI[TYPE_RXPD][TYPE_AVG] =
> - CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
> - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
> -
> - lbs_deb_leave(LBS_DEB_RX);
> -}
> -
> -/**
> * @brief This function processes received packet and forwards it
> * to kernel/upper layer
> *
> @@ -240,8 +147,6 @@ int lbs_process_rxed_packet(struct lbs_p
> if (priv->auto_rate)
> priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
>
> - lbs_compute_rssi(priv, p_rx_pd);
> -
> lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
> priv->stats.rx_bytes += skb->len;
> priv->stats.rx_packets++;
> @@ -359,7 +264,7 @@ static int process_rxed_802_11_packet(st
> /* known values */
> radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
> /* XXX must check no carryout */
> - radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
> + radiotap_hdr.antsignal = CAL_RSSI(prxpd->snr, prxpd->nf);
> radiotap_hdr.rx_flags = 0;
> if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
> radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
> @@ -386,8 +291,6 @@ static int process_rxed_802_11_packet(st
> if (priv->auto_rate)
> priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
>
> - lbs_compute_rssi(priv, prxpd);
> -
> lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
> priv->stats.rx_bytes += skb->len;
> priv->stats.rx_packets++;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-19 14:31 ` Dan Williams
@ 2008-03-19 15:14 ` Holger Schurig
2008-03-19 15:27 ` Dan Williams
2008-03-19 16:36 ` Holger Schurig
1 sibling, 1 reply; 9+ messages in thread
From: Holger Schurig @ 2008-03-19 15:14 UTC (permalink / raw)
To: Dan Williams; +Cc: Dan Williams, linux-wireless, John W. Linville
> We do need a qual.level for adhoc though.
Hmm, I don't have really knowledge about ADHOC. If it is only
> We should be reporting 100% signal strength there or something.
then the code for this would probably be something like
if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate
&& !lbs_ssid_cmp(priv->curbssparams.ssid,
priv->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)) {
iwe.u.qual.level = 100;
}
If you think about something different or more complex, it would
be cool if you could help me a bit more :-)
> Second, we really should be reporting the noise for scan
> results, _not_ the default noise value. We certainly can get
> the noise results averaged from past beacons, providing those
> beacons are recent. That was probably the intent of the
> beacon averaging stuff. I might have been a bit too hasty in
> suggesting its removal.
We don't have a noise value for scan results. There is only an
RSSI field in the scan result.
Yes, the GET_RSSI command would give us the noise of received
baecon. *BUT* only for the beacons from the current associated
access point. This has two problems:
* we might not be associated to an AP
* the noise level reported from an associated AP at channel 1
might be very wrong to report the noise level of a scanned AP on
channel 13.
Using averaged noise is useless for other reasons:
* in the case of a moving station the driver doesn't know if the
old data that is used for the average is from the same location
or if the device moved
* the age of the averaged data has not been taken into account.
* and here again driver ignored the fact that noise can be
different on different channels.
So if we don't (1) have noise value for scanning, (2) can't
really average it and (3) you don't to report a default value,
then we can simply turn of the reporting of the noise:
- iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED |
+ IW_QUAL_LEVEL_UPDATED;
"iwlist eth1 scan" then no longer reports the noise.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-19 15:14 ` Holger Schurig
@ 2008-03-19 15:27 ` Dan Williams
2008-03-19 15:44 ` Holger Schurig
2008-03-26 9:21 ` Holger Schurig
0 siblings, 2 replies; 9+ messages in thread
From: Dan Williams @ 2008-03-19 15:27 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-wireless, John W. Linville
On Wed, 2008-03-19 at 16:14 +0100, Holger Schurig wrote:
> > We do need a qual.level for adhoc though.
>
> Hmm, I don't have really knowledge about ADHOC. If it is only
When there is no existing ad-hoc BSS with the requested SSID, a driver
should create an AdHoc BSS with that SSID. It generates a random MAC
address (within a certain range of course) and begins to beacon for that
SSID. If other stations join the ad-hoc BSS, the beaconing
responsibility is handed off between stations according to a certain
interval.
If there is an existing ad-hoc BSS with the requested SSID, the driver
joins the BSS by using the existing BSSID and joining the beacon pool.
Scan results for Ad-Hoc stations are actually received beacons that the
stations themselves are putting out.
> > We should be reporting 100% signal strength there or something.
>
> then the code for this would probably be something like
>
> if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate
> && !lbs_ssid_cmp(priv->curbssparams.ssid,
> priv->curbssparams.ssid_len,
> bss->ssid, bss->ssid_len)) {
> iwe.u.qual.level = 100;
> }
>
> If you think about something different or more complex, it would
> be cool if you could help me a bit more :-)
This is fine for now; but we should in the future track the SNR and NF
from received beacons for this BSS through GET_RSSI and if there is an
acceptable value for that, use it instead.
Otherwise we'll always report 100% for a BSS that we created even if
others have joined and we are not beaconing, because we don't know if
we've gotten beacons from other stations, because we're not tracking the
beacon average for the current BSS using GET_RSSI.
>
> > Second, we really should be reporting the noise for scan
> > results, _not_ the default noise value. We certainly can get
> > the noise results averaged from past beacons, providing those
> > beacons are recent. That was probably the intent of the
> > beacon averaging stuff. I might have been a bit too hasty in
> > suggesting its removal.
>
> We don't have a noise value for scan results. There is only an
> RSSI field in the scan result.
I know.
> Yes, the GET_RSSI command would give us the noise of received
> baecon. *BUT* only for the beacons from the current associated
> access point. This has two problems:
> * we might not be associated to an AP
Right, at which point we'd just use the default.
> * the noise level reported from an associated AP at channel 1
> might be very wrong to report the noise level of a scanned AP on
> channel 13.
True. So I guess on the non-associated channel we'd use the default,
and you can just use the default for now.
>
> Using averaged noise is useless for other reasons:
>
> * in the case of a moving station the driver doesn't know if the
> old data that is used for the average is from the same location
> or if the device moved
> * the age of the averaged data has not been taken into account.
> * and here again driver ignored the fact that noise can be
> different on different channels.
Well, the averaged noise should be a fairly quickly sliding window that
only takes the last few seconds (maybe 30?) into account.
> So if we don't (1) have noise value for scanning, (2) can't
> really average it and (3) you don't to report a default value,
> then we can simply turn of the reporting of the noise:
>
> - iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
> + iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED |
> + IW_QUAL_LEVEL_UPDATED;
>
> "iwlist eth1 scan" then no longer reports the noise.
Yeah, and then you've just screwed over userspace tools that want noise,
like NetworkManager.
---------
My main points were:
1) There are certainly bugs in the current code, no doubt
2) We need to fix the Ad-Hoc code to report signal strength somehow, and
that can only happen by GET_RSSI
3) We can do a lot better (at least on the current channel) for scan
results by using the windowed average of the beacons as reported by
GET_RSSI; this is less important than #2 though
My recommendations:
1) We do need to fix the Ad-Hoc bits somehow, I guess that means
periodically poking GET_RSSI when connected and averaging the result
over the last 30 seconds, weighting recent results more
2) Use the windowed average for 'iwconfig'/SIOCGIWSTATS, the Ad-Hoc scan
result, and scan results on the current channel
3) Use the default noise floor for all channels not the associated
channel
If you like, I'm interested in doing this.
Dan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-19 15:27 ` Dan Williams
@ 2008-03-19 15:44 ` Holger Schurig
2008-03-26 9:21 ` Holger Schurig
1 sibling, 0 replies; 9+ messages in thread
From: Holger Schurig @ 2008-03-19 15:44 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-wireless, John W. Linville
> 1) We do need to fix the Ad-Hoc bits somehow, I guess that
> means periodically poking GET_RSSI when connected and
> averaging the result over the last 30 seconds, weighting
> recent results more
Okay for the periodically poking.
But we don't really need to average by ourselves, the GET_RSSI
has an average weight parameter. We can store this in
priv->avg_rssi and priv->avg_noise to re-use it later.
> 2) Use the windowed average for 'iwconfig'/SIOCGIWSTATS, the
> Ad-Hoc scan result, and scan results on the current channel
The patch as it is doesn't use any averaging
for 'iwconfig'/SIOCGIWSTATS, it just uses the value from
GET_RSSI, which is from the beacons of the associated AP.
Together with the changed (simplified) quality calculation I now
get a fast-enought changing display for a moving station. And
it's no longer jerky as it used to be, despite the missing
averaging. This non-jerkyness might come from the fact that RXPD
packets aren't taken into account anymore. So I'm not sure if
any averaging here will be an improvement, at least not for
moving stations. It might be nicer for an office PC, thought.
I don't have a problem with priv->avg_noise for scan results and
no problem at all what you want to do with AD HOC :-)
>
> 3) Use the default noise floor for all channels not the
> associated channel
>
> If you like, I'm interested in doing this.
>
> Dan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-19 14:31 ` Dan Williams
2008-03-19 15:14 ` Holger Schurig
@ 2008-03-19 16:36 ` Holger Schurig
1 sibling, 0 replies; 9+ messages in thread
From: Holger Schurig @ 2008-03-19 16:36 UTC (permalink / raw)
To: Dan Williams; +Cc: libertas-dev, linux-wireless, John W. Linville
> We do need a qual.level for adhoc though. Unfortunately,
> there's no way for userspace to know that the adhoc BSS the
> card is associated with is created by the card, or if the card
> just joined the BSS. We should be reporting 100% signal
> strength there or something.
Take 2 of the patch does this now.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libertas: convert RSSI to a direct command
2008-03-19 15:27 ` Dan Williams
2008-03-19 15:44 ` Holger Schurig
@ 2008-03-26 9:21 ` Holger Schurig
1 sibling, 0 replies; 9+ messages in thread
From: Holger Schurig @ 2008-03-26 9:21 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-wireless, John W. Linville, libertas-dev
> My recommendations:
>
> 1) We do need to fix the Ad-Hoc bits somehow, I guess that
> means periodically poking GET_RSSI when connected and
> averaging the result over the last 30 seconds, weighting
> recent results more
>
> 2) Use the windowed average for 'iwconfig'/SIOCGIWSTATS, the
> Ad-Hoc scan result, and scan results on the current channel
>
> 3) Use the default noise floor for all channels not the
> associated channel
>
> If you like, I'm interested in doing this.
That's ok for me.
John W. Linville asked me on IRC about the status of this
patch, as he noticed that this patch isn't acked yet. What
do you think about my "[PATCH, take 2] libertas: convert RSSI to
a direct command" patch?
It fixed the obvious point 1). From my point of view, 2) and 3)
are "sugar". It could probably be nice to have this, but in my
experiments (device sitting on the desk and moving around with
several APs) it's not really necessary. So 2) and 3) could maybe
applied as separate patches on top of "take 2".
If you think that the averaging is absolutely needed for AdHoc,
then I'll revive the old convert-rssi patch that didn't kill the
averaging. But I think that's not needed.
However, because of my patches from today, the "take 2" doesn't
apply anymore. But I'll send a "take 3" in a minute :-)
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-03-26 9:24 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-13 9:59 [PATCH] libertas: convert RSSI to a direct command Holger Schurig
2008-03-13 14:50 ` Dan Williams
-- strict thread matches above, loose matches on Subject: below --
2008-03-18 12:42 Holger Schurig
2008-03-19 14:31 ` Dan Williams
2008-03-19 15:14 ` Holger Schurig
2008-03-19 15:27 ` Dan Williams
2008-03-19 15:44 ` Holger Schurig
2008-03-26 9:21 ` Holger Schurig
2008-03-19 16:36 ` Holger Schurig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).