2019-03-20 10:04:38

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 00/14] qtnfmac: regulatory rework and misc fixes

Hello Kalle and all,

Here is the patch set with fixes and enhancements for qtnfmac driver.
The major changes include the following items:
- regulatory rework patches
- use high priority path for EAPOL frames
- fixes to support multiple cards on the same pcie host

Regards,
Sergey

Igor Mitsyanko (10):
qtnfmac: make regulatory notifier work on per-phy basis
qtnfmac: simplify error reporting in regulatory notifier
qtnfmac: include full channels info to regulatory notifier
qtnfmac: pass complete channel info in regulatory notifier
qtnfmac: flexible regulatory domain registration logic
qtnfmac: allow each MAC to specify its own regulatory rules
qtnfmac: pass DFS region to firmware on region update
qtnfmac: update bands information on CHANGE_INTF command
qtnfmac: send EAPOL frames via control path
qtnfmac: use scan duration param for different scan types

Sergey Matyukevich (4):
qtnfmac: fix core attach error path in pcie backend
qtnfmac: simplify firmware state tracking
qtnfmac: allow changing the netns
qtnfmac: fix debugfs entries for multiple cards on the same host

drivers/net/wireless/quantenna/qtnfmac/bus.h | 25 +-
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 86 +++--
drivers/net/wireless/quantenna/qtnfmac/commands.c | 362 +++++++++++----------
drivers/net/wireless/quantenna/qtnfmac/commands.h | 6 +-
drivers/net/wireless/quantenna/qtnfmac/core.c | 56 +++-
drivers/net/wireless/quantenna/qtnfmac/core.h | 5 +-
drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 36 +-
.../wireless/quantenna/qtnfmac/pcie/pcie_priv.h | 3 +-
.../wireless/quantenna/qtnfmac/pcie/pearl_pcie.c | 23 +-
.../wireless/quantenna/qtnfmac/pcie/topaz_pcie.c | 31 +-
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 85 +++--
.../net/wireless/quantenna/qtnfmac/qlink_util.c | 117 +++++++
.../net/wireless/quantenna/qtnfmac/qlink_util.h | 5 +
13 files changed, 523 insertions(+), 317 deletions(-)

--
2.11.0



2019-03-20 10:04:40

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 02/14] qtnfmac: simplify error reporting in regulatory notifier

From: Igor Mitsyanko <[email protected]>

Error reporting in qtnf_cfg80211_reg_notifier only requires to print
one type of message and an error code. Firmware will report success
for an attempt to set regulatory region to the same value,
so no special handling is required for this case.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 295890b2673c..ae08b37d81d2 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -1005,16 +1005,8 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy,

ret = qtnf_cmd_reg_notify(mac, req);
if (ret) {
- if (ret == -EOPNOTSUPP) {
- pr_warn("reg update not supported\n");
- } else if (ret == -EALREADY) {
- pr_info("regulatory domain is already set to %c%c",
- req->alpha2[0], req->alpha2[1]);
- } else {
- pr_err("failed to update reg domain to %c%c\n",
- req->alpha2[0], req->alpha2[1]);
- }
-
+ pr_err("MAC%u: failed to update region to %c%c: %d\n",
+ mac->macid, req->alpha2[0], req->alpha2[1], ret);
return;
}

--
2.11.0


2019-03-20 10:04:52

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 01/14] qtnfmac: make regulatory notifier work on per-phy basis

From: Igor Mitsyanko <[email protected]>

Wireless core calls regulatory notifier for each wiphy and it only
guarantees that bands info is updated for this particular wiphy prior
to calling a notifier. Hence updating all wiphy which belong to driver
in a single notifier callback is redundant and incorrect.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 32 +++++++----------------
drivers/net/wireless/quantenna/qtnfmac/commands.c | 9 +++----
drivers/net/wireless/quantenna/qtnfmac/commands.h | 2 +-
3 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index dcb0991432f4..295890b2673c 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -993,20 +993,17 @@ static struct cfg80211_ops qtn_cfg80211_ops = {
#endif
};

-static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in,
+static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *req)
{
- struct qtnf_wmac *mac = wiphy_priv(wiphy_in);
- struct qtnf_bus *bus = mac->bus;
- struct wiphy *wiphy;
- unsigned int mac_idx;
+ struct qtnf_wmac *mac = wiphy_priv(wiphy);
enum nl80211_band band;
int ret;

pr_debug("MAC%u: initiator=%d alpha=%c%c\n", mac->macid, req->initiator,
req->alpha2[0], req->alpha2[1]);

- ret = qtnf_cmd_reg_notify(bus, req);
+ ret = qtnf_cmd_reg_notify(mac, req);
if (ret) {
if (ret == -EOPNOTSUPP) {
pr_warn("reg update not supported\n");
@@ -1021,25 +1018,14 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in,
return;
}

- for (mac_idx = 0; mac_idx < QTNF_MAX_MAC; ++mac_idx) {
- if (!(bus->hw_info.mac_bitmap & (1 << mac_idx)))
- continue;
-
- mac = bus->mac[mac_idx];
- if (!mac)
+ for (band = 0; band < NUM_NL80211_BANDS; ++band) {
+ if (!wiphy->bands[band])
continue;

- wiphy = priv_to_wiphy(mac);
-
- for (band = 0; band < NUM_NL80211_BANDS; ++band) {
- if (!wiphy->bands[band])
- continue;
-
- ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]);
- if (ret)
- pr_err("failed to get chan info for mac %u band %u\n",
- mac_idx, band);
- }
+ ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]);
+ if (ret)
+ pr_err("MAC%u: failed to update band %u\n",
+ mac->macid, band);
}
}

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 85a2a58f4c16..9aabba7429ed 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2404,13 +2404,14 @@ int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up)
return ret;
}

-int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req)
+int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req)
{
+ struct qtnf_bus *bus = mac->bus;
struct sk_buff *cmd_skb;
int ret;
struct qlink_cmd_reg_notify *cmd;

- cmd_skb = qtnf_cmd_alloc_new_cmdskb(QLINK_MACID_RSVD, QLINK_VIFID_RSVD,
+ cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
QLINK_CMD_REG_NOTIFY,
sizeof(*cmd));
if (!cmd_skb)
@@ -2449,10 +2450,6 @@ int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req)

qtnf_bus_lock(bus);
ret = qtnf_cmd_send(bus, cmd_skb);
- if (ret)
- goto out;
-
-out:
qtnf_bus_unlock(bus);

return ret;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h b/drivers/net/wireless/quantenna/qtnfmac/commands.h
index 64f0b9dc8a14..050f9a49d16c 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h
@@ -57,7 +57,7 @@ int qtnf_cmd_send_disconnect(struct qtnf_vif *vif,
u16 reason_code);
int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif,
bool up);
-int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req);
+int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req);
int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel,
struct qtnf_chan_stats *stats);
int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,
--
2.11.0


2019-03-20 10:05:00

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 07/14] qtnfmac: pass DFS region to firmware on region update

From: Igor Mitsyanko <[email protected]>

Pass DFS region as requested by regulatory core directly to firmware
so it can initialize radar detection block accordingly.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 15 +++++++++++++++
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 6 ++++--
2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 1a248d9f2e4c..cc7f74333f48 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2376,6 +2376,21 @@ int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req)
break;
}

+ switch (req->dfs_region) {
+ case NL80211_DFS_FCC:
+ cmd->dfs_region = QLINK_DFS_FCC;
+ break;
+ case NL80211_DFS_ETSI:
+ cmd->dfs_region = QLINK_DFS_ETSI;
+ break;
+ case NL80211_DFS_JP:
+ cmd->dfs_region = QLINK_DFS_JP;
+ break;
+ default:
+ cmd->dfs_region = QLINK_DFS_UNSET;
+ break;
+ }
+
cmd->num_channels = 0;

for (band = 0; band < NUM_NL80211_BANDS; band++) {
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index 6951f6370985..f6d30069ef3a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -582,6 +582,7 @@ enum qlink_user_reg_hint_type {
* of &enum qlink_user_reg_hint_type.
* @num_channels: number of &struct qlink_tlv_channel in a variable portion of a
* payload.
+ * @dfs_region: one of &enum qlink_dfs_regions.
* @info: variable portion of regulatory notifier callback.
*/
struct qlink_cmd_reg_notify {
@@ -590,7 +591,8 @@ struct qlink_cmd_reg_notify {
u8 initiator;
u8 user_reg_hint_type;
u8 num_channels;
- u8 rsvd[3];
+ u8 dfs_region;
+ u8 rsvd[2];
u8 info[0];
} __packed;

@@ -800,7 +802,7 @@ enum qlink_dfs_regions {
* @alpha2: country code ID firmware is configured to.
* @n_reg_rules: number of regulatory rules TLVs in variable portion of the
* message.
- * @dfs_region: regulatory DFS region, one of @enum qlink_dfs_region.
+ * @dfs_region: regulatory DFS region, one of &enum qlink_dfs_regions.
* @var_info: variable-length WMAC info data.
*/
struct qlink_resp_get_mac_info {
--
2.11.0


2019-03-20 10:05:03

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 04/14] qtnfmac: pass complete channel info in regulatory notifier

From: Igor Mitsyanko <[email protected]>

Currently only a portion of per-channel information is passed to
firmware. Extend logic to pass all useful per-channel data.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 49 +++++++------------
.../net/wireless/quantenna/qtnfmac/qlink_util.c | 55 ++++++++++++++++++++++
.../net/wireless/quantenna/qtnfmac/qlink_util.h | 3 ++
3 files changed, 76 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index b1b622019f12..e61bec7c5d8a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -1709,21 +1709,7 @@ int qtnf_cmd_band_info_get(struct qtnf_wmac *mac,
struct qlink_resp_band_info_get *resp;
size_t info_len = 0;
int ret = 0;
- u8 qband;
-
- switch (band->band) {
- case NL80211_BAND_2GHZ:
- qband = QLINK_BAND_2GHZ;
- break;
- case NL80211_BAND_5GHZ:
- qband = QLINK_BAND_5GHZ;
- break;
- case NL80211_BAND_60GHZ:
- qband = QLINK_BAND_60GHZ;
- break;
- default:
- return -EINVAL;
- }
+ u8 qband = qlink_utils_band_cfg2q(band->band);

cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
QLINK_CMD_BAND_INFO_GET,
@@ -2107,22 +2093,23 @@ int qtnf_cmd_send_del_sta(struct qtnf_vif *vif,
static void qtnf_cmd_channel_tlv_add(struct sk_buff *cmd_skb,
const struct ieee80211_channel *sc)
{
- struct qlink_tlv_channel *qchan;
- u32 flags = 0;
-
- qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
- qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
- qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - sizeof(qchan->hdr));
- qchan->chan.center_freq = cpu_to_le16(sc->center_freq);
- qchan->chan.hw_value = cpu_to_le16(sc->hw_value);
-
- if (sc->flags & IEEE80211_CHAN_NO_IR)
- flags |= QLINK_CHAN_NO_IR;
-
- if (sc->flags & IEEE80211_CHAN_RADAR)
- flags |= QLINK_CHAN_RADAR;
-
- qchan->chan.flags = cpu_to_le32(flags);
+ struct qlink_tlv_channel *tlv;
+ struct qlink_channel *qch;
+
+ tlv = skb_put_zero(cmd_skb, sizeof(*tlv));
+ qch = &tlv->chan;
+ tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
+ tlv->hdr.len = cpu_to_le16(sizeof(*qch));
+
+ qch->center_freq = cpu_to_le16(sc->center_freq);
+ qch->hw_value = cpu_to_le16(sc->hw_value);
+ qch->band = qlink_utils_band_cfg2q(sc->band);
+ qch->max_power = sc->max_power;
+ qch->max_reg_power = sc->max_reg_power;
+ qch->max_antenna_gain = sc->max_antenna_gain;
+ qch->beacon_found = sc->beacon_found;
+ qch->dfs_state = qlink_utils_dfs_state_cfg2q(sc->dfs_state);
+ qch->flags = cpu_to_le32(qlink_utils_chflags_cfg2q(sc->flags));
}

static void qtnf_cmd_randmac_tlv_add(struct sk_buff *cmd_skb,
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
index 72bfd17cb687..8cae9d8d1ab6 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
@@ -182,3 +182,58 @@ void qlink_acl_data_cfg2q(const struct cfg80211_acl_data *acl,
memcpy(qacl->mac_addrs, acl->mac_addrs,
acl->n_acl_entries * sizeof(*qacl->mac_addrs));
}
+
+enum qlink_band qlink_utils_band_cfg2q(enum nl80211_band band)
+{
+ switch (band) {
+ case NL80211_BAND_2GHZ:
+ return QLINK_BAND_2GHZ;
+ case NL80211_BAND_5GHZ:
+ return QLINK_BAND_5GHZ;
+ case NL80211_BAND_60GHZ:
+ return QLINK_BAND_60GHZ;
+ default:
+ return -EINVAL;
+ }
+}
+
+enum qlink_dfs_state qlink_utils_dfs_state_cfg2q(enum nl80211_dfs_state state)
+{
+ switch (state) {
+ case NL80211_DFS_USABLE:
+ return QLINK_DFS_USABLE;
+ case NL80211_DFS_AVAILABLE:
+ return QLINK_DFS_AVAILABLE;
+ case NL80211_DFS_UNAVAILABLE:
+ default:
+ return QLINK_DFS_UNAVAILABLE;
+ }
+}
+
+u32 qlink_utils_chflags_cfg2q(u32 cfgflags)
+{
+ u32 flags = 0;
+
+ if (cfgflags & IEEE80211_CHAN_DISABLED)
+ flags |= QLINK_CHAN_DISABLED;
+
+ if (cfgflags & IEEE80211_CHAN_NO_IR)
+ flags |= QLINK_CHAN_NO_IR;
+
+ if (cfgflags & IEEE80211_CHAN_RADAR)
+ flags |= QLINK_CHAN_RADAR;
+
+ if (cfgflags & IEEE80211_CHAN_NO_HT40PLUS)
+ flags |= QLINK_CHAN_NO_HT40PLUS;
+
+ if (cfgflags & IEEE80211_CHAN_NO_HT40MINUS)
+ flags |= QLINK_CHAN_NO_HT40MINUS;
+
+ if (cfgflags & IEEE80211_CHAN_NO_80MHZ)
+ flags |= QLINK_CHAN_NO_80MHZ;
+
+ if (cfgflags & IEEE80211_CHAN_NO_160MHZ)
+ flags |= QLINK_CHAN_NO_160MHZ;
+
+ return flags;
+}
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
index 781ea7fe79f2..9d10a2098ca7 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
@@ -79,5 +79,8 @@ bool qtnf_utils_is_bit_set(const u8 *arr, unsigned int bit,
unsigned int arr_max_len);
void qlink_acl_data_cfg2q(const struct cfg80211_acl_data *acl,
struct qlink_acl_data *qacl);
+enum qlink_band qlink_utils_band_cfg2q(enum nl80211_band band);
+enum qlink_dfs_state qlink_utils_dfs_state_cfg2q(enum nl80211_dfs_state state);
+u32 qlink_utils_chflags_cfg2q(u32 cfgflags);

#endif /* _QTN_FMAC_QLINK_UTIL_H_ */
--
2.11.0


2019-03-20 10:05:13

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 03/14] qtnfmac: include full channels info to regulatory notifier

From: Igor Mitsyanko <[email protected]>

Before regulatory notifier is invoked by a wireless core, it will
update band information for the wiphy. Pass this information to
firmware together with new region alpha2 code.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 20 ++++++++++++++++++++
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 8 +++++++-
2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 9aabba7429ed..b1b622019f12 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2406,10 +2406,13 @@ int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif, bool up)

int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req)
{
+ struct wiphy *wiphy = priv_to_wiphy(mac);
struct qtnf_bus *bus = mac->bus;
struct sk_buff *cmd_skb;
int ret;
struct qlink_cmd_reg_notify *cmd;
+ enum nl80211_band band;
+ const struct ieee80211_supported_band *cfg_band;

cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, QLINK_VIFID_RSVD,
QLINK_CMD_REG_NOTIFY,
@@ -2448,6 +2451,23 @@ int qtnf_cmd_reg_notify(struct qtnf_wmac *mac, struct regulatory_request *req)
break;
}

+ cmd->num_channels = 0;
+
+ for (band = 0; band < NUM_NL80211_BANDS; band++) {
+ unsigned int i;
+
+ cfg_band = wiphy->bands[band];
+ if (!cfg_band)
+ continue;
+
+ cmd->num_channels += cfg_band->n_channels;
+
+ for (i = 0; i < cfg_band->n_channels; ++i) {
+ qtnf_cmd_channel_tlv_add(cmd_skb,
+ &cfg_band->channels[i]);
+ }
+ }
+
qtnf_bus_lock(bus);
ret = qtnf_cmd_send(bus, cmd_skb);
qtnf_bus_unlock(bus);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index 7798edcf7980..ca84684a1a93 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -6,7 +6,7 @@

#include <linux/ieee80211.h>

-#define QLINK_PROTO_VER 13
+#define QLINK_PROTO_VER 14

#define QLINK_MACID_RSVD 0xFF
#define QLINK_VIFID_RSVD 0xFF
@@ -580,12 +580,18 @@ enum qlink_user_reg_hint_type {
* @initiator: which entity sent the request, one of &enum qlink_reg_initiator.
* @user_reg_hint_type: type of hint for QLINK_REGDOM_SET_BY_USER request, one
* of &enum qlink_user_reg_hint_type.
+ * @num_channels: number of &struct qlink_tlv_channel in a variable portion of a
+ * payload.
+ * @info: variable portion of regulatory notifier callback.
*/
struct qlink_cmd_reg_notify {
struct qlink_cmd chdr;
u8 alpha2[2];
u8 initiator;
u8 user_reg_hint_type;
+ u8 num_channels;
+ u8 rsvd[3];
+ u8 info[0];
} __packed;

/**
--
2.11.0


2019-03-20 10:05:13

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 05/14] qtnfmac: flexible regulatory domain registration logic

From: Igor Mitsyanko <[email protected]>

Use REGULATORY_CUSTOM_REG flag only if firmware advertised a custom
regulatory domain prior to wiphy registration. Use REGULATORY_STRICT_REG
flag only if firmware knows its regulatory domain.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index ae08b37d81d2..3131ced8801f 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -1073,6 +1073,7 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
struct wiphy *wiphy = priv_to_wiphy(mac);
struct qtnf_mac_info *macinfo = &mac->macinfo;
int ret;
+ bool regdomain_is_known;

if (!wiphy) {
pr_err("invalid wiphy pointer\n");
@@ -1144,11 +1145,20 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
wiphy->wowlan = macinfo->wowlan;
#endif

+ regdomain_is_known = isalpha(hw_info->rd->alpha2[0]) &&
+ isalpha(hw_info->rd->alpha2[1]);
+
if (hw_info->hw_capab & QLINK_HW_CAPAB_REG_UPDATE) {
- wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
- REGULATORY_CUSTOM_REG;
wiphy->reg_notifier = qtnf_cfg80211_reg_notifier;
- wiphy_apply_custom_regulatory(wiphy, hw_info->rd);
+
+ if (hw_info->rd->alpha2[0] == '9' &&
+ hw_info->rd->alpha2[1] == '9') {
+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+ REGULATORY_STRICT_REG;
+ wiphy_apply_custom_regulatory(wiphy, hw_info->rd);
+ } else if (regdomain_is_known) {
+ wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
+ }
} else {
wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
}
@@ -1172,8 +1182,7 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)

if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
ret = regulatory_set_wiphy_regd(wiphy, hw_info->rd);
- else if (isalpha(hw_info->rd->alpha2[0]) &&
- isalpha(hw_info->rd->alpha2[1]))
+ else if (regdomain_is_known)
ret = regulatory_hint(wiphy, hw_info->rd->alpha2);

out:
--
2.11.0


2019-03-20 10:05:18

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

Fix creation of debugfs entries for qtnfmac wireless card: use separate
directories for different wireless cards. This commit enables support
for multiple qtnfmac wireless cards on the same PCIe host.

Signed-off-by: Sergey Matyukevich <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
index b561b75e4433..56fc6d49c121 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
@@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)

int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
{
+ struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
+ char card_id[64];
int ret;

bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
@@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
if (ret) {
pr_err("failed to attach core\n");
} else {
- qtnf_debugfs_init(bus, DRV_NAME);
+ snprintf(card_id, sizeof(card_id), "%s:%s",
+ DRV_NAME, pci_name(priv->pdev));
+ qtnf_debugfs_init(bus, card_id);
qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show);
qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show);
qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats);
--
2.11.0


2019-03-20 10:05:21

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 10/14] qtnfmac: simplify firmware state tracking

This patch streamlines firmware state tracking. In particular, state
QTNF_FW_STATE_FW_DNLD_DONE is removed, states QTNF_FW_STATE_RESET and
QTNF_FW_STATE_DETACHED are merged into a single state. Besides, new
state QTNF_FW_STATE_RUNNING is introduced to distinguish between
the following two cases:
- firmware load succeeded, firmware init process is ongoing
- firmware init succeeded, firmware is fully functional

Signed-off-by: Sergey Matyukevich <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/bus.h | 24 ++++++++++++++++++----
drivers/net/wireless/quantenna/qtnfmac/commands.c | 3 +--
drivers/net/wireless/quantenna/qtnfmac/core.c | 8 +++++---
drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 10 ++++-----
4 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/bus.h b/drivers/net/wireless/quantenna/qtnfmac/bus.h
index 14b569b6d1b5..dc1bd32d4827 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/bus.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/bus.h
@@ -13,12 +13,11 @@
#define QTNF_MAX_MAC 3

enum qtnf_fw_state {
- QTNF_FW_STATE_RESET,
- QTNF_FW_STATE_FW_DNLD_DONE,
+ QTNF_FW_STATE_DETACHED,
QTNF_FW_STATE_BOOT_DONE,
QTNF_FW_STATE_ACTIVE,
- QTNF_FW_STATE_DETACHED,
- QTNF_FW_STATE_EP_DEAD,
+ QTNF_FW_STATE_RUNNING,
+ QTNF_FW_STATE_DEAD,
};

struct qtnf_bus;
@@ -58,6 +57,23 @@ struct qtnf_bus {
char bus_priv[0] __aligned(sizeof(void *));
};

+static inline bool qtnf_fw_is_up(struct qtnf_bus *bus)
+{
+ enum qtnf_fw_state state = bus->fw_state;
+
+ return ((state == QTNF_FW_STATE_ACTIVE) ||
+ (state == QTNF_FW_STATE_RUNNING));
+}
+
+static inline bool qtnf_fw_is_attached(struct qtnf_bus *bus)
+{
+ enum qtnf_fw_state state = bus->fw_state;
+
+ return ((state == QTNF_FW_STATE_ACTIVE) ||
+ (state == QTNF_FW_STATE_RUNNING) ||
+ (state == QTNF_FW_STATE_DEAD));
+}
+
static inline void *get_bus_priv(struct qtnf_bus *bus)
{
if (WARN(!bus, "qtnfmac: invalid bus pointer"))
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 2e658e394dc6..a04321305ebc 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -89,8 +89,7 @@ static int qtnf_cmd_send_with_reply(struct qtnf_bus *bus,

pr_debug("VIF%u.%u cmd=0x%.4X\n", mac_id, vif_id, cmd_id);

- if (bus->fw_state != QTNF_FW_STATE_ACTIVE &&
- cmd_id != QLINK_CMD_FW_INIT) {
+ if (!qtnf_fw_is_up(bus) && cmd_id != QLINK_CMD_FW_INIT) {
pr_warn("VIF%u.%u: drop cmd 0x%.4X in fw state %d\n",
mac_id, vif_id, cmd_id, bus->fw_state);
dev_kfree_skb(cmd_skb);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c
index f04f4e1f7d68..eed12e4dec65 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -589,8 +589,6 @@ int qtnf_core_attach(struct qtnf_bus *bus)
int ret;

qtnf_trans_init(bus);
-
- bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
qtnf_bus_data_rx_start(bus);

bus->workqueue = alloc_ordered_workqueue("QTNF_BUS", 0);
@@ -639,6 +637,7 @@ int qtnf_core_attach(struct qtnf_bus *bus)
}
}

+ bus->fw_state = QTNF_FW_STATE_RUNNING;
return 0;

error:
@@ -657,7 +656,7 @@ void qtnf_core_detach(struct qtnf_bus *bus)
for (macid = 0; macid < QTNF_MAX_MAC; macid++)
qtnf_core_mac_detach(bus, macid);

- if (bus->fw_state == QTNF_FW_STATE_ACTIVE)
+ if (qtnf_fw_is_up(bus))
qtnf_cmd_send_deinit_fw(bus);

bus->fw_state = QTNF_FW_STATE_DETACHED;
@@ -683,6 +682,9 @@ struct net_device *qtnf_classify_skb(struct qtnf_bus *bus, struct sk_buff *skb)
struct qtnf_wmac *mac;
struct qtnf_vif *vif;

+ if (unlikely(bus->fw_state != QTNF_FW_STATE_RUNNING))
+ return NULL;
+
meta = (struct qtnf_frame_meta_info *)
(skb_tail_pointer(skb) - sizeof(*meta));

diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
index a693667a83d7..b561b75e4433 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
@@ -56,7 +56,7 @@ int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb)

if (ret == -ETIMEDOUT) {
pr_err("EP firmware is dead\n");
- bus->fw_state = QTNF_FW_STATE_EP_DEAD;
+ bus->fw_state = QTNF_FW_STATE_DEAD;
}

return ret;
@@ -132,11 +132,10 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
{
int ret;

- bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE;
+ bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
ret = qtnf_core_attach(bus);
if (ret) {
pr_err("failed to attach core\n");
- bus->fw_state = QTNF_FW_STATE_DETACHED;
} else {
qtnf_debugfs_init(bus, DRV_NAME);
qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show);
@@ -335,7 +334,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pcie_priv = get_bus_priv(bus);
pci_set_drvdata(pdev, bus);
bus->dev = &pdev->dev;
- bus->fw_state = QTNF_FW_STATE_RESET;
+ bus->fw_state = QTNF_FW_STATE_DETACHED;
pcie_priv->pdev = pdev;
pcie_priv->tx_stopped = 0;
pcie_priv->rx_bd_num = rx_bd_size_param;
@@ -410,8 +409,7 @@ static void qtnf_pcie_remove(struct pci_dev *dev)

cancel_work_sync(&bus->fw_work);

- if (bus->fw_state == QTNF_FW_STATE_ACTIVE ||
- bus->fw_state == QTNF_FW_STATE_EP_DEAD)
+ if (qtnf_fw_is_attached(bus))
qtnf_core_detach(bus);

netif_napi_del(&bus->mux_napi);
--
2.11.0


2019-03-20 10:05:22

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 08/14] qtnfmac: update bands information on CHANGE_INTF command

From: Igor Mitsyanko <[email protected]>

In some regions, different regulatory limits (like max Tx power) may be
defined for different operating modes. As an example: in ETSI regions
DFS master devices may use higher transmit powers compared to DFS slave
devices. Update bands information in CHANGE_INTF command if mode of
operation changes.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index cc7f74333f48..2e658e394dc6 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -786,8 +786,25 @@ int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
int use4addr,
u8 *mac_addr)
{
- return qtnf_cmd_send_add_change_intf(vif, iftype, use4addr, mac_addr,
- QLINK_CMD_CHANGE_INTF);
+ int ret;
+
+ ret = qtnf_cmd_send_add_change_intf(vif, iftype, use4addr, mac_addr,
+ QLINK_CMD_CHANGE_INTF);
+
+ /* Regulatory settings may be different for different interface types */
+ if (ret == 0 && vif->wdev.iftype != iftype) {
+ enum nl80211_band band;
+ struct wiphy *wiphy = priv_to_wiphy(vif->mac);
+
+ for (band = 0; band < NUM_NL80211_BANDS; ++band) {
+ if (!wiphy->bands[band])
+ continue;
+
+ qtnf_cmd_band_info_get(vif->mac, wiphy->bands[band]);
+ }
+ }
+
+ return ret;
}

int qtnf_cmd_send_del_intf(struct qtnf_vif *vif)
--
2.11.0


2019-03-20 10:05:23

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 06/14] qtnfmac: allow each MAC to specify its own regulatory rules

From: Igor Mitsyanko <[email protected]>

Currently driver uses the same regulatory rules to register all wiphy
instances. This is not logically correct since each wiphy may have
different capabilities (different supported bands, EIRP etc).
Allow firmware to pass regulatory rules for each MAC separately.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 13 +-
drivers/net/wireless/quantenna/qtnfmac/commands.c | 186 +++++++--------------
drivers/net/wireless/quantenna/qtnfmac/core.c | 5 +-
drivers/net/wireless/quantenna/qtnfmac/core.h | 2 +-
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 42 ++---
.../net/wireless/quantenna/qtnfmac/qlink_util.c | 62 +++++++
.../net/wireless/quantenna/qtnfmac/qlink_util.h | 2 +
7 files changed, 156 insertions(+), 156 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 3131ced8801f..cea948466744 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -1145,17 +1145,16 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
wiphy->wowlan = macinfo->wowlan;
#endif

- regdomain_is_known = isalpha(hw_info->rd->alpha2[0]) &&
- isalpha(hw_info->rd->alpha2[1]);
+ regdomain_is_known = isalpha(mac->rd->alpha2[0]) &&
+ isalpha(mac->rd->alpha2[1]);

if (hw_info->hw_capab & QLINK_HW_CAPAB_REG_UPDATE) {
wiphy->reg_notifier = qtnf_cfg80211_reg_notifier;

- if (hw_info->rd->alpha2[0] == '9' &&
- hw_info->rd->alpha2[1] == '9') {
+ if (mac->rd->alpha2[0] == '9' && mac->rd->alpha2[1] == '9') {
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
REGULATORY_STRICT_REG;
- wiphy_apply_custom_regulatory(wiphy, hw_info->rd);
+ wiphy_apply_custom_regulatory(wiphy, mac->rd);
} else if (regdomain_is_known) {
wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
}
@@ -1181,9 +1180,9 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
goto out;

if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
- ret = regulatory_set_wiphy_regd(wiphy, hw_info->rd);
+ ret = regulatory_set_wiphy_regd(wiphy, mac->rd);
else if (regdomain_is_known)
- ret = regulatory_hint(wiphy, hw_info->rd->alpha2);
+ ret = regulatory_hint(wiphy, mac->rd->alpha2);

out:
return ret;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index e61bec7c5d8a..1a248d9f2e4c 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -831,55 +831,6 @@ int qtnf_cmd_send_del_intf(struct qtnf_vif *vif)
return ret;
}

-static u32 qtnf_cmd_resp_reg_rule_flags_parse(u32 qflags)
-{
- u32 flags = 0;
-
- if (qflags & QLINK_RRF_NO_OFDM)
- flags |= NL80211_RRF_NO_OFDM;
-
- if (qflags & QLINK_RRF_NO_CCK)
- flags |= NL80211_RRF_NO_CCK;
-
- if (qflags & QLINK_RRF_NO_INDOOR)
- flags |= NL80211_RRF_NO_INDOOR;
-
- if (qflags & QLINK_RRF_NO_OUTDOOR)
- flags |= NL80211_RRF_NO_OUTDOOR;
-
- if (qflags & QLINK_RRF_DFS)
- flags |= NL80211_RRF_DFS;
-
- if (qflags & QLINK_RRF_PTP_ONLY)
- flags |= NL80211_RRF_PTP_ONLY;
-
- if (qflags & QLINK_RRF_PTMP_ONLY)
- flags |= NL80211_RRF_PTMP_ONLY;
-
- if (qflags & QLINK_RRF_NO_IR)
- flags |= NL80211_RRF_NO_IR;
-
- if (qflags & QLINK_RRF_AUTO_BW)
- flags |= NL80211_RRF_AUTO_BW;
-
- if (qflags & QLINK_RRF_IR_CONCURRENT)
- flags |= NL80211_RRF_IR_CONCURRENT;
-
- if (qflags & QLINK_RRF_NO_HT40MINUS)
- flags |= NL80211_RRF_NO_HT40MINUS;
-
- if (qflags & QLINK_RRF_NO_HT40PLUS)
- flags |= NL80211_RRF_NO_HT40PLUS;
-
- if (qflags & QLINK_RRF_NO_80MHZ)
- flags |= NL80211_RRF_NO_80MHZ;
-
- if (qflags & QLINK_RRF_NO_160MHZ)
- flags |= NL80211_RRF_NO_160MHZ;
-
- return flags;
-}
-
static int
qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
const struct qlink_resp_get_hw_info *resp,
@@ -887,7 +838,6 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
{
struct qtnf_hw_info *hwinfo = &bus->hw_info;
const struct qlink_tlv_hdr *tlv;
- const struct qlink_tlv_reg_rule *tlv_rule;
const char *bld_name = NULL;
const char *bld_rev = NULL;
const char *bld_type = NULL;
@@ -898,19 +848,8 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
const char *calibration_ver = NULL;
const char *uboot_ver = NULL;
u32 hw_ver = 0;
- struct ieee80211_reg_rule *rule;
u16 tlv_type;
u16 tlv_value_len;
- unsigned int rule_idx = 0;
-
- if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES))
- return -E2BIG;
-
- hwinfo->rd = kzalloc(struct_size(hwinfo->rd, reg_rules,
- resp->n_reg_rules), GFP_KERNEL);
-
- if (!hwinfo->rd)
- return -ENOMEM;

hwinfo->num_mac = resp->num_mac;
hwinfo->mac_bitmap = resp->mac_bitmap;
@@ -919,30 +858,11 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
hwinfo->total_tx_chain = resp->total_tx_chain;
hwinfo->total_rx_chain = resp->total_rx_chain;
hwinfo->hw_capab = le32_to_cpu(resp->hw_capab);
- hwinfo->rd->n_reg_rules = resp->n_reg_rules;
- hwinfo->rd->alpha2[0] = resp->alpha2[0];
- hwinfo->rd->alpha2[1] = resp->alpha2[1];

bld_tmstamp = le32_to_cpu(resp->bld_tmstamp);
plat_id = le32_to_cpu(resp->plat_id);
hw_ver = le32_to_cpu(resp->hw_ver);

- switch (resp->dfs_region) {
- case QLINK_DFS_FCC:
- hwinfo->rd->dfs_region = NL80211_DFS_FCC;
- break;
- case QLINK_DFS_ETSI:
- hwinfo->rd->dfs_region = NL80211_DFS_ETSI;
- break;
- case QLINK_DFS_JP:
- hwinfo->rd->dfs_region = NL80211_DFS_JP;
- break;
- case QLINK_DFS_UNSET:
- default:
- hwinfo->rd->dfs_region = NL80211_DFS_UNSET;
- break;
- }
-
tlv = (const struct qlink_tlv_hdr *)resp->info;

while (info_len >= sizeof(*tlv)) {
@@ -956,37 +876,6 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
}

switch (tlv_type) {
- case QTN_TLV_ID_REG_RULE:
- if (rule_idx >= resp->n_reg_rules) {
- pr_warn("unexpected number of rules: %u\n",
- resp->n_reg_rules);
- return -EINVAL;
- }
-
- if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) {
- pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
- tlv_type, tlv_value_len);
- return -EINVAL;
- }
-
- tlv_rule = (const struct qlink_tlv_reg_rule *)tlv;
- rule = &hwinfo->rd->reg_rules[rule_idx++];
-
- rule->freq_range.start_freq_khz =
- le32_to_cpu(tlv_rule->start_freq_khz);
- rule->freq_range.end_freq_khz =
- le32_to_cpu(tlv_rule->end_freq_khz);
- rule->freq_range.max_bandwidth_khz =
- le32_to_cpu(tlv_rule->max_bandwidth_khz);
- rule->power_rule.max_antenna_gain =
- le32_to_cpu(tlv_rule->max_antenna_gain);
- rule->power_rule.max_eirp =
- le32_to_cpu(tlv_rule->max_eirp);
- rule->dfs_cac_ms =
- le32_to_cpu(tlv_rule->dfs_cac_ms);
- rule->flags = qtnf_cmd_resp_reg_rule_flags_parse(
- le32_to_cpu(tlv_rule->flags));
- break;
case QTN_TLV_ID_BUILD_NAME:
bld_name = (const void *)tlv->val;
break;
@@ -1019,17 +908,8 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
}

- if (rule_idx != resp->n_reg_rules) {
- pr_warn("unexpected number of rules: expected %u got %u\n",
- resp->n_reg_rules, rule_idx);
- kfree(hwinfo->rd);
- hwinfo->rd = NULL;
- return -EINVAL;
- }
-
- pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u, capab=0x%x\n",
+ pr_info("fw_version=%d, MACs map %#x, chains Tx=%u Rx=%u, capab=0x%x\n",
hwinfo->fw_ver, hwinfo->mac_bitmap,
- hwinfo->rd->alpha2[0], hwinfo->rd->alpha2[1],
hwinfo->total_tx_chain, hwinfo->total_rx_chain,
hwinfo->hw_capab);

@@ -1085,9 +965,12 @@ qtnf_parse_wowlan_info(struct qtnf_wmac *mac,
}
}

-static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
- const u8 *tlv_buf, size_t tlv_buf_size)
+static int
+qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
+ const struct qlink_resp_get_mac_info *resp,
+ size_t tlv_buf_size)
{
+ const u8 *tlv_buf = resp->var_info;
struct ieee80211_iface_combination *comb = NULL;
size_t n_comb = 0;
struct ieee80211_iface_limit *limits;
@@ -1105,6 +988,38 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
u8 ext_capa_len = 0;
u8 ext_capa_mask_len = 0;
int i = 0;
+ struct ieee80211_reg_rule *rule;
+ unsigned int rule_idx = 0;
+ const struct qlink_tlv_reg_rule *tlv_rule;
+
+ if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES))
+ return -E2BIG;
+
+ mac->rd = kzalloc(sizeof(*mac->rd) +
+ sizeof(struct ieee80211_reg_rule) *
+ resp->n_reg_rules, GFP_KERNEL);
+ if (!mac->rd)
+ return -ENOMEM;
+
+ mac->rd->n_reg_rules = resp->n_reg_rules;
+ mac->rd->alpha2[0] = resp->alpha2[0];
+ mac->rd->alpha2[1] = resp->alpha2[1];
+
+ switch (resp->dfs_region) {
+ case QLINK_DFS_FCC:
+ mac->rd->dfs_region = NL80211_DFS_FCC;
+ break;
+ case QLINK_DFS_ETSI:
+ mac->rd->dfs_region = NL80211_DFS_ETSI;
+ break;
+ case QLINK_DFS_JP:
+ mac->rd->dfs_region = NL80211_DFS_JP;
+ break;
+ case QLINK_DFS_UNSET:
+ default:
+ mac->rd->dfs_region = NL80211_DFS_UNSET;
+ break;
+ }

tlv = (const struct qlink_tlv_hdr *)tlv_buf;
while (tlv_buf_size >= sizeof(struct qlink_tlv_hdr)) {
@@ -1225,6 +1140,23 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
mac->macinfo.wowlan = NULL;
qtnf_parse_wowlan_info(mac, wowlan);
break;
+ case QTN_TLV_ID_REG_RULE:
+ if (rule_idx >= resp->n_reg_rules) {
+ pr_warn("unexpected number of rules: %u\n",
+ resp->n_reg_rules);
+ return -EINVAL;
+ }
+
+ if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) {
+ pr_warn("malformed TLV 0x%.2X; LEN: %u\n",
+ tlv_type, tlv_value_len);
+ return -EINVAL;
+ }
+
+ tlv_rule = (const struct qlink_tlv_reg_rule *)tlv;
+ rule = &mac->rd->reg_rules[rule_idx++];
+ qlink_utils_regrule_q2nl(rule, tlv_rule);
+ break;
default:
pr_warn("MAC%u: unknown TLV type %u\n",
mac->macid, tlv_type);
@@ -1253,6 +1185,12 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
return -EINVAL;
}

+ if (rule_idx != resp->n_reg_rules) {
+ pr_warn("unexpected number of rules: expected %u got %u\n",
+ resp->n_reg_rules, rule_idx);
+ return -EINVAL;
+ }
+
if (ext_capa_len > 0) {
ext_capa = kmemdup(ext_capa, ext_capa_len, GFP_KERNEL);
if (!ext_capa)
@@ -1663,7 +1601,7 @@ int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac)

resp = (const struct qlink_resp_get_mac_info *)resp_skb->data;
qtnf_cmd_resp_proc_mac_info(mac, resp);
- ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len);
+ ret = qtnf_parse_variable_mac_info(mac, resp, var_data_len);

out:
qtnf_bus_unlock(mac->bus);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c
index ee1b75fda1dd..f04f4e1f7d68 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -499,6 +499,8 @@ static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid)
qtnf_mac_iface_comb_free(mac);
qtnf_mac_ext_caps_free(mac);
kfree(mac->macinfo.wowlan);
+ kfree(mac->rd);
+ mac->rd = NULL;
wiphy_free(wiphy);
bus->mac[macid] = NULL;
}
@@ -665,9 +667,6 @@ void qtnf_core_detach(struct qtnf_bus *bus)
destroy_workqueue(bus->workqueue);
}

- kfree(bus->hw_info.rd);
- bus->hw_info.rd = NULL;
-
qtnf_trans_free(bus);
}
EXPORT_SYMBOL_GPL(qtnf_core_detach);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h
index a31cff46e964..1b983ec9afcc 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.h
@@ -112,6 +112,7 @@ struct qtnf_wmac {
struct cfg80211_scan_request *scan_req;
struct mutex mac_lock; /* lock during wmac speicific ops */
struct delayed_work scan_timeout;
+ struct ieee80211_regdomain *rd;
};

struct qtnf_hw_info {
@@ -120,7 +121,6 @@ struct qtnf_hw_info {
u8 mac_bitmap;
u32 fw_ver;
u32 hw_capab;
- struct ieee80211_regdomain *rd;
u8 total_tx_chain;
u8 total_rx_chain;
char fw_version[ETHTOOL_FWVERS_LEN];
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index ca84684a1a93..6951f6370985 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -6,7 +6,7 @@

#include <linux/ieee80211.h>

-#define QLINK_PROTO_VER 14
+#define QLINK_PROTO_VER 15

#define QLINK_MACID_RSVD 0xFF
#define QLINK_VIFID_RSVD 0xFF
@@ -771,6 +771,18 @@ struct qlink_resp {
} __packed;

/**
+ * enum qlink_dfs_regions - regulatory DFS regions
+ *
+ * Corresponds to &enum nl80211_dfs_regions.
+ */
+enum qlink_dfs_regions {
+ QLINK_DFS_UNSET = 0,
+ QLINK_DFS_FCC = 1,
+ QLINK_DFS_ETSI = 2,
+ QLINK_DFS_JP = 3,
+};
+
+/**
* struct qlink_resp_get_mac_info - response for QLINK_CMD_MAC_INFO command
*
* Data describing specific physical device providing wireless MAC
@@ -785,6 +797,10 @@ struct qlink_resp {
* @bands_cap: wireless bands WMAC can operate in, bitmap of &enum qlink_band.
* @max_ap_assoc_sta: Maximum number of associations supported by WMAC.
* @radar_detect_widths: bitmask of channels BW for which WMAC can detect radar.
+ * @alpha2: country code ID firmware is configured to.
+ * @n_reg_rules: number of regulatory rules TLVs in variable portion of the
+ * message.
+ * @dfs_region: regulatory DFS region, one of @enum qlink_dfs_region.
* @var_info: variable-length WMAC info data.
*/
struct qlink_resp_get_mac_info {
@@ -798,23 +814,14 @@ struct qlink_resp_get_mac_info {
__le16 radar_detect_widths;
__le32 max_acl_mac_addrs;
u8 bands_cap;
+ u8 alpha2[2];
+ u8 n_reg_rules;
+ u8 dfs_region;
u8 rsvd[1];
u8 var_info[0];
} __packed;

/**
- * enum qlink_dfs_regions - regulatory DFS regions
- *
- * Corresponds to &enum nl80211_dfs_regions.
- */
-enum qlink_dfs_regions {
- QLINK_DFS_UNSET = 0,
- QLINK_DFS_FCC = 1,
- QLINK_DFS_ETSI = 2,
- QLINK_DFS_JP = 3,
-};
-
-/**
* struct qlink_resp_get_hw_info - response for QLINK_CMD_GET_HW_INFO command
*
* Description of wireless hardware capabilities and features.
@@ -826,11 +833,7 @@ enum qlink_dfs_regions {
* @mac_bitmap: Bitmap of MAC IDs that are active and can be used in firmware.
* @total_tx_chains: total number of transmit chains used by device.
* @total_rx_chains: total number of receive chains.
- * @alpha2: country code ID firmware is configured to.
- * @n_reg_rules: number of regulatory rules TLVs in variable portion of the
- * message.
- * @dfs_region: regulatory DFS region, one of @enum qlink_dfs_region.
- * @info: variable-length HW info, can contain QTN_TLV_ID_REG_RULE.
+ * @info: variable-length HW info.
*/
struct qlink_resp_get_hw_info {
struct qlink_resp rhdr;
@@ -844,9 +847,6 @@ struct qlink_resp_get_hw_info {
u8 mac_bitmap;
u8 total_tx_chain;
u8 total_rx_chain;
- u8 alpha2[2];
- u8 n_reg_rules;
- u8 dfs_region;
u8 info[0];
} __packed;

diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
index 8cae9d8d1ab6..1a972bce7b8b 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
@@ -237,3 +237,65 @@ u32 qlink_utils_chflags_cfg2q(u32 cfgflags)

return flags;
}
+
+static u32 qtnf_reg_rule_flags_parse(u32 qflags)
+{
+ u32 flags = 0;
+
+ if (qflags & QLINK_RRF_NO_OFDM)
+ flags |= NL80211_RRF_NO_OFDM;
+
+ if (qflags & QLINK_RRF_NO_CCK)
+ flags |= NL80211_RRF_NO_CCK;
+
+ if (qflags & QLINK_RRF_NO_INDOOR)
+ flags |= NL80211_RRF_NO_INDOOR;
+
+ if (qflags & QLINK_RRF_NO_OUTDOOR)
+ flags |= NL80211_RRF_NO_OUTDOOR;
+
+ if (qflags & QLINK_RRF_DFS)
+ flags |= NL80211_RRF_DFS;
+
+ if (qflags & QLINK_RRF_PTP_ONLY)
+ flags |= NL80211_RRF_PTP_ONLY;
+
+ if (qflags & QLINK_RRF_PTMP_ONLY)
+ flags |= NL80211_RRF_PTMP_ONLY;
+
+ if (qflags & QLINK_RRF_NO_IR)
+ flags |= NL80211_RRF_NO_IR;
+
+ if (qflags & QLINK_RRF_AUTO_BW)
+ flags |= NL80211_RRF_AUTO_BW;
+
+ if (qflags & QLINK_RRF_IR_CONCURRENT)
+ flags |= NL80211_RRF_IR_CONCURRENT;
+
+ if (qflags & QLINK_RRF_NO_HT40MINUS)
+ flags |= NL80211_RRF_NO_HT40MINUS;
+
+ if (qflags & QLINK_RRF_NO_HT40PLUS)
+ flags |= NL80211_RRF_NO_HT40PLUS;
+
+ if (qflags & QLINK_RRF_NO_80MHZ)
+ flags |= NL80211_RRF_NO_80MHZ;
+
+ if (qflags & QLINK_RRF_NO_160MHZ)
+ flags |= NL80211_RRF_NO_160MHZ;
+
+ return flags;
+}
+
+void qlink_utils_regrule_q2nl(struct ieee80211_reg_rule *rule,
+ const struct qlink_tlv_reg_rule *tlv)
+{
+ rule->freq_range.start_freq_khz = le32_to_cpu(tlv->start_freq_khz);
+ rule->freq_range.end_freq_khz = le32_to_cpu(tlv->end_freq_khz);
+ rule->freq_range.max_bandwidth_khz =
+ le32_to_cpu(tlv->max_bandwidth_khz);
+ rule->power_rule.max_antenna_gain = le32_to_cpu(tlv->max_antenna_gain);
+ rule->power_rule.max_eirp = le32_to_cpu(tlv->max_eirp);
+ rule->dfs_cac_ms = le32_to_cpu(tlv->dfs_cac_ms);
+ rule->flags = qtnf_reg_rule_flags_parse(le32_to_cpu(tlv->flags));
+}
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
index 9d10a2098ca7..f873beed2ae7 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
@@ -82,5 +82,7 @@ void qlink_acl_data_cfg2q(const struct cfg80211_acl_data *acl,
enum qlink_band qlink_utils_band_cfg2q(enum nl80211_band band);
enum qlink_dfs_state qlink_utils_dfs_state_cfg2q(enum nl80211_dfs_state state);
u32 qlink_utils_chflags_cfg2q(u32 cfgflags);
+void qlink_utils_regrule_q2nl(struct ieee80211_reg_rule *rule,
+ const struct qlink_tlv_reg_rule *tlv_rule);

#endif /* _QTN_FMAC_QLINK_UTIL_H_ */
--
2.11.0


2019-03-20 10:05:24

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 09/14] qtnfmac: fix core attach error path in pcie backend

Report that firmware is up and running only for successful firmware
download. Simplify qtnf_pcie_fw_boot_done: modify error path so that
no need to pass firmware dowload result to this function. Finally,
do not create debugfs entries if firmware download succeeded,
but core attach failed.

Signed-off-by: Sergey Matyukevich <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 25 +++++++---------------
.../wireless/quantenna/qtnfmac/pcie/pcie_priv.h | 2 +-
.../wireless/quantenna/qtnfmac/pcie/pearl_pcie.c | 23 ++++++++++----------
.../wireless/quantenna/qtnfmac/pcie/topaz_pcie.c | 23 ++++++++++++--------
4 files changed, 34 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
index c3a32effa6f0..a693667a83d7 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
@@ -128,32 +128,23 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
return 0;
}

-void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success)
+int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
{
- struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
- struct pci_dev *pdev = priv->pdev;
int ret;

- if (boot_success) {
- bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE;
-
- ret = qtnf_core_attach(bus);
- if (ret) {
- pr_err("failed to attach core\n");
- boot_success = false;
- }
- }
-
- if (boot_success) {
+ bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE;
+ ret = qtnf_core_attach(bus);
+ if (ret) {
+ pr_err("failed to attach core\n");
+ bus->fw_state = QTNF_FW_STATE_DETACHED;
+ } else {
qtnf_debugfs_init(bus, DRV_NAME);
qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show);
qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show);
qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats);
- } else {
- bus->fw_state = QTNF_FW_STATE_DETACHED;
}

- put_device(&pdev->dev);
+ return ret;
}

static void qtnf_tune_pcie_mps(struct pci_dev *pdev)
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
index bbc074e1f34d..b21de4f52a9d 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
@@ -70,7 +70,7 @@ struct qtnf_pcie_bus_priv {

int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb);
int qtnf_pcie_alloc_skb_array(struct qtnf_pcie_bus_priv *priv);
-void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success);
+int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus);
void qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv,
struct qtnf_shm_ipc_region __iomem *ipc_tx_reg,
struct qtnf_shm_ipc_region __iomem *ipc_rx_reg,
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
index 1f5facbb8905..3aa3714d4dfd 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
@@ -980,12 +980,11 @@ static void qtnf_pearl_fw_work_handler(struct work_struct *work)
{
struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work);
struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus);
+ u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK;
+ const char *fwname = QTN_PCI_PEARL_FW_NAME;
struct pci_dev *pdev = ps->base.pdev;
const struct firmware *fw;
int ret;
- u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK;
- const char *fwname = QTN_PCI_PEARL_FW_NAME;
- bool fw_boot_success = false;

if (ps->base.flashboot) {
state |= QTN_RC_FW_FLASHBOOT;
@@ -1031,23 +1030,23 @@ static void qtnf_pearl_fw_work_handler(struct work_struct *work)
goto fw_load_exit;
}

- pr_info("firmware is up and running\n");
-
if (qtnf_poll_state(&ps->bda->bda_ep_state,
QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) {
pr_err("firmware runtime failure\n");
goto fw_load_exit;
}

- fw_boot_success = true;
+ pr_info("firmware is up and running\n");

-fw_load_exit:
- qtnf_pcie_fw_boot_done(bus, fw_boot_success);
+ ret = qtnf_pcie_fw_boot_done(bus);
+ if (ret)
+ goto fw_load_exit;

- if (fw_boot_success) {
- qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats);
- qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats);
- }
+ qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats);
+ qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats);
+
+fw_load_exit:
+ put_device(&pdev->dev);
}

static void qtnf_pearl_reclaim_tasklet_fn(unsigned long data)
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
index cbcda57105f3..d9b83ea6281c 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
@@ -1023,8 +1023,9 @@ static void qtnf_topaz_fw_work_handler(struct work_struct *work)
{
struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work);
struct qtnf_pcie_topaz_state *ts = (void *)get_bus_priv(bus);
- int ret;
int bootloader_needed = readl(&ts->bda->bda_flags) & QTN_BDA_XMIT_UBOOT;
+ struct pci_dev *pdev = ts->base.pdev;
+ int ret;

qtnf_set_state(&ts->bda->bda_bootstate, QTN_BDA_FW_TARGET_BOOT);

@@ -1073,19 +1074,23 @@ static void qtnf_topaz_fw_work_handler(struct work_struct *work)
}
}

+ ret = qtnf_post_init_ep(ts);
+ if (ret) {
+ pr_err("FW runtime failure\n");
+ goto fw_load_exit;
+ }
+
pr_info("firmware is up and running\n");

- ret = qtnf_post_init_ep(ts);
+ ret = qtnf_pcie_fw_boot_done(bus);
if (ret)
- pr_err("FW runtime failure\n");
+ goto fw_load_exit;

-fw_load_exit:
- qtnf_pcie_fw_boot_done(bus, ret ? false : true);
+ qtnf_debugfs_add_entry(bus, "pkt_stats", qtnf_dbg_pkt_stats);
+ qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats);

- if (ret == 0) {
- qtnf_debugfs_add_entry(bus, "pkt_stats", qtnf_dbg_pkt_stats);
- qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats);
- }
+fw_load_exit:
+ put_device(&pdev->dev);
}

static void qtnf_reclaim_tasklet_fn(unsigned long data)
--
2.11.0


2019-03-20 10:05:31

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 11/14] qtnfmac: allow changing the netns

Allow to change netns for wireless interfaces created by qtnfmac driver.

Signed-off-by: Sergey Matyukevich <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index cea948466744..95572555ed6a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -1106,7 +1106,8 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
WIPHY_FLAG_AP_UAPSD |
WIPHY_FLAG_HAS_CHANNEL_SWITCH |
- WIPHY_FLAG_4ADDR_STATION;
+ WIPHY_FLAG_4ADDR_STATION |
+ WIPHY_FLAG_NETNS_OK;
wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;

if (hw_info->hw_capab & QLINK_HW_CAPAB_DFS_OFFLOAD)
--
2.11.0


2019-03-20 10:05:40

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 13/14] qtnfmac: send EAPOL frames via control path

From: Igor Mitsyanko <[email protected]>

Use control path to send EAPOL frames to make sure they are
sent with higher priority with aggregation disabled.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/bus.h | 1 +
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 17 +++++---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 10 ++---
drivers/net/wireless/quantenna/qtnfmac/commands.h | 4 +-
drivers/net/wireless/quantenna/qtnfmac/core.c | 45 ++++++++++++++++++++--
drivers/net/wireless/quantenna/qtnfmac/core.h | 3 ++
drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 1 +
.../wireless/quantenna/qtnfmac/pcie/pcie_priv.h | 1 +
.../wireless/quantenna/qtnfmac/pcie/topaz_pcie.c | 8 ++++
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 24 +++++++-----
10 files changed, 89 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/bus.h b/drivers/net/wireless/quantenna/qtnfmac/bus.h
index dc1bd32d4827..7cea08f71838 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/bus.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/bus.h
@@ -49,6 +49,7 @@ struct qtnf_bus {
struct napi_struct mux_napi;
struct net_device mux_dev;
struct workqueue_struct *workqueue;
+ struct workqueue_struct *hprio_workqueue;
struct work_struct fw_work;
struct work_struct event_work;
struct mutex bus_lock; /* lock during command/event processing */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 95572555ed6a..c78500bcaa2d 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -144,6 +144,7 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
{
struct net_device *netdev = wdev->netdev;
struct qtnf_vif *vif;
+ struct sk_buff *skb;

if (WARN_ON(!netdev))
return -EFAULT;
@@ -157,6 +158,11 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
if (netif_carrier_ok(netdev))
netif_carrier_off(netdev);

+ while ((skb = skb_dequeue(&vif->high_pri_tx_queue)))
+ dev_kfree_skb_any(skb);
+
+ cancel_work_sync(&vif->high_pri_tx_work);
+
if (netdev->reg_state == NETREG_REGISTERED)
unregister_netdevice(netdev);

@@ -424,13 +430,13 @@ qtnf_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
*cookie = short_cookie;

if (params->offchan)
- flags |= QLINK_MGMT_FRAME_TX_FLAG_OFFCHAN;
+ flags |= QLINK_FRAME_TX_FLAG_OFFCHAN;

if (params->no_cck)
- flags |= QLINK_MGMT_FRAME_TX_FLAG_NO_CCK;
+ flags |= QLINK_FRAME_TX_FLAG_NO_CCK;

if (params->dont_wait_for_ack)
- flags |= QLINK_MGMT_FRAME_TX_FLAG_ACK_NOWAIT;
+ flags |= QLINK_FRAME_TX_FLAG_ACK_NOWAIT;

/* If channel is not specified, pass "freq = 0" to tell device
* firmware to use current channel.
@@ -445,9 +451,8 @@ qtnf_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
le16_to_cpu(mgmt_frame->frame_control), mgmt_frame->da,
params->len, short_cookie, flags);

- return qtnf_cmd_send_mgmt_frame(vif, short_cookie, flags,
- freq,
- params->buf, params->len);
+ return qtnf_cmd_send_frame(vif, short_cookie, flags,
+ freq, params->buf, params->len);
}

static int
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index a04321305ebc..62edddb8551e 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -381,11 +381,11 @@ int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg)
return ret;
}

-int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
- u16 freq, const u8 *buf, size_t len)
+int qtnf_cmd_send_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
+ u16 freq, const u8 *buf, size_t len)
{
struct sk_buff *cmd_skb;
- struct qlink_cmd_mgmt_frame_tx *cmd;
+ struct qlink_cmd_frame_tx *cmd;
int ret;

if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) {
@@ -395,14 +395,14 @@ int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
}

cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
- QLINK_CMD_SEND_MGMT_FRAME,
+ QLINK_CMD_SEND_FRAME,
sizeof(*cmd));
if (!cmd_skb)
return -ENOMEM;

qtnf_bus_lock(vif->mac->bus);

- cmd = (struct qlink_cmd_mgmt_frame_tx *)cmd_skb->data;
+ cmd = (struct qlink_cmd_frame_tx *)cmd_skb->data;
cmd->cookie = cpu_to_le32(cookie);
cmd->freq = cpu_to_le16(freq);
cmd->flags = cpu_to_le16(flags);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h b/drivers/net/wireless/quantenna/qtnfmac/commands.h
index 050f9a49d16c..6406365287fc 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h
@@ -27,8 +27,8 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
const struct cfg80211_ap_settings *s);
int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif);
int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg);
-int qtnf_cmd_send_mgmt_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
- u16 freq, const u8 *buf, size_t len);
+int qtnf_cmd_send_frame(struct qtnf_vif *vif, u32 cookie, u16 flags,
+ u16 freq, const u8 *buf, size_t len);
int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type,
const u8 *buf, size_t len);
int qtnf_cmd_get_sta_info(struct qtnf_vif *vif, const u8 *sta_mac,
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c
index eed12e4dec65..54ea86ae4959 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -368,6 +368,23 @@ static void qtnf_mac_scan_timeout(struct work_struct *work)
qtnf_mac_scan_finish(mac, true);
}

+static void qtnf_vif_send_data_high_pri(struct work_struct *work)
+{
+ struct qtnf_vif *vif =
+ container_of(work, struct qtnf_vif, high_pri_tx_work);
+ struct sk_buff *skb;
+
+ if (!vif->netdev ||
+ vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
+ return;
+
+ while ((skb = skb_dequeue(&vif->high_pri_tx_queue))) {
+ qtnf_cmd_send_frame(vif, 0, QLINK_FRAME_TX_FLAG_8023,
+ 0, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ }
+}
+
static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
unsigned int macid)
{
@@ -395,7 +412,8 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
vif->mac = mac;
vif->vifid = i;
qtnf_sta_list_init(&vif->sta_list);
-
+ INIT_WORK(&vif->high_pri_tx_work, qtnf_vif_send_data_high_pri);
+ skb_queue_head_init(&vif->high_pri_tx_queue);
vif->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!vif->stats64)
pr_warn("VIF%u.%u: per cpu stats allocation failed\n",
@@ -598,6 +616,13 @@ int qtnf_core_attach(struct qtnf_bus *bus)
goto error;
}

+ bus->hprio_workqueue = alloc_workqueue("QTNF_HPRI", WQ_HIGHPRI, 0);
+ if (!bus->hprio_workqueue) {
+ pr_err("failed to alloc high prio workqueue\n");
+ ret = -ENOMEM;
+ goto error;
+ }
+
INIT_WORK(&bus->event_work, qtnf_event_work_handler);

ret = qtnf_cmd_send_init_fw(bus);
@@ -607,7 +632,6 @@ int qtnf_core_attach(struct qtnf_bus *bus)
}

bus->fw_state = QTNF_FW_STATE_ACTIVE;
-
ret = qtnf_cmd_get_hw_info(bus);
if (ret) {
pr_err("failed to get HW info: %d\n", ret);
@@ -642,7 +666,6 @@ int qtnf_core_attach(struct qtnf_bus *bus)

error:
qtnf_core_detach(bus);
-
return ret;
}
EXPORT_SYMBOL_GPL(qtnf_core_attach);
@@ -664,6 +687,13 @@ void qtnf_core_detach(struct qtnf_bus *bus)
if (bus->workqueue) {
flush_workqueue(bus->workqueue);
destroy_workqueue(bus->workqueue);
+ bus->workqueue = NULL;
+ }
+
+ if (bus->hprio_workqueue) {
+ flush_workqueue(bus->hprio_workqueue);
+ destroy_workqueue(bus->hprio_workqueue);
+ bus->hprio_workqueue = NULL;
}

qtnf_trans_free(bus);
@@ -800,6 +830,15 @@ void qtnf_update_tx_stats(struct net_device *ndev, const struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(qtnf_update_tx_stats);

+void qtnf_packet_send_hi_pri(struct sk_buff *skb)
+{
+ struct qtnf_vif *vif = qtnf_netdev_get_priv(skb->dev);
+
+ skb_queue_tail(&vif->high_pri_tx_queue, skb);
+ queue_work(vif->mac->bus->hprio_workqueue, &vif->high_pri_tx_work);
+}
+EXPORT_SYMBOL_GPL(qtnf_packet_send_hi_pri);
+
MODULE_AUTHOR("Quantenna Communications");
MODULE_DESCRIPTION("Quantenna 802.11 wireless LAN FullMAC driver.");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h
index 1b983ec9afcc..af8372dfb927 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.h
@@ -63,6 +63,8 @@ struct qtnf_vif {
struct qtnf_wmac *mac;

struct work_struct reset_work;
+ struct work_struct high_pri_tx_work;
+ struct sk_buff_head high_pri_tx_queue;
struct qtnf_sta_list sta_list;
unsigned long cons_tx_timeout_cnt;
int generation;
@@ -149,6 +151,7 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev);

void qtnf_netdev_updown(struct net_device *ndev, bool up);
void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted);
+void qtnf_packet_send_hi_pri(struct sk_buff *skb);

static inline struct qtnf_vif *qtnf_netdev_get_priv(struct net_device *dev)
{
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
index 56fc6d49c121..069fe61aa477 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
@@ -358,6 +358,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pcie_priv->pcie_irq_count = 0;
pcie_priv->tx_reclaim_done = 0;
pcie_priv->tx_reclaim_req = 0;
+ pcie_priv->tx_eapol = 0;

pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PCIE");
if (!pcie_priv->workqueue) {
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
index b21de4f52a9d..5e8b9cb68419 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
@@ -62,6 +62,7 @@ struct qtnf_pcie_bus_priv {
u32 tx_done_count;
u32 tx_reclaim_done;
u32 tx_reclaim_req;
+ u32 tx_eapol;

u8 msi_enabled;
u8 tx_stopped;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
index d9b83ea6281c..9a4380ed7f1b 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
@@ -498,6 +498,13 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
int len;
int i;

+ if (unlikely(skb->protocol == htons(ETH_P_PAE))) {
+ qtnf_packet_send_hi_pri(skb);
+ qtnf_update_tx_stats(skb->dev, skb);
+ priv->tx_eapol++;
+ return NETDEV_TX_OK;
+ }
+
spin_lock_irqsave(&priv->tx_lock, flags);

if (!qtnf_tx_queue_ready(ts)) {
@@ -761,6 +768,7 @@ static int qtnf_dbg_pkt_stats(struct seq_file *s, void *data)
seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count);
seq_printf(s, "tx_reclaim_done(%u)\n", priv->tx_reclaim_done);
seq_printf(s, "tx_reclaim_req(%u)\n", priv->tx_reclaim_req);
+ seq_printf(s, "tx_eapol(%u)\n", priv->tx_eapol);

seq_printf(s, "tx_bd_r_index(%u)\n", priv->tx_bd_r_index);
seq_printf(s, "tx_done_index(%u)\n", tx_done_index);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index f6d30069ef3a..2fe71adc221a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -206,6 +206,8 @@ struct qlink_sta_info_state {
* execution status (one of &enum qlink_cmd_result). Reply message
* may also contain data payload specific to the command type.
*
+ * @QLINK_CMD_SEND_FRAME: send specified frame over the air; firmware will
+ * encapsulate 802.3 packet into 802.11 frame automatically.
* @QLINK_CMD_BAND_INFO_GET: for the specified MAC and specified band, get
* the band's description including number of operational channels and
* info on each channel, HT/VHT capabilities, supported rates etc.
@@ -220,7 +222,7 @@ enum qlink_cmd_type {
QLINK_CMD_FW_INIT = 0x0001,
QLINK_CMD_FW_DEINIT = 0x0002,
QLINK_CMD_REGISTER_MGMT = 0x0003,
- QLINK_CMD_SEND_MGMT_FRAME = 0x0004,
+ QLINK_CMD_SEND_FRAME = 0x0004,
QLINK_CMD_MGMT_SET_APPIE = 0x0005,
QLINK_CMD_PHY_PARAMS_GET = 0x0011,
QLINK_CMD_PHY_PARAMS_SET = 0x0012,
@@ -321,22 +323,26 @@ struct qlink_cmd_mgmt_frame_register {
u8 do_register;
} __packed;

-enum qlink_mgmt_frame_tx_flags {
- QLINK_MGMT_FRAME_TX_FLAG_NONE = 0,
- QLINK_MGMT_FRAME_TX_FLAG_OFFCHAN = BIT(0),
- QLINK_MGMT_FRAME_TX_FLAG_NO_CCK = BIT(1),
- QLINK_MGMT_FRAME_TX_FLAG_ACK_NOWAIT = BIT(2),
+/**
+ * @QLINK_FRAME_TX_FLAG_8023: frame has a 802.3 header; if not set, frame
+ * is a 802.11 encapsulated.
+ */
+enum qlink_frame_tx_flags {
+ QLINK_FRAME_TX_FLAG_OFFCHAN = BIT(0),
+ QLINK_FRAME_TX_FLAG_NO_CCK = BIT(1),
+ QLINK_FRAME_TX_FLAG_ACK_NOWAIT = BIT(2),
+ QLINK_FRAME_TX_FLAG_8023 = BIT(3),
};

/**
- * struct qlink_cmd_mgmt_frame_tx - data for QLINK_CMD_SEND_MGMT_FRAME command
+ * struct qlink_cmd_frame_tx - data for QLINK_CMD_SEND_FRAME command
*
* @cookie: opaque request identifier.
* @freq: Frequency to use for frame transmission.
- * @flags: Transmission flags, one of &enum qlink_mgmt_frame_tx_flags.
+ * @flags: Transmission flags, one of &enum qlink_frame_tx_flags.
* @frame_data: frame to transmit.
*/
-struct qlink_cmd_mgmt_frame_tx {
+struct qlink_cmd_frame_tx {
struct qlink_cmd chdr;
__le32 cookie;
__le16 freq;
--
2.11.0


2019-03-20 10:05:42

by Sergey Matyukevich

[permalink] [raw]
Subject: [PATCH 14/14] qtnfmac: use scan duration param for different scan types

From: Igor Mitsyanko <[email protected]>

Use scan duration param for both active and passive scan dwell times.
Document what different types of dwell times are used for. Explicitly
specify that if unset, automatic selection by device firmware
will be used.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 49 ++++++++++++++++++-----
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 11 ++++-
2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 62edddb8551e..e58495403dde 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -11,6 +11,13 @@
#include "bus.h"
#include "commands.h"

+#define QTNF_SCAN_TIME_AUTO 0
+
+/* Let device itself to select best values for current conditions */
+#define QTNF_SCAN_DWELL_ACTIVE_DEFAULT QTNF_SCAN_TIME_AUTO
+#define QTNF_SCAN_DWELL_PASSIVE_DEFAULT QTNF_SCAN_TIME_AUTO
+#define QTNF_SCAN_SAMPLE_DURATION_DEFAULT QTNF_SCAN_TIME_AUTO
+
static int qtnf_cmd_check_reply_header(const struct qlink_resp *resp,
u16 cmd_id, u8 mac_id, u8 vif_id,
size_t resp_size)
@@ -938,7 +945,7 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
"\nHardware ID: %s" \
"\nCalibration version: %s" \
"\nU-Boot version: %s" \
- "\nHardware version: 0x%08x",
+ "\nHardware version: 0x%08x\n",
bld_name, bld_rev, bld_type, bld_label,
(unsigned long)bld_tmstamp,
(unsigned long)plat_id,
@@ -2082,6 +2089,35 @@ static void qtnf_cmd_randmac_tlv_add(struct sk_buff *cmd_skb,
memcpy(randmac->mac_addr_mask, mac_addr_mask, ETH_ALEN);
}

+static void qtnf_cmd_scan_set_dwell(struct qtnf_wmac *mac,
+ struct sk_buff *cmd_skb)
+{
+ struct cfg80211_scan_request *scan_req = mac->scan_req;
+ u16 dwell_active = QTNF_SCAN_DWELL_ACTIVE_DEFAULT;
+ u16 dwell_passive = QTNF_SCAN_DWELL_PASSIVE_DEFAULT;
+ u16 duration = QTNF_SCAN_SAMPLE_DURATION_DEFAULT;
+
+ if (scan_req->duration) {
+ dwell_active = scan_req->duration;
+ dwell_passive = scan_req->duration;
+ }
+
+ pr_debug("MAC%u: %s scan dwell active=%u, passive=%u, duration=%u\n",
+ mac->macid,
+ scan_req->duration_mandatory ? "mandatory" : "max",
+ dwell_active, dwell_passive, duration);
+
+ qtnf_cmd_skb_put_tlv_u16(cmd_skb,
+ QTN_TLV_ID_SCAN_DWELL_ACTIVE,
+ dwell_active);
+ qtnf_cmd_skb_put_tlv_u16(cmd_skb,
+ QTN_TLV_ID_SCAN_DWELL_PASSIVE,
+ dwell_passive);
+ qtnf_cmd_skb_put_tlv_u16(cmd_skb,
+ QTN_TLV_ID_SCAN_SAMPLE_DURATION,
+ duration);
+}
+
int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
{
struct sk_buff *cmd_skb;
@@ -2133,6 +2169,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
}
}

+ qtnf_cmd_scan_set_dwell(mac, cmd_skb);
+
if (scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
pr_debug("MAC%u: scan with random addr=%pM, mask=%pM\n",
mac->macid,
@@ -2148,15 +2186,6 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
qtnf_cmd_skb_put_tlv_tag(cmd_skb, QTN_TLV_ID_SCAN_FLUSH);
}

- if (scan_req->duration) {
- pr_debug("MAC%u: %s scan duration %u\n", mac->macid,
- scan_req->duration_mandatory ? "mandatory" : "max",
- scan_req->duration);
-
- qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_SCAN_DWELL,
- scan_req->duration);
- }
-
ret = qtnf_cmd_send(mac->bus, cmd_skb);
if (ret)
goto out;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index 2fe71adc221a..158c9eba20ef 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -1162,6 +1162,13 @@ struct qlink_event_external_auth {
* carried by QTN_TLV_ID_STA_STATS_MAP.
* @QTN_TLV_ID_MAX_SCAN_SSIDS: maximum number of SSIDs the device can scan
* for in any given scan.
+ * @QTN_TLV_ID_SCAN_DWELL_ACTIVE: time spent on a single channel for an active
+ * scan.
+ * @QTN_TLV_ID_SCAN_DWELL_PASSIVE: time spent on a single channel for a passive
+ * scan.
+ * @QTN_TLV_ID_SCAN_SAMPLE_DURATION: total duration of sampling a single channel
+ * during a scan including off-channel dwell time and operating channel
+ * time.
*/
enum qlink_tlv_id {
QTN_TLV_ID_FRAG_THRESH = 0x0201,
@@ -1194,7 +1201,9 @@ enum qlink_tlv_id {
QTN_TLV_ID_WOWLAN_CAPAB = 0x0410,
QTN_TLV_ID_WOWLAN_PATTERN = 0x0411,
QTN_TLV_ID_SCAN_FLUSH = 0x0412,
- QTN_TLV_ID_SCAN_DWELL = 0x0413,
+ QTN_TLV_ID_SCAN_DWELL_ACTIVE = 0x0413,
+ QTN_TLV_ID_SCAN_DWELL_PASSIVE = 0x0416,
+ QTN_TLV_ID_SCAN_SAMPLE_DURATION = 0x0417,
};

struct qlink_tlv_hdr {
--
2.11.0


2019-03-20 14:05:57

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

Sergey Matyukevich <[email protected]> writes:

> Fix creation of debugfs entries for qtnfmac wireless card: use separate
> directories for different wireless cards. This commit enables support
> for multiple qtnfmac wireless cards on the same PCIe host.
>
> Signed-off-by: Sergey Matyukevich <[email protected]>
> ---
> drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> index b561b75e4433..56fc6d49c121 100644
> --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
>
> int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> {
> + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
> + char card_id[64];
> int ret;
>
> bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
> @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> if (ret) {
> pr_err("failed to attach core\n");
> } else {
> - qtnf_debugfs_init(bus, DRV_NAME);
> + snprintf(card_id, sizeof(card_id), "%s:%s",
> + DRV_NAME, pci_name(priv->pdev));

Can you give an example for the path?

--
Kalle Valo

2019-03-20 14:08:46

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 14/14] qtnfmac: use scan duration param for different scan types

Sergey Matyukevich <[email protected]> writes:

> From: Igor Mitsyanko <[email protected]>
>
> Use scan duration param for both active and passive scan dwell times.
> Document what different types of dwell times are used for. Explicitly
> specify that if unset, automatic selection by device firmware
> will be used.
>
> Signed-off-by: Igor Mitsyanko <[email protected]>
> ---
> drivers/net/wireless/quantenna/qtnfmac/commands.c | 49 ++++++++++++++++++-----
> drivers/net/wireless/quantenna/qtnfmac/qlink.h | 11 ++++-
> 2 files changed, 49 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
> index 62edddb8551e..e58495403dde 100644
> --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
> +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
> @@ -11,6 +11,13 @@
> #include "bus.h"
> #include "commands.h"
>
> +#define QTNF_SCAN_TIME_AUTO 0
> +
> +/* Let device itself to select best values for current conditions */
> +#define QTNF_SCAN_DWELL_ACTIVE_DEFAULT QTNF_SCAN_TIME_AUTO
> +#define QTNF_SCAN_DWELL_PASSIVE_DEFAULT QTNF_SCAN_TIME_AUTO
> +#define QTNF_SCAN_SAMPLE_DURATION_DEFAULT QTNF_SCAN_TIME_AUTO

These three defines look odd. Why not just use QTNF_SCAN_TIME_AUTO
directly?

--
Kalle Valo

2019-03-20 15:17:32

by Sergey Matyukevich

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

> > Fix creation of debugfs entries for qtnfmac wireless card: use separate
> > directories for different wireless cards. This commit enables support
> > for multiple qtnfmac wireless cards on the same PCIe host.
> >
> > Signed-off-by: Sergey Matyukevich <[email protected]>
> > ---
> > drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
> > 1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> > index b561b75e4433..56fc6d49c121 100644
> > --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> > +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> > @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
> >
> > int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> > {
> > + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
> > + char card_id[64];
> > int ret;
> >
> > bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
> > @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> > if (ret) {
> > pr_err("failed to attach core\n");
> > } else {
> > - qtnf_debugfs_init(bus, DRV_NAME);
> > + snprintf(card_id, sizeof(card_id), "%s:%s",
> > + DRV_NAME, pci_name(priv->pdev));
>
> Can you give an example for the path?
>

For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0

Regards,
Sergey

2019-03-20 15:22:15

by Sergey Matyukevich

[permalink] [raw]
Subject: Re: [PATCH 14/14] qtnfmac: use scan duration param for different scan types

> > From: Igor Mitsyanko <[email protected]>
> >
> > Use scan duration param for both active and passive scan dwell times.
> > Document what different types of dwell times are used for. Explicitly
> > specify that if unset, automatic selection by device firmware
> > will be used.
> >
> > Signed-off-by: Igor Mitsyanko <[email protected]>
> > ---
> > drivers/net/wireless/quantenna/qtnfmac/commands.c | 49 ++++++++++++++++++-----
> > drivers/net/wireless/quantenna/qtnfmac/qlink.h | 11 ++++-
> > 2 files changed, 49 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
> > index 62edddb8551e..e58495403dde 100644
> > --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
> > +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
> > @@ -11,6 +11,13 @@
> > #include "bus.h"
> > #include "commands.h"
> >
> > +#define QTNF_SCAN_TIME_AUTO 0
> > +
> > +/* Let device itself to select best values for current conditions */
> > +#define QTNF_SCAN_DWELL_ACTIVE_DEFAULT QTNF_SCAN_TIME_AUTO
> > +#define QTNF_SCAN_DWELL_PASSIVE_DEFAULT QTNF_SCAN_TIME_AUTO
> > +#define QTNF_SCAN_SAMPLE_DURATION_DEFAULT QTNF_SCAN_TIME_AUTO
>
> These three defines look odd. Why not just use QTNF_SCAN_TIME_AUTO
> directly?

Well, this is to be able to tweak their defaults independently if needed.

Regards,
Sergey

2019-03-21 07:35:09

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

Sergey Matyukevich <[email protected]> writes:

>> > Fix creation of debugfs entries for qtnfmac wireless card: use separate
>> > directories for different wireless cards. This commit enables support
>> > for multiple qtnfmac wireless cards on the same PCIe host.
>> >
>> > Signed-off-by: Sergey Matyukevich <[email protected]>
>> > ---
>> > drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
>> > 1 file changed, 5 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>> > index b561b75e4433..56fc6d49c121 100644
>> > --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>> > +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>> > @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
>> >
>> > int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>> > {
>> > + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
>> > + char card_id[64];
>> > int ret;
>> >
>> > bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
>> > @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>> > if (ret) {
>> > pr_err("failed to attach core\n");
>> > } else {
>> > - qtnf_debugfs_init(bus, DRV_NAME);
>> > + snprintf(card_id, sizeof(card_id), "%s:%s",
>> > + DRV_NAME, pci_name(priv->pdev));
>>
>> Can you give an example for the path?
>>
>
> For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0

TBH not really fond of that. What about
"/sys/kernel/debug/qtnfmac/pcie:0000:01:00.0"? IIRC iwlwifi used
something like that.

And please add an example path to the commit log.

--
Kalle Valo

2019-03-21 08:26:39

by Sergey Matyukevich

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

Hello Kalle,

> >> > Fix creation of debugfs entries for qtnfmac wireless card: use separate
> >> > directories for different wireless cards. This commit enables support
> >> > for multiple qtnfmac wireless cards on the same PCIe host.
> >> >
> >> > Signed-off-by: Sergey Matyukevich <[email protected]>
> >> > ---
> >> > drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
> >> > 1 file changed, 5 insertions(+), 1 deletion(-)
> >> >
> >> > diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> >> > index b561b75e4433..56fc6d49c121 100644
> >> > --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> >> > +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> >> > @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
> >> >
> >> > int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> >> > {
> >> > + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
> >> > + char card_id[64];
> >> > int ret;
> >> >
> >> > bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
> >> > @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> >> > if (ret) {
> >> > pr_err("failed to attach core\n");
> >> > } else {
> >> > - qtnf_debugfs_init(bus, DRV_NAME);
> >> > + snprintf(card_id, sizeof(card_id), "%s:%s",
> >> > + DRV_NAME, pci_name(priv->pdev));
> >>
> >> Can you give an example for the path?
> >>
> >
> > For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0
>
> TBH not really fond of that. What about
> "/sys/kernel/debug/qtnfmac/pcie:0000:01:00.0"? IIRC iwlwifi used
> something like that.
>
> And please add an example path to the commit log.

Ok, will be fixed and resubmitted in v2.

Or, alternatively, if the other patches are ok for you,
feel free to drop the questionable ones and apply all
the others. I will rework the rejected pieces and
resubmit them, adding more pending fixes.

Regards,
Sergey

2019-03-21 10:15:06

by Arend Van Spriel

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

On 3/21/2019 8:35 AM, Kalle Valo wrote:
> Sergey Matyukevich <[email protected]> writes:
>
>>>> Fix creation of debugfs entries for qtnfmac wireless card: use separate
>>>> directories for different wireless cards. This commit enables support
>>>> for multiple qtnfmac wireless cards on the same PCIe host.
>>>>
>>>> Signed-off-by: Sergey Matyukevich <[email protected]>
>>>> ---
>>>> drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
>>>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>>>> index b561b75e4433..56fc6d49c121 100644
>>>> --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>>>> +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>>>> @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
>>>>
>>>> int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>>>> {
>>>> + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
>>>> + char card_id[64];
>>>> int ret;
>>>>
>>>> bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
>>>> @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>>>> if (ret) {
>>>> pr_err("failed to attach core\n");
>>>> } else {
>>>> - qtnf_debugfs_init(bus, DRV_NAME);
>>>> + snprintf(card_id, sizeof(card_id), "%s:%s",
>>>> + DRV_NAME, pci_name(priv->pdev));
>>>
>>> Can you give an example for the path?
>>>
>>
>> For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0
>
> TBH not really fond of that. What about
> "/sys/kernel/debug/qtnfmac/pcie:0000:01:00.0"? IIRC iwlwifi used
> something like that.

In brcmfmac we used to have it like that, but I changed it to use wiphy
debugfs, ie. /sys/kernel/debug/ieee80211/phyX/.

Gr. AvS

2019-03-21 15:47:40

by Sergey Matyukevich

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

> > > > > Fix creation of debugfs entries for qtnfmac wireless card: use separate
> > > > > directories for different wireless cards. This commit enables support
> > > > > for multiple qtnfmac wireless cards on the same PCIe host.
> > > > >
> > > > > Signed-off-by: Sergey Matyukevich <[email protected]>
> > > > > ---
> > > > > drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
> > > > > 1 file changed, 5 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> > > > > index b561b75e4433..56fc6d49c121 100644
> > > > > --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> > > > > +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
> > > > > @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
> > > > >
> > > > > int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> > > > > {
> > > > > + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
> > > > > + char card_id[64];
> > > > > int ret;
> > > > >
> > > > > bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
> > > > > @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
> > > > > if (ret) {
> > > > > pr_err("failed to attach core\n");
> > > > > } else {
> > > > > - qtnf_debugfs_init(bus, DRV_NAME);
> > > > > + snprintf(card_id, sizeof(card_id), "%s:%s",
> > > > > + DRV_NAME, pci_name(priv->pdev));
> > > >
> > > > Can you give an example for the path?
> > > >
> > >
> > > For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0
> >
> > TBH not really fond of that. What about
> > "/sys/kernel/debug/qtnfmac/pcie:0000:01:00.0"? IIRC iwlwifi used
> > something like that.


Hello Arend,

> In brcmfmac we used to have it like that, but I changed it to use wiphy
> debugfs, ie. /sys/kernel/debug/ieee80211/phyX/.

Yes, I saw the patches for brcmfmac. In fact, looking at those patches
we figured out that we have a problem before we started testing
two cards in one pcie host :)

But /sys/kernel/debug/eee80211/phyX approach does not fit well for our
use-case. We may have up to 3 phy-s for single card, but counters
exported via debugfs are for pcie device as a whole.

Thanks,
Sergey

2019-03-21 17:06:51

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

Arend Van Spriel <[email protected]> writes:

> On 3/21/2019 8:35 AM, Kalle Valo wrote:
>> Sergey Matyukevich <[email protected]> writes:
>>
>>>>> Fix creation of debugfs entries for qtnfmac wireless card: use separate
>>>>> directories for different wireless cards. This commit enables support
>>>>> for multiple qtnfmac wireless cards on the same PCIe host.
>>>>>
>>>>> Signed-off-by: Sergey Matyukevich <[email protected]>
>>>>> ---
>>>>> drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
>>>>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>>>>> index b561b75e4433..56fc6d49c121 100644
>>>>> --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>>>>> +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>>>>> @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
>>>>>
>>>>> int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>>>>> {
>>>>> + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
>>>>> + char card_id[64];
>>>>> int ret;
>>>>>
>>>>> bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
>>>>> @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>>>>> if (ret) {
>>>>> pr_err("failed to attach core\n");
>>>>> } else {
>>>>> - qtnf_debugfs_init(bus, DRV_NAME);
>>>>> + snprintf(card_id, sizeof(card_id), "%s:%s",
>>>>> + DRV_NAME, pci_name(priv->pdev));
>>>>
>>>> Can you give an example for the path?
>>>>
>>>
>>> For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0
>>
>> TBH not really fond of that. What about
>> "/sys/kernel/debug/qtnfmac/pcie:0000:01:00.0"? IIRC iwlwifi used
>> something like that.
>
> In brcmfmac we used to have it like that, but I changed it to use
> wiphy debugfs, ie. /sys/kernel/debug/ieee80211/phyX/.

Yeah, that's much better.

--
Kalle Valo

2019-03-22 08:44:12

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host

Sergey Matyukevich <[email protected]> writes:

> Hello Kalle,
>
>> >> > Fix creation of debugfs entries for qtnfmac wireless card: use separate
>> >> > directories for different wireless cards. This commit enables support
>> >> > for multiple qtnfmac wireless cards on the same PCIe host.
>> >> >
>> >> > Signed-off-by: Sergey Matyukevich <[email protected]>
>> >> > ---
>> >> > drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 6 +++++-
>> >> > 1 file changed, 5 insertions(+), 1 deletion(-)
>> >> >
>> >> > diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>> >> > index b561b75e4433..56fc6d49c121 100644
>> >> > --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>> >> > +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
>> >> > @@ -130,6 +130,8 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data)
>> >> >
>> >> > int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>> >> > {
>> >> > + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
>> >> > + char card_id[64];
>> >> > int ret;
>> >> >
>> >> > bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
>> >> > @@ -137,7 +139,9 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus)
>> >> > if (ret) {
>> >> > pr_err("failed to attach core\n");
>> >> > } else {
>> >> > - qtnf_debugfs_init(bus, DRV_NAME);
>> >> > + snprintf(card_id, sizeof(card_id), "%s:%s",
>> >> > + DRV_NAME, pci_name(priv->pdev));
>> >>
>> >> Can you give an example for the path?
>> >>
>> >
>> > For instance: /sys/kernel/debug/qtnfmac_pcie:0000:01:00.0
>>
>> TBH not really fond of that. What about
>> "/sys/kernel/debug/qtnfmac/pcie:0000:01:00.0"? IIRC iwlwifi used
>> something like that.
>>
>> And please add an example path to the commit log.
>
> Ok, will be fixed and resubmitted in v2.

Thanks.

> Or, alternatively, if the other patches are ok for you,
> feel free to drop the questionable ones and apply all
> the others. I will rework the rejected pieces and
> resubmit them, adding more pending fixes.

A good point, that's easier. So I have dropped patch 12.

--
Kalle Valo

2019-04-04 09:58:28

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 01/14] qtnfmac: make regulatory notifier work on per-phy basis

Sergey Matyukevich <[email protected]> wrote:

> From: Igor Mitsyanko <[email protected]>
>
> Wireless core calls regulatory notifier for each wiphy and it only
> guarantees that bands info is updated for this particular wiphy prior
> to calling a notifier. Hence updating all wiphy which belong to driver
> in a single notifier callback is redundant and incorrect.
>
> Signed-off-by: Igor Mitsyanko <[email protected]>

13 patches applied to wireless-drivers-next.git, thanks.

d123172175db qtnfmac: make regulatory notifier work on per-phy basis
642f15a5cee7 qtnfmac: simplify error reporting in regulatory notifier
a2fbaaf757e3 qtnfmac: include full channels info to regulatory notifier
2c31129f8f40 qtnfmac: pass complete channel info in regulatory notifier
48cefdfbcb57 qtnfmac: flexible regulatory domain registration logic
c698bce01562 qtnfmac: allow each MAC to specify its own regulatory rules
438fb43bcab1 qtnfmac: pass DFS region to firmware on region update
93eeab26791d qtnfmac: update bands information on CHANGE_INTF command
ae1946be26bc qtnfmac: fix core attach error path in pcie backend
83b00f6eb863 qtnfmac: simplify firmware state tracking
72b3270e01ab qtnfmac: allow changing the netns
bc70732f9bd9 qtnfmac: send EAPOL frames via control path
b63967cae6b1 qtnfmac: use scan duration param for different scan types

--
https://patchwork.kernel.org/patch/10861235/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches