* Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host
From: Sergey Matyukevich @ 2019-03-20 15:16 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless@vger.kernel.org, Igor Mitsyanko
In-Reply-To: <874l7xzlmo.fsf@purkki.adurom.net>
> > 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 <sergey.matyukevich.os@quantenna.com>
> > ---
> > 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
^ permalink raw reply
* Re: [PATCH] ath10k: Fix ASPM L1 state on QCA988X
From: Ben Greear @ 2019-03-20 15:12 UTC (permalink / raw)
To: Tomislav Požega, linux-wireless; +Cc: kvalo, Sujith Manoharan
In-Reply-To: <1553025580-6118-1-git-send-email-pozega.tomislav@gmail.com>
On 3/19/19 12:59 PM, Tomislav Požega wrote:
> On some systems there are heavy crashes if the kernel config
> option CONFIG_PCIEASPM_PERFORMANCE is not set. Patch provided by
> Sujith for ath9k fixes this issue and the card operates without
> crashes with kernel default CONFIG_PCIEASPM_DEFAULT option that uses
> BIOS provided ASPM settings. Tested with QCA9862 mPCIe card.
Hello,
Were these firmware crashes or system crashes or both? Can you
describe that a bit more so we can better understand what bugs this
is fixing?
Thanks,
Ben
>
> Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
> ---
> drivers/net/wireless/ath/ath10k/pci.c | 15 +++++++++++++--
> 1 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
> index 271f92c..e24403c 100644
> --- a/drivers/net/wireless/ath/ath10k/pci.c
> +++ b/drivers/net/wireless/ath/ath10k/pci.c
> @@ -2787,14 +2787,25 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar,
> enum ath10k_firmware_mode fw_mode)
> {
> struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
> + struct pci_dev *pdev = ar_pci->pdev;
> int ret;
> + u32 val;
>
> ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n");
>
> - pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL,
> + if (ar->dev_id == QCA988X_2_0_DEVICE_ID) {
> + pci_read_config_dword(pdev, 0x70c, &val);
> + if ((val & 0xff000000) == 0x17000000) {
> + val &= 0x00ffffff;
> + val |= 0x27000000;
> + pci_write_config_dword(pdev, 0x570c, val);
> + }
> + } else {
> + pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL,
> &ar_pci->link_ctl);
> - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
> + pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
> ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
> + }
>
> /*
> * Bring the target up cleanly.
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* crda package not compiled with openssl-1.1.1
From: Chaoxing Lin @ 2019-03-20 14:46 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
USEOPENSSL=1 make
None of crda released package can compiled with openssl-1.1.1 which removed "struct bignum_st"
Can anyone update crda packages?
^ permalink raw reply
* Re: [PATCH 14/14] qtnfmac: use scan duration param for different scan types
From: Kalle Valo @ 2019-03-20 14:08 UTC (permalink / raw)
To: Sergey Matyukevich; +Cc: linux-wireless@vger.kernel.org, Igor Mitsyanko
In-Reply-To: <20190320100340.14168-15-sergey.matyukevich.os@quantenna.com>
Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> writes:
> From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
>
> 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 <igor.mitsyanko.os@quantenna.com>
> ---
> 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
^ permalink raw reply
* Re: [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host
From: Kalle Valo @ 2019-03-20 14:05 UTC (permalink / raw)
To: Sergey Matyukevich; +Cc: linux-wireless@vger.kernel.org, Igor Mitsyanko
In-Reply-To: <20190320100340.14168-13-sergey.matyukevich.os@quantenna.com>
Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> 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 <sergey.matyukevich.os@quantenna.com>
> ---
> 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
^ permalink raw reply
* Re: [PATCH] ath9k: Differentiate between max combined and per chain power
From: Tom Psyborg @ 2019-03-20 13:49 UTC (permalink / raw)
To: Sven Eckelmann; +Cc: linux-wireless, Kalle Valo, QCA ath9k Development
In-Reply-To: <20190320103723.27228-1-sven@narfation.org>
On 20/03/2019, Sven Eckelmann <sven@narfation.org> wrote:
> This also means that a device with multiple tx chains is even limited
> further:
>
> * 1 chain: 31 dBm per chain
> * 2 chains: 28 dBm per chain
> * 3 chains: 26 dBm per chain
>
This is flawed theory and should be reverted instead of making further
complications. Simplest way would be to remove
POWER_CORRECTION_FOR_TWO_CHAIN and POWER_CORRECTION_FOR_THREE_CHAIN;
from driver
^ permalink raw reply
* Re: [PATCH RFC v2] mac80211: debugfs option to force TX status frames
From: Jeremy Sowden @ 2019-03-20 12:13 UTC (permalink / raw)
To: Julius Niedworok
Cc: Kalle Valo, ga58taw, linux-wireless, david, nc, Johannes Berg,
David S. Miller, netdev, linux-kernel
In-Reply-To: <D78A58DC-E38B-4BD8-9D11-A873FFE16602@gmx.net>
[-- Attachment #1: Type: text/plain, Size: 1304 bytes --]
On 2019-03-19, at 16:07:32 +0100, Julius Niedworok wrote:
> On 11.03.2019 15:52, Jeremy Sowden wrote:
> > It's the value that matters, not the type. It will only be too big
> > for the buffer if the result of casting local->force_tx_status to
> > int is less than -9 or greeater than 99.
> >
> > scnprintf(buf, size(buf), "%lld\n",
> > (long long)local->force_tx_status)
> >
> > would also be fine if the value were in range. Note also that
> > scnprintf will not overrun the buffer: it will truncate the string.
>
> Thanks for the clarification :)
You're welcome. :)
> > As it happens, arguments to variadic functions are subject to the
> > "default argument promotions," so if local->force_tx_status is in
> > fact a bool (I can't find the definition), it would be promoted to
> > int and the cast is superfluous.
>
> Yes - the cast is superfluous. We still think it might be useful to
> keep it there to make the point that the value will be casted.
> However, if you prefer to omit the cast, we are happy to take it out.
If I were maintaining this code, I'd probably take it out. However, I
did have to check the documentation to verify that the cast wasn't
required, and I know the more obscure corners of the C standard pretty
well, so it may cause less confusion to keep it.
J.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 0/2] Add xo calibration support for wifi rf clock
From: Govind Singh @ 2019-03-20 11:46 UTC (permalink / raw)
To: Sven Eckelmann
Cc: ath10k, linux-wireless, Shashidhar Lakkavalli,
Catrinel Catrinescu, srichara
In-Reply-To: <2614783.8fX38OIfA2@bentobox>
Hi Sven,
On 2019-03-20 14:07, Sven Eckelmann wrote:
> On Wednesday, 20 March 2019 05:45:09 CET Govind Singh wrote:
>> PMIC XO is the clock source for wifi rf clock in integrated wifi
>> chipset ex: WCN3990. Due to board layout errors XO frequency drifts
>> can cause wifi rf clock inaccuracy.
>> XO calibration test tree in Factory Test Mode is used to find the
>> best frequency offset(for example +/-2KHz )by programming XO trim
>> register. This ensure system clock stays within required 20 ppm
>> WLAN rf clock.
>>
>> Retrieve the xo trim offset via system firmware (e.g., device tree),
>> especially in the case where the device doesn't have a useful EEPROM
>> on which to store the calibrated XO offset (e.g., for integrated
>> Wifi).
>> Calibrated XO offset is sent to fw, which compensate the clock drift
>> by programing the XO trim register.
>
> Who is responsible to fill in this values in the device-tree?
This is populated via boot-loader/system fw(for chrome-OS its coreboot).
Post calibration QDART writes to non-volatile/persist region and
during boot up boot loader fills this value in dt node as there is
no otp region or EPROM available.
> On other
> products, the correct XTAL capacitor registers values are calibrated on
> different devices (in the same product line) separately to ensure that
> each
> device has a minimal inaccuracy. During the boot of the device, the two
> u8
> taken from params_for_tuning_caps (inside the EEPROM) are just written
> to the
> AR_CH0_XTAL register (mapped to the correct the INDAC and OUTDAC
> region).
>
> Your patch here seems to be doing something similar (you may correct me
> if I
> misinterpret something) but you are already saying that these devices
> don't
> have an EEPROM. This is already quite odd because then we also wouldn't
> have
> temperature compensation (also stored in per device EEPROM/precal data
> for
> other devices).
>
> So you move it to the device tree. By default, this device tree is most
> likely
> a static thing which is shipped with the rest of the firmware. So no
> per
> device data is stored in this DTB on the flash. To include device
> specific
> information (mac addresses, calibration data, ...), you could also have
> the
> bootloader (u-boot for example) change the device tree during the boot
> process
> and let it inject the device specific XO trim register data.
>
> How is this planned to work? Is the bootloader expected to modify the
> device
> tree during the boot to provide the device specific xo-cal-data. If
> yes, where
> is it getting the information from? And is there already support for
> QDART for
> it?
>
Per device data will be stored in NOR flash by QDART and dt entry will
be populated during boot by bootloader.
Here we are trying to set the xo trim register of PMIC xtal, which is
the base clk source of wifi rf clk.
> If you do this, why aren't you using the data from qcom,ath10k-pre-
> calibration-data. At least for other ath10k devices, it includes the
> previously mentioned tuning caps. It is the first time I heard about an
> XO
> trim register and thus it might be something different than what I
> expect.
>
No, Integrated chip set ex:WCN3990 does not use
ath10k-pre-calibration-data.
>
> Last question: why is it an u32 when the message with xo_cal_data can
> only
> transport an u8?
>
Yes, this i will fix in next version.
> Kind regards,
> Sven
BR,
Govind
^ permalink raw reply
* [PATCH] ath9k: Differentiate between max combined and per chain power
From: Sven Eckelmann @ 2019-03-20 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Kalle Valo, QCA ath9k Development, Sven Eckelmann
The ath9k driver uses as maximum allowed txpower the constant
MAX_RATE_POWER. It is used to set a maximum txpower limit for the PHY
(which is combined txpower) and also the maximum txpower for per chain
rates. Its value 63 is derived from the maximum number the registers can
store for the per chain txpower.
The max txpower a user can set because of this is 31 dBm (floor(63 / 2)).
This also means that a device with multiple tx chains is even limited
further:
* 1 chain: 31 dBm per chain
* 2 chains: 28 dBm per chain
* 3 chains: 26 dBm per chain
This combined txpower limit of 31 dBm becomes even more problematic when
some extra antenna gain is set in the EEPROM. A high power device is then
no longer able to reach its potential limits.
Instead the code dealing with the combined txpower must use a higher limit
than 63 and only the code dealing with the per chain txpower have to use
the limit of 63. Since the antenna gain can be quite large and 8 bit
variables are often used in ath9k for txpower, a large, divisible by two
number like 254 is a good choice for this new limit.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
drivers/net/wireless/ath/ath9k/eeprom.c | 2 +-
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 1 +
drivers/net/wireless/ath/ath9k/hw.c | 8 ++++----
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/init.c | 2 +-
5 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 6fbd5559c0c0..c22d457dbc54 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -428,7 +428,7 @@ u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit,
else
power_limit = 0;
- return power_limit;
+ return min_t(u16, power_limit, MAX_RATE_POWER);
}
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index b8c0a08066a0..e8c2cc03be0c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -424,6 +424,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
scaledPower = powerLimit - antenna_reduction;
+ scaledPower = min_t(u16, scaledPower, MAX_RATE_POWER);
numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
pCtlMode = ctlModesFor11g;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8581d917635a..f47322869bc3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -446,7 +446,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
regulatory->country_code = CTRY_DEFAULT;
- regulatory->power_limit = MAX_RATE_POWER;
+ regulatory->power_limit = MAX_COMBINED_POWER;
ah->hw_version.magic = AR5416_MAGIC;
ah->hw_version.subvendorid = 0;
@@ -2952,7 +2952,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
ctl = ath9k_regd_get_ctl(reg, chan);
channel = chan->chan;
- chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
+ chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER);
new_pwr = min_t(int, chan_pwr, reg->power_limit);
ah->eep_ops->set_txpower(ah, chan, ctl,
@@ -2965,9 +2965,9 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
struct ath9k_channel *chan = ah->curchan;
struct ieee80211_channel *channel = chan->chan;
- reg->power_limit = min_t(u32, limit, MAX_RATE_POWER);
+ reg->power_limit = min_t(u32, limit, MAX_COMBINED_POWER);
if (test)
- channel->max_power = MAX_RATE_POWER / 2;
+ channel->max_power = MAX_COMBINED_POWER / 2;
ath9k_hw_apply_txpower(ah, chan, test);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 68956cdc8c9a..2e4489700a85 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -173,6 +173,7 @@
#define ATH9K_NUM_QUEUES 10
#define MAX_RATE_POWER 63
+#define MAX_COMBINED_POWER 254 /* 128 dBm, chosen to fit in u8 */
#define AH_WAIT_TIMEOUT 100000 /* (us) */
#define AH_TSF_WRITE_TIMEOUT 100 /* (us) */
#define AH_TIME_QUANTUM 10
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 98141b699c88..043801f773b5 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -805,7 +805,7 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
ah->curchan = &ah->channels[chan->hw_value];
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
ath9k_cmn_get_channel(sc->hw, ah, &chandef);
- ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
+ ath9k_hw_set_txpowerlimit(ah, MAX_COMBINED_POWER, true);
}
}
--
2.20.1
^ permalink raw reply related
* [PATCH 14/14] qtnfmac: use scan duration param for different scan types
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 13/14] qtnfmac: send EAPOL frames via control path
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Use control path to send EAPOL frames to make sure they are
sent with higher priority with aggregation disabled.
Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 11/14] qtnfmac: allow changing the netns
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
Allow to change netns for wireless interfaces created by qtnfmac driver.
Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 09/14] qtnfmac: fix core attach error path in pcie backend
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
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 <sergey.matyukevich.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 06/14] qtnfmac: allow each MAC to specify its own regulatory rules
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 08/14] qtnfmac: update bands information on CHANGE_INTF command
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 10/14] qtnfmac: simplify firmware state tracking
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
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 <sergey.matyukevich.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 12/14] qtnfmac: fix debugfs entries for multiple cards on the same host
From: Sergey Matyukevich @ 2019-03-20 10:04 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
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 <sergey.matyukevich.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 05/14] qtnfmac: flexible regulatory domain registration logic
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 03/14] qtnfmac: include full channels info to regulatory notifier
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 04/14] qtnfmac: pass complete channel info in regulatory notifier
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 07/14] qtnfmac: pass DFS region to firmware on region update
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Pass DFS region as requested by regulatory core directly to firmware
so it can initialize radar detection block accordingly.
Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 01/14] qtnfmac: make regulatory notifier work on per-phy basis
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 02/14] qtnfmac: simplify error reporting in regulatory notifier
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
In-Reply-To: <20190320100340.14168-1-sergey.matyukevich.os@quantenna.com>
From: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
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 <igor.mitsyanko.os@quantenna.com>
---
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
^ permalink raw reply related
* [PATCH 00/14] qtnfmac: regulatory rework and misc fixes
From: Sergey Matyukevich @ 2019-03-20 10:03 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: Igor Mitsyanko, Sergey Matyukevich
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
^ permalink raw reply
* Re: linux-next: Fixes tag needs some work in the net tree
From: Lorenzo Bianconi @ 2019-03-20 9:45 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David Miller, Networking, Linux Next Mailing List,
Linux Kernel Mailing List, Lorenzo Bianconi, Kalle Valo, Wireless
In-Reply-To: <20190320081549.7112c33c@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 619 bytes --]
> Hi all,
>
> In commit
>
> 13f61dfc5235 ("mt76: fix schedule while atomic in mt76x02_reset_state")
>
> Fixes tag
>
> Fixes: e4ebb8b403d1 ("mt76: mt76x2: implement full device restart on watchdog reset")
>
> has these problem(s):
>
> - Target SHA1 does not exist
>
> Did you mean:
>
> 004960423fe1 ("mt76: mt76x2: implement full device restart on watchdog reset")
Hi Stephen,
yes, the right Fixes tag is:
004960423fe1 ("mt76: mt76x2: implement full device restart on watchdog reset")
Sorry for the mistake.
Regards,
Lorenzo
>
> --
> Cheers,
> Stephen Rothwell
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox