2017-09-21 21:34:43

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 0/9] qtnfmac: more info on current channel from device

From: Igor Mitsyanko <[email protected]>

This patchset has a goal to start using full current channel information
as reported by wireless device (specifically, center freq 1 and 2 and
operational BW).

It was part of bigger changeset when it was V1.

Changelist V2->V3:
Do not leave commit messages empty

Changelist V1->V2:
PATCH 2:
- do not rename "chandef" local variable with no purpose
- report secondary center frequency in info messages
PATCH 3:
- report secondary center frequency in info messages

Igor Mitsyanko (9):
qtnfmac: convert channel width from bitfiled to simple enum
qtnfmac: make "Channel change" event report full channel info
qtnfmac: retrieve current channel info from EP
qtnfmac: do not cache channel info from "connect" command
qtnfmac: let wifi card handle channel switch request to the same
chan
qtnfmac: pass VIF info to SendChannel command
qtnfmac: do not cache CSA chandef info
qtnfmac: remove unused mac::status field
qtnfmac: do not report channel changes until wiphy is registered

drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 69 +++++-----------------
drivers/net/wireless/quantenna/qtnfmac/commands.c | 52 +++++++++++++---
drivers/net/wireless/quantenna/qtnfmac/commands.h | 3 +-
drivers/net/wireless/quantenna/qtnfmac/core.h | 6 --
drivers/net/wireless/quantenna/qtnfmac/event.c | 34 ++++-------
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 45 ++++++++++----
.../net/wireless/quantenna/qtnfmac/qlink_util.c | 68 ++++++++++++++++++---
.../net/wireless/quantenna/qtnfmac/qlink_util.h | 4 ++
8 files changed, 175 insertions(+), 106 deletions(-)

--
2.9.5


2017-09-21 21:35:03

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 5/9] qtnfmac: let wifi card handle channel switch request to the same chan

From: Igor Mitsyanko <[email protected]>

No reason to verify channel switch request in driver, it can simply be
forwarded to wireless device. Device can perform required checks and
return appropriate error code, and driver may not even have information
on current operational channel.

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

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 17b323e..4590f30 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -846,11 +846,6 @@ static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}

- if (cfg80211_chandef_identical(&params->chandef, &mac->chandef)) {
- pr_err("%s: switch request to the same channel\n", dev->name);
- return -EALREADY;
- }
-
ret = qtnf_cmd_send_chan_switch(mac, params);
if (ret)
pr_warn("%s: failed to switch to channel (%u)\n",
--
2.9.5

2017-09-21 21:35:02

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 4/9] qtnfmac: do not cache channel info from "connect" command

From: Igor Mitsyanko <[email protected]>

This makes no sense because real operational channel is choosen based
on AP operation, not on what STA is configured to.

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

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 0ef1285..17b323e 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -613,8 +613,6 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
- struct qtnf_wmac *mac = wiphy_priv(wiphy);
- struct cfg80211_chan_def chandef;
struct qtnf_bss_config *bss_cfg;
int ret;

@@ -627,18 +625,6 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
bss_cfg = &vif->bss_cfg;
memset(bss_cfg, 0, sizeof(*bss_cfg));

- if (sme->channel) {
- /* FIXME: need to set proper nl80211_channel_type value */
- cfg80211_chandef_create(&chandef, sme->channel,
- NL80211_CHAN_HT20);
- /* fall-back to minimal safe chandef description */
- if (!cfg80211_chandef_valid(&chandef))
- cfg80211_chandef_create(&chandef, sme->channel,
- NL80211_CHAN_HT20);
-
- memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));
- }
-
bss_cfg->ssid_len = sme->ssid_len;
memcpy(&bss_cfg->ssid, sme->ssid, bss_cfg->ssid_len);
bss_cfg->auth_type = sme->auth_type;
@@ -663,6 +649,7 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
bss_cfg->connect_flags |= QLINK_STA_CONNECT_USE_RRM;

memcpy(&bss_cfg->crypto, &sme->crypto, sizeof(bss_cfg->crypto));
+
if (sme->bssid)
ether_addr_copy(bss_cfg->bssid, sme->bssid);
else
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 806b88b..c55bae1 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2055,8 +2055,10 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,

ether_addr_copy(cmd->bssid, bss_cfg->bssid);

- if (vif->mac->chandef.chan)
- cmd->channel = cpu_to_le16(vif->mac->chandef.chan->hw_value);
+ if (sme->channel)
+ cmd->channel = cpu_to_le16(sme->channel->hw_value);
+ else
+ cmd->channel = 0;

cmd->bg_scan_period = cpu_to_le16(bss_cfg->bg_scan_period);

--
2.9.5

2017-09-21 21:34:48

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 2/9] qtnfmac: make "Channel change" event report full channel info

From: Igor Mitsyanko <[email protected]>

Specifically, it has to report center frequency, secondary center
frequency (for 80+80) and BW.
Introduce channel definition structure to qlink and modify channel
change event processing function accordingly.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/event.c | 29 ++++++------
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 18 +++++++-
.../net/wireless/quantenna/qtnfmac/qlink_util.c | 52 ++++++++++++++++++++++
.../net/wireless/quantenna/qtnfmac/qlink_util.h | 4 ++
4 files changed, 85 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
index 0fc2814..df58e83 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
@@ -25,6 +25,7 @@
#include "trans.h"
#include "util.h"
#include "event.h"
+#include "qlink_util.h"

static int
qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
@@ -359,39 +360,35 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
{
struct wiphy *wiphy = priv_to_wiphy(mac);
struct cfg80211_chan_def chandef;
- struct ieee80211_channel *chan;
struct qtnf_vif *vif;
- int freq;
int i;

if (len < sizeof(*data)) {
- pr_err("payload is too short\n");
+ pr_err("MAC%u: payload is too short\n", mac->macid);
return -EINVAL;
}

- freq = le32_to_cpu(data->freq);
- chan = ieee80211_get_channel(wiphy, freq);
- if (!chan) {
- pr_err("channel at %d MHz not found\n", freq);
+ qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);
+
+ if (!cfg80211_chandef_valid(&chandef)) {
+ pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", mac->macid,
+ chandef.center_freq1, chandef.center_freq2,
+ chandef.width);
return -EINVAL;
}

- pr_debug("MAC%d switch to new channel %u MHz\n", mac->macid, freq);
+ pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
+ mac->macid, chandef.chan->hw_value, chandef.center_freq1,
+ chandef.center_freq2, chandef.width);

if (mac->status & QTNF_MAC_CSA_ACTIVE) {
mac->status &= ~QTNF_MAC_CSA_ACTIVE;
- if (chan->hw_value != mac->csa_chandef.chan->hw_value)
+ if (chandef.chan->hw_value != mac->csa_chandef.chan->hw_value)
pr_warn("unexpected switch to %u during CSA to %u\n",
- chan->hw_value,
+ chandef.chan->hw_value,
mac->csa_chandef.chan->hw_value);
}

- /* FIXME: need to figure out proper nl80211_channel_type value */
- cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
- /* fall-back to minimal safe chandef description */
- if (!cfg80211_chandef_valid(&chandef))
- cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
-
memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));

for (i = 0; i < QTNF_MAX_INTF; i++) {
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index a69fd470..5936854 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -118,6 +118,20 @@ enum qlink_channel_width {
QLINK_CHAN_WIDTH_160,
};

+/**
+ * struct qlink_chandef - qlink channel definition
+ *
+ * @center_freq1: center frequency of first segment
+ * @center_freq2: center frequency of second segment (80+80 only)
+ * @width: channel width, one of @enum qlink_channel_width
+ */
+struct qlink_chandef {
+ __le16 center_freq1;
+ __le16 center_freq2;
+ u8 width;
+ u8 rsvd[3];
+} __packed;
+
/* QLINK Command messages related definitions
*/

@@ -764,11 +778,11 @@ struct qlink_event_bss_leave {
/**
* struct qlink_event_freq_change - data for QLINK_EVENT_FREQ_CHANGE event
*
- * @freq: new operating frequency in MHz
+ * @chan: new operating channel definition
*/
struct qlink_event_freq_change {
struct qlink_event ehdr;
- __le32 freq;
+ struct qlink_chandef chan;
} __packed;

enum qlink_rxmgmt_flags {
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
index 369b77d..3c1db5b 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
@@ -75,3 +75,55 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask)

return result;
}
+
+static enum nl80211_chan_width qlink_chanwidth_to_nl(u8 qlw)
+{
+ switch (qlw) {
+ case QLINK_CHAN_WIDTH_20_NOHT:
+ return NL80211_CHAN_WIDTH_20_NOHT;
+ case QLINK_CHAN_WIDTH_20:
+ return NL80211_CHAN_WIDTH_20;
+ case QLINK_CHAN_WIDTH_40:
+ return NL80211_CHAN_WIDTH_40;
+ case QLINK_CHAN_WIDTH_80:
+ return NL80211_CHAN_WIDTH_80;
+ case QLINK_CHAN_WIDTH_80P80:
+ return NL80211_CHAN_WIDTH_80P80;
+ case QLINK_CHAN_WIDTH_160:
+ return NL80211_CHAN_WIDTH_160;
+ case QLINK_CHAN_WIDTH_5:
+ return NL80211_CHAN_WIDTH_5;
+ case QLINK_CHAN_WIDTH_10:
+ return NL80211_CHAN_WIDTH_10;
+ default:
+ return -1;
+ }
+}
+
+void qlink_chandef_q2cfg(struct wiphy *wiphy,
+ const struct qlink_chandef *qch,
+ struct cfg80211_chan_def *chdef)
+{
+ chdef->center_freq1 = le16_to_cpu(qch->center_freq1);
+ chdef->center_freq2 = le16_to_cpu(qch->center_freq2);
+ chdef->width = qlink_chanwidth_to_nl(qch->width);
+
+ switch (chdef->width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ case NL80211_CHAN_WIDTH_5:
+ case NL80211_CHAN_WIDTH_10:
+ chdef->chan = ieee80211_get_channel(wiphy, chdef->center_freq1);
+ break;
+ case NL80211_CHAN_WIDTH_40:
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_80P80:
+ case NL80211_CHAN_WIDTH_160:
+ chdef->chan = ieee80211_get_channel(wiphy,
+ chdef->center_freq1 - 10);
+ break;
+ default:
+ chdef->chan = NULL;
+ break;
+ }
+}
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
index de06c1e..5e49a8a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h
@@ -19,6 +19,7 @@

#include <linux/types.h>
#include <linux/skbuff.h>
+#include <net/cfg80211.h>

#include "qlink.h"

@@ -62,5 +63,8 @@ static inline void qtnf_cmd_skb_put_tlv_u16(struct sk_buff *skb,

u16 qlink_iface_type_to_nl_mask(u16 qlink_type);
u8 qlink_chan_width_mask_to_nl(u16 qlink_mask);
+void qlink_chandef_q2cfg(struct wiphy *wiphy,
+ const struct qlink_chandef *qch,
+ struct cfg80211_chan_def *chdef);

#endif /* _QTN_FMAC_QLINK_UTIL_H_ */
--
2.9.5

2017-09-21 21:35:01

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 3/9] qtnfmac: retrieve current channel info from EP

From: Igor Mitsyanko <[email protected]>

Do not try to cache current operational channel info in driver, this
is a potential source of synchronization issues + driver does not
really need that info.

Introduce GET_CHANNEL command and process it appropriately.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 35 +++++++++------------
drivers/net/wireless/quantenna/qtnfmac/commands.c | 38 +++++++++++++++++++++++
drivers/net/wireless/quantenna/qtnfmac/commands.h | 1 +
drivers/net/wireless/quantenna/qtnfmac/qlink.h | 11 +++++++
4 files changed, 64 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 856fa6e..0ef1285 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -793,37 +793,30 @@ qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct net_device *ndev = wdev->netdev;
struct qtnf_vif *vif;
+ int ret;

if (!ndev)
return -ENODEV;

vif = qtnf_netdev_get_priv(wdev->netdev);

- switch (vif->wdev.iftype) {
- case NL80211_IFTYPE_STATION:
- if (vif->sta_state == QTNF_STA_DISCONNECTED) {
- pr_warn("%s: STA disconnected\n", ndev->name);
- return -ENODATA;
- }
- break;
- case NL80211_IFTYPE_AP:
- if (!(vif->bss_status & QTNF_STATE_AP_START)) {
- pr_warn("%s: AP not started\n", ndev->name);
- return -ENODATA;
- }
- break;
- default:
- pr_err("unsupported vif type (%d)\n", vif->wdev.iftype);
- return -ENODATA;
+ ret = qtnf_cmd_get_channel(vif, chandef);
+ if (ret) {
+ pr_err("%s: failed to get channel: %d\n", ndev->name, ret);
+ goto out;
}

- if (!cfg80211_chandef_valid(&mac->chandef)) {
- pr_err("invalid channel settings on %s\n", ndev->name);
- return -ENODATA;
+ if (!cfg80211_chandef_valid(chandef)) {
+ pr_err("%s: bad chan freq1=%u freq2=%u bw=%u\n", ndev->name,
+ chandef->center_freq1, chandef->center_freq2,
+ chandef->width);
+ ret = -ENODATA;
}

- memcpy(chandef, &mac->chandef, sizeof(*chandef));
- return 0;
+ memcpy(&mac->chandef, chandef, sizeof(mac->chandef));
+
+out:
+ return ret;
}

static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 4206886..806b88b 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2358,3 +2358,41 @@ int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
qtnf_bus_unlock(mac->bus);
return ret;
}
+
+int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef)
+{
+ struct qtnf_bus *bus = vif->mac->bus;
+ const struct qlink_resp_channel_get *resp;
+ struct sk_buff *cmd_skb;
+ struct sk_buff *resp_skb = NULL;
+ u16 res_code = QLINK_CMD_RESULT_OK;
+ int ret;
+
+ cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
+ QLINK_CMD_CHAN_GET,
+ sizeof(struct qlink_cmd));
+ if (unlikely(!cmd_skb))
+ return -ENOMEM;
+
+ qtnf_bus_lock(bus);
+
+ ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code,
+ sizeof(*resp), NULL);
+
+ qtnf_bus_unlock(bus);
+
+ if (unlikely(ret))
+ goto out;
+
+ if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ resp = (const struct qlink_resp_channel_get *)resp_skb->data;
+ qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef);
+
+out:
+ consume_skb(resp_skb);
+ return ret;
+}
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h b/drivers/net/wireless/quantenna/qtnfmac/commands.h
index 783b203..e1bcb83 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h
@@ -75,5 +75,6 @@ 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_wmac *mac,
struct cfg80211_csa_settings *params);
+int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef);

#endif /* QLINK_COMMANDS_H_ */
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index 5936854..fb88f3e 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -169,6 +169,7 @@ enum qlink_cmd_type {
QLINK_CMD_REG_NOTIFY = 0x0019,
QLINK_CMD_CHANS_INFO_GET = 0x001A,
QLINK_CMD_CHAN_SWITCH = 0x001B,
+ QLINK_CMD_CHAN_GET = 0x001C,
QLINK_CMD_CONFIG_AP = 0x0020,
QLINK_CMD_START_AP = 0x0021,
QLINK_CMD_STOP_AP = 0x0022,
@@ -694,6 +695,16 @@ struct qlink_resp_get_chan_stats {
u8 info[0];
} __packed;

+/**
+ * struct qlink_resp_channel_get - response for QLINK_CMD_CHAN_GET command
+ *
+ * @chan: definition of current operating channel.
+ */
+struct qlink_resp_channel_get {
+ struct qlink_resp rhdr;
+ struct qlink_chandef chan;
+} __packed;
+
/* QLINK Events messages related definitions
*/

--
2.9.5

2017-09-21 21:35:07

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 7/9] qtnfmac: do not cache CSA chandef info

From: Igor Mitsyanko <[email protected]>

It is never used for anything useful, and all logic is handled by
either WiFi card or higher layers.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 12 ------------
drivers/net/wireless/quantenna/qtnfmac/commands.c | 2 --
drivers/net/wireless/quantenna/qtnfmac/core.h | 1 -
drivers/net/wireless/quantenna/qtnfmac/event.c | 8 +-------
4 files changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 30f8be5..262e8cf 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -809,7 +809,6 @@ qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_csa_settings *params)
{
- struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
int ret;

@@ -830,17 +829,6 @@ static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
return -EOPNOTSUPP;
}

- if (vif->vifid != 0) {
- if (!(mac->status & QTNF_MAC_CSA_ACTIVE))
- return -EOPNOTSUPP;
-
- if (!cfg80211_chandef_identical(&params->chandef,
- &mac->csa_chandef))
- return -EINVAL;
-
- return 0;
- }
-
if (!cfg80211_chandef_valid(&params->chandef)) {
pr_err("%s: invalid channel\n", dev->name);
return -EINVAL;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 0138dad..42f7e1d 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2337,8 +2337,6 @@ int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,

switch (res_code) {
case QLINK_CMD_RESULT_OK:
- memcpy(&mac->csa_chandef, &params->chandef,
- sizeof(mac->csa_chandef));
mac->status |= QTNF_MAC_CSA_ACTIVE;
ret = 0;
break;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h
index 066fcd1..521ce09 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.h
@@ -147,7 +147,6 @@ struct qtnf_wmac {
struct qtnf_vif iflist[QTNF_MAX_INTF];
struct cfg80211_scan_request *scan_req;
struct cfg80211_chan_def chandef;
- struct cfg80211_chan_def csa_chandef;
struct mutex mac_lock; /* lock during wmac speicific ops */
struct timer_list scan_timeout;
};
diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
index df58e83..77563b0 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
@@ -381,13 +381,7 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
mac->macid, chandef.chan->hw_value, chandef.center_freq1,
chandef.center_freq2, chandef.width);

- if (mac->status & QTNF_MAC_CSA_ACTIVE) {
- mac->status &= ~QTNF_MAC_CSA_ACTIVE;
- if (chandef.chan->hw_value != mac->csa_chandef.chan->hw_value)
- pr_warn("unexpected switch to %u during CSA to %u\n",
- chandef.chan->hw_value,
- mac->csa_chandef.chan->hw_value);
- }
+ mac->status &= ~QTNF_MAC_CSA_ACTIVE;

memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));

--
2.9.5

2017-09-21 21:34:45

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 1/9] qtnfmac: convert channel width from bitfiled to simple enum

From: Igor Mitsyanko <[email protected]>

This will allow to use qlink channel width values to specify BW setting
corresponding to enum nl80211_chan_width.
Current user is converted to apply BIT() macro manually to each individual
qlink_channel_width enumeration value.

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

diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index a8242f6..a69fd470 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -108,14 +108,14 @@ enum qlink_sta_flags {
};

enum qlink_channel_width {
- QLINK_CHAN_WIDTH_5 = BIT(0),
- QLINK_CHAN_WIDTH_10 = BIT(1),
- QLINK_CHAN_WIDTH_20_NOHT = BIT(2),
- QLINK_CHAN_WIDTH_20 = BIT(3),
- QLINK_CHAN_WIDTH_40 = BIT(4),
- QLINK_CHAN_WIDTH_80 = BIT(5),
- QLINK_CHAN_WIDTH_80P80 = BIT(6),
- QLINK_CHAN_WIDTH_160 = BIT(7),
+ QLINK_CHAN_WIDTH_5 = 0,
+ QLINK_CHAN_WIDTH_10,
+ QLINK_CHAN_WIDTH_20_NOHT,
+ QLINK_CHAN_WIDTH_20,
+ QLINK_CHAN_WIDTH_40,
+ QLINK_CHAN_WIDTH_80,
+ QLINK_CHAN_WIDTH_80P80,
+ QLINK_CHAN_WIDTH_160,
};

/* QLINK Command messages related definitions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
index cf024c9..369b77d 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c
@@ -49,28 +49,28 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask)
{
u8 result = 0;

- if (qlink_mask & QLINK_CHAN_WIDTH_5)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_5))
result |= BIT(NL80211_CHAN_WIDTH_5);

- if (qlink_mask & QLINK_CHAN_WIDTH_10)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_10))
result |= BIT(NL80211_CHAN_WIDTH_10);

- if (qlink_mask & QLINK_CHAN_WIDTH_20_NOHT)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_20_NOHT))
result |= BIT(NL80211_CHAN_WIDTH_20_NOHT);

- if (qlink_mask & QLINK_CHAN_WIDTH_20)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_20))
result |= BIT(NL80211_CHAN_WIDTH_20);

- if (qlink_mask & QLINK_CHAN_WIDTH_40)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_40))
result |= BIT(NL80211_CHAN_WIDTH_40);

- if (qlink_mask & QLINK_CHAN_WIDTH_80)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_80))
result |= BIT(NL80211_CHAN_WIDTH_80);

- if (qlink_mask & QLINK_CHAN_WIDTH_80P80)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_80P80))
result |= BIT(NL80211_CHAN_WIDTH_80P80);

- if (qlink_mask & QLINK_CHAN_WIDTH_160)
+ if (qlink_mask & BIT(QLINK_CHAN_WIDTH_160))
result |= BIT(NL80211_CHAN_WIDTH_160);

return result;
--
2.9.5

2017-09-21 21:35:10

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 9/9] qtnfmac: do not report channel changes until wiphy is registered

From: Igor Mitsyanko <[email protected]>

Wireless device may send "channel changed" event before driver
registered this device with wireless core, which will result in
warnings.
Once device is registered, higher layer will query channel info
manually using .get_channel callback.

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

diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
index b1acc24..7481d5b 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
@@ -368,6 +368,9 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
return -EINVAL;
}

+ if (!wiphy->registered)
+ return 0;
+
qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);

if (!cfg80211_chandef_valid(&chandef)) {
--
2.9.5

2017-09-21 21:35:08

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 8/9] qtnfmac: remove unused mac::status field

From: Igor Mitsyanko <[email protected]>

There are no users of this field and it can safely be removed.

Signed-off-by: Igor Mitsyanko <[email protected]>
---
drivers/net/wireless/quantenna/qtnfmac/commands.c | 1 -
drivers/net/wireless/quantenna/qtnfmac/core.h | 5 -----
drivers/net/wireless/quantenna/qtnfmac/event.c | 2 --
3 files changed, 8 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 42f7e1d..8f95f98 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2337,7 +2337,6 @@ int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,

switch (res_code) {
case QLINK_CMD_RESULT_OK:
- mac->status |= QTNF_MAC_CSA_ACTIVE;
ret = 0;
break;
case QLINK_CMD_RESULT_ENOTFOUND:
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h
index 521ce09..2cd0150 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.h
@@ -89,10 +89,6 @@ enum qtnf_sta_state {
QTNF_STA_CONNECTED
};

-enum qtnf_mac_status {
- QTNF_MAC_CSA_ACTIVE = BIT(0)
-};
-
struct qtnf_vif {
struct wireless_dev wdev;
u8 vifid;
@@ -141,7 +137,6 @@ struct qtnf_wmac {
u8 macid;
u8 wiphy_registered;
u8 macaddr[ETH_ALEN];
- u32 status;
struct qtnf_bus *bus;
struct qtnf_mac_info macinfo;
struct qtnf_vif iflist[QTNF_MAX_INTF];
diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
index 77563b0..b1acc24 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
@@ -381,8 +381,6 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
mac->macid, chandef.chan->hw_value, chandef.center_freq1,
chandef.center_freq2, chandef.width);

- mac->status &= ~QTNF_MAC_CSA_ACTIVE;
-
memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));

for (i = 0; i < QTNF_MAX_INTF; i++) {
--
2.9.5

2017-09-25 08:28:14

by Kalle Valo

[permalink] [raw]
Subject: Re: [V3, 1/9] qtnfmac: convert channel width from bitfiled to simple enum

Igor Mitsyanko <[email protected]> wrote:

> From: Igor Mitsyanko <[email protected]>
>
> This will allow to use qlink channel width values to specify BW setting
> corresponding to enum nl80211_chan_width.
> Current user is converted to apply BIT() macro manually to each individual
> qlink_channel_width enumeration value.
>
> Signed-off-by: Igor Mitsyanko <[email protected]>

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

77d68147745b qtnfmac: convert channel width from bitfiled to simple enum
fac7f9bf1481 qtnfmac: make "Channel change" event report full channel info
9e5478b608b5 qtnfmac: retrieve current channel info from EP
96d4eaf20fb8 qtnfmac: do not cache channel info from "connect" command
3656ab0fef5b qtnfmac: let wifi card handle channel switch request to the same chan
8c015b9067d6 qtnfmac: pass VIF info to SendChannel command
97397633108a qtnfmac: do not cache CSA chandef info
6bfe61d697cb qtnfmac: remove unused mac::status field
115af851234f qtnfmac: do not report channel changes until wiphy is registered

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

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

2017-09-21 21:35:05

by Igor Mitsyanko

[permalink] [raw]
Subject: [PATCH V3 6/9] qtnfmac: pass VIF info to SendChannel command

From: Igor Mitsyanko <[email protected]>

Do not assume whether wireless device can or can not handle switching
several interfaces on a single radio to different channels. Device will
handle it itself and will return appropriate error code.

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

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 4590f30..30f8be5 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -846,7 +846,7 @@ static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}

- ret = qtnf_cmd_send_chan_switch(mac, params);
+ ret = qtnf_cmd_send_chan_switch(vif, params);
if (ret)
pr_warn("%s: failed to switch to channel (%u)\n",
dev->name, params->chandef.chan->hw_value);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index c55bae1..0138dad 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -2306,15 +2306,16 @@ int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel,
return ret;
}

-int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
+int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,
struct cfg80211_csa_settings *params)
{
+ struct qtnf_wmac *mac = vif->mac;
struct qlink_cmd_chan_switch *cmd;
struct sk_buff *cmd_skb;
u16 res_code = QLINK_CMD_RESULT_OK;
int ret;

- cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0x0,
+ cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid,
QLINK_CMD_CHAN_SWITCH,
sizeof(*cmd));

diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h b/drivers/net/wireless/quantenna/qtnfmac/commands.h
index e1bcb83..8a5a82c 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h
@@ -73,7 +73,7 @@ int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif,
int qtnf_cmd_reg_notify(struct qtnf_bus *bus, 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_wmac *mac,
+int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,
struct cfg80211_csa_settings *params);
int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef);

--
2.9.5