From patchwork Thu Jun 30 08:43:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kalle Valo X-Patchwork-Id: 932172 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5U8iM5p029005 for ; Thu, 30 Jun 2011 08:44:22 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758682Ab1F3IoJ (ORCPT ); Thu, 30 Jun 2011 04:44:09 -0400 Received: from emh06.mail.saunalahti.fi ([62.142.5.116]:33962 "EHLO emh06.mail.saunalahti.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758125Ab1F3IoD (ORCPT ); Thu, 30 Jun 2011 04:44:03 -0400 Received: from saunalahti-vams (vs3-10.mail.saunalahti.fi [62.142.5.94]) by emh06-2.mail.saunalahti.fi (Postfix) with SMTP id B7105C7D85; Thu, 30 Jun 2011 11:44:00 +0300 (EEST) Received: from emh06.mail.saunalahti.fi ([62.142.5.116]) by vs3-10.mail.saunalahti.fi ([62.142.5.94]) with SMTP (gateway) id A024F1B23D0; Thu, 30 Jun 2011 11:44:00 +0300 Received: from localhost6.localdomain6 (a88-115-184-248.elisa-laajakaista.fi [88.115.184.248]) by emh06.mail.saunalahti.fi (Postfix) with ESMTP id 47897E51A6; Thu, 30 Jun 2011 11:43:55 +0300 (EEST) Subject: [PATCH v2] ath6kl: implement testmode rx command To: gregkh@suse.de From: Kalle Valo Cc: devel@linuxdriverproject.org, linux-wireless@vger.kernel.org Date: Thu, 30 Jun 2011 11:43:54 +0300 Message-ID: <20110630084354.5352.83068.stgit@localhost6.localdomain6> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Antivirus: VAMS Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 30 Jun 2011 08:44:23 +0000 (UTC) Add new testmode command for retrieving rx reports from firmware. Signed-off-by: Kalle Valo --- drivers/staging/ath6kl/os/linux/cfg80211.c | 99 ++++++++++++++++++++ .../staging/ath6kl/os/linux/include/ar6000_drv.h | 10 -- drivers/staging/ath6kl/os/linux/include/cfg80211.h | 11 ++ drivers/staging/ath6kl/wmi/wmi.c | 6 + 4 files changed, 114 insertions(+), 12 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 441ae04..5fdda4a 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -1472,6 +1472,7 @@ enum ar6k_testmode_attr { enum ar6k_testmode_cmd { AR6K_TM_CMD_TCMD = 0, + AR6K_TM_CMD_RX_REPORT = 1, }; #define AR6K_TM_DATA_MAX_LEN 5000 @@ -1482,11 +1483,88 @@ static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = { .len = AR6K_TM_DATA_MAX_LEN }, }; +void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf, + int buf_len) +{ + if (down_interruptible(&ar->arSem)) + return; + + kfree(ar->tcmd_rx_report); + + ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL); + ar->tcmd_rx_report_len = buf_len; + + up(&ar->arSem); + + wake_up(&arEvent); +} + +static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf, + int buf_len, struct sk_buff *skb) +{ + int ret = 0; + long left; + + if (down_interruptible(&ar->arSem)) + return -ERESTARTSYS; + + if (ar->arWmiReady == false) { + ret = -EIO; + goto out; + } + + if (ar->bIsDestroyProgress) { + ret = -EBUSY; + goto out; + } + + WARN_ON(ar->tcmd_rx_report != NULL); + WARN_ON(ar->tcmd_rx_report_len > 0); + + if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) { + up(&ar->arSem); + return -EIO; + } + + left = wait_event_interruptible_timeout(arEvent, + ar->tcmd_rx_report != NULL, + wmitimeout * HZ); + + if (left == 0) { + ret = -ETIMEDOUT; + goto out; + } else if (left < 0) { + ret = left; + goto out; + } + + if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) { + ret = -EINVAL; + goto out; + } + + NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len, + ar->tcmd_rx_report); + + kfree(ar->tcmd_rx_report); + ar->tcmd_rx_report = NULL; + +out: + up(&ar->arSem); + + return ret; + +nla_put_failure: + ret = -ENOBUFS; + goto out; +} + static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len) { struct ar6_softc *ar = wiphy_priv(wiphy); struct nlattr *tb[AR6K_TM_ATTR_MAX + 1]; - int err, buf_len; + int err, buf_len, reply_len; + struct sk_buff *skb; void *buf; err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len, @@ -1510,6 +1588,25 @@ static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len) return 0; break; + case AR6K_TM_CMD_RX_REPORT: + if (!tb[AR6K_TM_ATTR_DATA]) + return -EINVAL; + + buf = nla_data(tb[AR6K_TM_ATTR_DATA]); + buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]); + + reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN); + skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len); + if (!skb) + return -ENOMEM; + + err = ar6000_testmode_rx_report(ar, buf, buf_len, skb); + if (err < 0) { + kfree_skb(skb); + return err; + } + + return cfg80211_testmode_reply(skb); default: return -EOPNOTSUPP; } diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 2911ea0..05cc774 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -546,15 +546,9 @@ struct ar6_softc { s8 arMaxRetries; u8 arPhyCapability; #ifdef CONFIG_HOST_TCMD_SUPPORT - u8 tcmdRxReport; - u32 tcmdRxTotalPkt; - s32 tcmdRxRssi; - u32 tcmdPm; u32 arTargetMode; - u32 tcmdRxcrcErrPkt; - u32 tcmdRxsecErrPkt; - u16 tcmdRateCnt[TCMD_MAX_RATES]; - u16 tcmdRateCntShortGuard[TCMD_MAX_RATES]; + void *tcmd_rx_report; + int tcmd_rx_report_len; #endif AR6000_WLAN_STATE arWlanState; struct ar_node_mapping arNodeMap[MAX_NODE_NUM]; diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index 1a6ae97..d525320 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -41,6 +41,17 @@ void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); +#ifdef CONFIG_NL80211_TESTMODE +void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf, + int buf_len); +#else +static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar, + void *buf, int buf_len) +{ +} +#endif + + #endif /* _AR6K_CFG80211_H_ */ diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 4a17f99..c7b5e5c 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -41,6 +41,7 @@ #include "a_debug.h" #include "dbglog_api.h" #include "roaming.h" +#include "cfg80211.h" #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0) @@ -4465,10 +4466,9 @@ wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance) static int wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len) { + ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len); - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - return 0; + return 0; } #endif /* CONFIG_HOST_TCMD_SUPPORT*/