From: Jerome Pouiller <Jerome.Pouiller@silabs.com>
To: devel@driverdev.osuosl.org, linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"David S . Miller" <davem@davemloft.net>,
Kalle Valo <kvalo@codeaurora.org>
Subject: [PATCH 09/10] staging: wfx: allow to set PTA settings
Date: Tue, 26 May 2020 19:18:20 +0200 [thread overview]
Message-ID: <20200526171821.934581-10-Jerome.Pouiller@silabs.com> (raw)
In-Reply-To: <20200526171821.934581-1-Jerome.Pouiller@silabs.com>
From: Jérôme Pouiller <jerome.pouiller@silabs.com>
The device allows to do Packet Traffic Arbitration (PTA or also Coex)
with other RF chips.
Currently, there is no API to manage the PTA parameters. This patch
provides a vendor extension to nl80211 to change the PTA parameters.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
drivers/staging/wfx/hif_api_general.h | 41 ++++++++++++++++
drivers/staging/wfx/hif_tx.c | 46 +++++++++++++++++
drivers/staging/wfx/hif_tx.h | 5 ++
drivers/staging/wfx/nl80211_vendor.c | 71 +++++++++++++++++++++++++++
drivers/staging/wfx/nl80211_vendor.h | 16 ++++++
drivers/staging/wfx/wfx.h | 4 ++
6 files changed, 183 insertions(+)
diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h
index c8af3534700ca..eb90164ab87c7 100644
--- a/drivers/staging/wfx/hif_api_general.h
+++ b/drivers/staging/wfx/hif_api_general.h
@@ -369,4 +369,45 @@ struct hif_cnf_prevent_rollback {
__le32 status;
} __packed;
+struct hif_req_pta_settings {
+ u8 PtaMode;
+ u8 RequestSignalActiveLevel;
+ u8 PrioritySignalActiveLevel;
+ u8 FreqSignalActiveLevel;
+ u8 GrantSignalActiveLevel;
+ u8 CoexType;
+ u8 DefaultGrantState;
+ u8 SimultaneousRxAccesses;
+ u8 PrioritySamplingTime;
+ u8 TxRxSamplingTime;
+ u8 FreqSamplingTime;
+ u8 GrantValidTime;
+ u8 FemControlTime;
+ u8 FirstSlotTime;
+ __le16 PeriodicTxRxSamplingTime;
+ __le16 CoexQuota;
+ __le16 WlanQuota;
+} __packed;
+
+struct hif_cnf_pta_settings {
+ __le32 status;
+} __packed;
+
+struct hif_req_pta_priority {
+ __le32 priority;
+} __packed;
+
+struct hif_cnf_pta_priority {
+ __le32 status;
+} __packed;
+
+struct hif_req_pta_enable {
+ u8 enable;
+ u8 reserved[3];
+} __packed;
+
+struct hif_cnf_pta_enable {
+ __le32 status;
+} __packed;
+
#endif
diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index 899e1eb71a44b..4cb8fe865e58f 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -535,6 +535,52 @@ int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len)
return ret;
}
+int hif_pta_settings(struct wfx_dev *wdev,
+ const struct hif_req_pta_settings *parms)
+{
+ int ret;
+ struct hif_msg *hif;
+ struct hif_req_pta_settings *body = wfx_alloc_hif(sizeof(*body), &hif);
+
+ if (!hif)
+ return -ENOMEM;
+ memcpy(body, parms, sizeof(*body));
+ wfx_fill_header(hif, -1, HIF_REQ_ID_PTA_SETTINGS, sizeof(*body));
+ ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
+ kfree(hif);
+ return ret;
+}
+
+int hif_pta_priority(struct wfx_dev *wdev, u32 priority)
+{
+ int ret;
+ struct hif_msg *hif;
+ struct hif_req_pta_priority *body = wfx_alloc_hif(sizeof(*body), &hif);
+
+ if (!hif)
+ return -ENOMEM;
+ body->priority = cpu_to_le32(priority);
+ wfx_fill_header(hif, -1, HIF_REQ_ID_PTA_PRIORITY, sizeof(*body));
+ ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
+ kfree(hif);
+ return ret;
+}
+
+int hif_pta_enable(struct wfx_dev *wdev, bool enable)
+{
+ int ret;
+ struct hif_msg *hif;
+ struct hif_req_pta_enable *body = wfx_alloc_hif(sizeof(*body), &hif);
+
+ if (!hif)
+ return -ENOMEM;
+ body->enable = enable;
+ wfx_fill_header(hif, -1, HIF_REQ_ID_PTA_STATE, sizeof(*body));
+ ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
+ kfree(hif);
+ return ret;
+}
+
int hif_burn_prevent_rollback(struct wfx_dev *wdev, u32 magic_word)
{
int ret;
diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h
index d29c72d94789a..f7202be4e7fc6 100644
--- a/drivers/staging/wfx/hif_tx.h
+++ b/drivers/staging/wfx/hif_tx.h
@@ -15,6 +15,7 @@ struct ieee80211_bss_conf;
struct ieee80211_tx_queue_params;
struct cfg80211_scan_request;
struct hif_req_add_key;
+struct hif_req_pta_settings;
struct wfx_dev;
struct wfx_vif;
@@ -57,6 +58,10 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
int hif_beacon_transmit(struct wfx_vif *wvif, bool enable);
int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id);
int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len);
+int hif_pta_settings(struct wfx_dev *wdev,
+ const struct hif_req_pta_settings *parms);
+int hif_pta_priority(struct wfx_dev *wdev, u32 priority);
+int hif_pta_enable(struct wfx_dev *wdev, bool enable);
int hif_burn_prevent_rollback(struct wfx_dev *wdev, u32 magic_word);
int hif_sl_set_mac_key(struct wfx_dev *wdev,
const u8 *slk_key, int destination);
diff --git a/drivers/staging/wfx/nl80211_vendor.c b/drivers/staging/wfx/nl80211_vendor.c
index 1a9d411718a73..d08072adaf9d6 100644
--- a/drivers/staging/wfx/nl80211_vendor.c
+++ b/drivers/staging/wfx/nl80211_vendor.c
@@ -70,3 +70,74 @@ int wfx_nl_burn_antirollback(struct wiphy *wiphy, struct wireless_dev *widev,
return 0;
}
+int wfx_nl_pta_params(struct wiphy *wiphy, struct wireless_dev *widev,
+ const void *data, int data_len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct wfx_dev *wdev = (struct wfx_dev *)hw->priv;
+ int reply_size = nla_total_size(sizeof(wdev->pta_settings)) +
+ nla_total_size(sizeof(u8)) +
+ nla_total_size(sizeof(u32));
+ struct nlattr *tb[WFX_NL80211_ATTR_MAX];
+ bool do_enable = false;
+ struct sk_buff *msg;
+ struct nlattr *nla;
+ int rc;
+
+ rc = nla_parse(tb, WFX_NL80211_ATTR_MAX - 1, data, data_len,
+ wfx_nl_policy, NULL);
+ if (rc)
+ return rc;
+ nla = tb[WFX_NL80211_ATTR_PTA_ENABLE];
+ if (nla) {
+ do_enable = true;
+ wdev->pta_enable = nla_get_u8(tb[WFX_NL80211_ATTR_PTA_ENABLE]);
+ }
+ if (do_enable && !wdev->pta_enable)
+ rc = hif_pta_enable(wdev, wdev->pta_enable);
+ if (rc)
+ return rc;
+ nla = tb[WFX_NL80211_ATTR_PTA_SETTINGS];
+ if (nla) {
+ // User has to care about endianness of data it send.
+ memcpy(&wdev->pta_settings, nla_data(nla),
+ sizeof(wdev->pta_settings));
+ rc = hif_pta_settings(wdev, &wdev->pta_settings);
+ }
+ if (rc)
+ return rc;
+ nla = tb[WFX_NL80211_ATTR_PTA_PRIORITY];
+ if (nla) {
+ wdev->pta_priority =
+ nla_get_u32(tb[WFX_NL80211_ATTR_PTA_PRIORITY]);
+ rc = hif_pta_priority(wdev, wdev->pta_priority);
+ }
+ if (rc)
+ return rc;
+ if (do_enable && wdev->pta_enable)
+ rc = hif_pta_enable(wdev, wdev->pta_enable);
+ if (rc)
+ return rc;
+
+ msg = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, reply_size);
+ if (!msg)
+ return -ENOMEM;
+ rc = nla_put(msg, WFX_NL80211_ATTR_PTA_SETTINGS,
+ sizeof(wdev->pta_settings), &wdev->pta_settings);
+ if (rc)
+ goto error;
+ rc = nla_put_u32(msg, WFX_NL80211_ATTR_PTA_PRIORITY,
+ wdev->pta_priority);
+ if (rc)
+ goto error;
+ rc = nla_put_u8(msg, WFX_NL80211_ATTR_PTA_ENABLE,
+ wdev->pta_enable ? 1 : 0);
+ if (rc)
+ goto error;
+ return cfg80211_vendor_cmd_reply(msg);
+
+error:
+ kfree_skb(msg);
+ return rc;
+}
+
diff --git a/drivers/staging/wfx/nl80211_vendor.h b/drivers/staging/wfx/nl80211_vendor.h
index 49efe8716a654..0ff3bf73f0ad3 100644
--- a/drivers/staging/wfx/nl80211_vendor.h
+++ b/drivers/staging/wfx/nl80211_vendor.h
@@ -18,21 +18,31 @@ int wfx_nl_ps_timeout(struct wiphy *wiphy, struct wireless_dev *widev,
const void *data, int data_len);
int wfx_nl_burn_antirollback(struct wiphy *wiphy, struct wireless_dev *widev,
const void *data, int data_len);
+int wfx_nl_pta_params(struct wiphy *wiphy, struct wireless_dev *widev,
+ const void *data, int data_len);
enum {
WFX_NL80211_SUBCMD_PS_TIMEOUT = 0x10,
WFX_NL80211_SUBCMD_BURN_PREVENT_ROLLBACK = 0x20,
+ WFX_NL80211_SUBCMD_PTA_PARMS = 0x30,
};
enum {
WFX_NL80211_ATTR_PS_TIMEOUT = 1,
WFX_NL80211_ATTR_ROLLBACK_MAGIC = 2,
+ WFX_NL80211_ATTR_PTA_ENABLE = 3,
+ WFX_NL80211_ATTR_PTA_PRIORITY = 4,
+ WFX_NL80211_ATTR_PTA_SETTINGS = 5,
WFX_NL80211_ATTR_MAX
};
static const struct nla_policy wfx_nl_policy[WFX_NL80211_ATTR_MAX] = {
[WFX_NL80211_ATTR_PS_TIMEOUT] = NLA_POLICY_RANGE(NLA_S32, -1, 127),
[WFX_NL80211_ATTR_ROLLBACK_MAGIC] = { .type = NLA_U32 },
+ [WFX_NL80211_ATTR_PTA_ENABLE] = NLA_POLICY_MAX(NLA_U8, 1),
+ [WFX_NL80211_ATTR_PTA_PRIORITY] = { .type = NLA_U32 },
+ [WFX_NL80211_ATTR_PTA_SETTINGS] =
+ NLA_POLICY_EXACT_LEN(sizeof(struct hif_req_pta_settings)),
};
static const struct wiphy_vendor_command wfx_nl80211_vendor_commands[] = {
@@ -49,6 +59,12 @@ static const struct wiphy_vendor_command wfx_nl80211_vendor_commands[] = {
.policy = wfx_nl_policy,
.doit = wfx_nl_burn_antirollback,
.maxattr = WFX_NL80211_ATTR_MAX - 1,
+ }, {
+ .info.vendor_id = WFX_NL80211_ID,
+ .info.subcmd = WFX_NL80211_SUBCMD_PTA_PARMS,
+ .policy = wfx_nl_policy,
+ .doit = wfx_nl_pta_params,
+ .maxattr = WFX_NL80211_ATTR_MAX - 1,
},
};
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index ef68aa4086e01..078f7885bf2fa 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -60,6 +60,10 @@ struct wfx_dev {
struct mutex rx_stats_lock;
struct hif_tx_power_loop_info tx_power_loop_info;
struct mutex tx_power_loop_info_lock;
+
+ bool pta_enable;
+ u32 pta_priority;
+ struct hif_req_pta_settings pta_settings;
};
struct wfx_vif {
--
2.26.2
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
next prev parent reply other threads:[~2020-05-26 17:19 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-26 17:18 [PATCH 00/10] staging: wfx: introduce nl80211 vendor extensions Jerome Pouiller
2020-05-26 17:18 ` [PATCH 01/10] staging: wfx: drop unused variable Jerome Pouiller
2020-05-26 17:18 ` [PATCH 02/10] staging: wfx: do not declare variables inside loops Jerome Pouiller
2020-05-26 17:18 ` [PATCH 03/10] staging: wfx: drop unused function wfx_pending_requeue() Jerome Pouiller
2020-05-26 17:18 ` [PATCH 04/10] staging: wfx: add support for tx_power_loop Jerome Pouiller
2020-05-26 17:18 ` [PATCH 05/10] staging: wfx: retrieve the PS status from the vif Jerome Pouiller
2020-05-26 17:18 ` [PATCH 06/10] staging: wfx: split wfx_get_ps_timeout() from wfx_update_pm() Jerome Pouiller
2020-05-26 17:18 ` [PATCH 07/10] staging: wfx: add support for set/get ps_timeout Jerome Pouiller
2020-05-26 17:18 ` [PATCH 08/10] staging: wfx: allow to burn prevent rollback bit Jerome Pouiller
2020-05-26 17:18 ` Jerome Pouiller [this message]
2020-05-26 17:18 ` [PATCH 10/10] staging: wfx: allow to run nl80211 vendor commands with 'iw' Jerome Pouiller
2020-05-27 8:22 ` [PATCH 00/10] staging: wfx: introduce nl80211 vendor extensions Greg Kroah-Hartman
2020-05-27 12:34 ` Kalle Valo
2020-05-27 13:05 ` Jérôme Pouiller
2020-05-29 15:13 ` 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=20200526171821.934581-10-Jerome.Pouiller@silabs.com \
--to=jerome.pouiller@silabs.com \
--cc=davem@davemloft.net \
--cc=devel@driverdev.osuosl.org \
--cc=gregkh@linuxfoundation.org \
--cc=kvalo@codeaurora.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=netdev@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;
as well as URLs for NNTP newsgroup(s).