* pull-request mwifiex-firmware 2019-02-28
From: Ganapathi Bhat @ 2019-02-28 17:36 UTC (permalink / raw)
To: linux-firmware@kernel.org
Cc: linux-wireless@vger.kernel.org, James Cao, Cathy Luo,
Rakesh Parmar, Zhiyuan Yang
The following changes since commit bd72387b8e49b1b7268ee60c97a131419284fb39:
linux-firmware: update Marvell PCIe-USB8997 firmware image (2019-02-12 11:42:24 +0530)
are available in the git repository at:
git://git.marvell.com/mwifiex-firmware.git
for you to fetch changes up to f0f63ed58fd49c42d06e05d1a6a8a1bd8e8b861c:
linux-firmware: update Marvell 8801/8887 firmware images (2019-02-28 23:02:36 +0530)
----------------------------------------------------------------
Ganapathi Bhat (2):
linux-firmware: update Marvell 8897/8997 firmware images
linux-firmware: update Marvell 8801/8887 firmware images
WHENCE | 10 +++++-----
mrvl/pcie8897_uapsta.bin | Bin 843828 -> 723540 bytes
mrvl/pcie8997_wlan_v4.bin | Bin 428788 -> 456488 bytes
mrvl/sd8801_uapsta.bin | Bin 258680 -> 255988 bytes
mrvl/sd8887_uapsta.bin | Bin 695532 -> 616840 bytes
mrvl/usbusb8997_combo_v4.bin | Bin 604536 -> 610252 bytes
6 files changed, 5 insertions(+), 5 deletions(-)
^ permalink raw reply
* [PATCH v3 2/2] mt76: dma: move mt76x02_init_{tx,rx}_queue in mt76 module
From: Lorenzo Bianconi @ 2019-02-28 16:54 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, lorenzo.bianconi
In-Reply-To: <cover.1551370209.git.lorenzo@kernel.org>
Move mt76x02_init_tx_queue and mt76x02_init_rx_queue in mt76
module in order to be reused adding support for mt7603 driver
and remove duplicated code.
Squash mt76x02_init_tx_queue and mt76x02_init_rx_queue in
mt76_dma_alloc_queue
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/dma.c | 9 ++++++-
drivers/net/wireless/mediatek/mt76/mt76.h | 4 ++-
.../net/wireless/mediatek/mt76/mt7603/dma.c | 26 +++++++------------
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 26 +++++++------------
4 files changed, 31 insertions(+), 34 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 6eedc0ec7661..d2b7fa2c76d1 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -21,7 +21,9 @@
#define DMA_DUMMY_TXWI ((void *) ~0)
static int
-mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q)
+mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ int idx, int n_desc, int bufsize,
+ u32 ring_base)
{
int size;
int i;
@@ -29,6 +31,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q)
spin_lock_init(&q->lock);
INIT_LIST_HEAD(&q->swq);
+ q->regs = dev->mmio.regs + ring_base + idx * MT_RING_SIZE;
+ q->ndesc = n_desc;
+ q->buf_size = bufsize;
+ q->hw_idx = idx;
+
size = q->ndesc * sizeof(struct mt76_desc);
q->desc = dmam_alloc_coherent(dev->dev, size, &q->desc_dma, GFP_KERNEL);
if (!q->desc)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 6376592e3cfd..29409f0871b7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -148,7 +148,9 @@ struct mt76_mcu_ops {
struct mt76_queue_ops {
int (*init)(struct mt76_dev *dev);
- int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q);
+ int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q,
+ int idx, int n_desc, int bufsize,
+ u32 ring_base);
int (*add_buf)(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_buf *buf, int nbufs, u32 info,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index d69e82c66ab2..5067c49142f7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -8,15 +8,12 @@ static int
mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_queue *q,
int idx, int n_desc)
{
- int ret;
-
- q->hw_idx = idx;
- q->regs = dev->mt76.mmio.regs + MT_TX_RING_BASE + idx * MT_RING_SIZE;
- q->ndesc = n_desc;
+ int err;
- ret = mt76_queue_alloc(dev, q);
- if (ret)
- return ret;
+ err = mt76_queue_alloc(dev, q, idx, n_desc, 0,
+ MT_TX_RING_BASE);
+ if (err < 0)
+ return err;
mt7603_irq_enable(dev, MT_INT_TX_DONE(idx));
@@ -106,15 +103,12 @@ static int
mt7603_init_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q,
int idx, int n_desc, int bufsize)
{
- int ret;
-
- q->regs = dev->mt76.mmio.regs + MT_RX_RING_BASE + idx * MT_RING_SIZE;
- q->ndesc = n_desc;
- q->buf_size = bufsize;
+ int err;
- ret = mt76_queue_alloc(dev, q);
- if (ret)
- return ret;
+ err = mt76_queue_alloc(dev, q, idx, n_desc, bufsize,
+ MT_RX_RING_BASE);
+ if (err < 0)
+ return err;
mt7603_irq_enable(dev, MT_INT_RX_DONE(idx));
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 507f368ed3f7..1a7926de1dec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -155,15 +155,12 @@ static int
mt76x02_init_tx_queue(struct mt76x02_dev *dev, struct mt76_queue *q,
int idx, int n_desc)
{
- int ret;
+ int err;
- q->regs = dev->mt76.mmio.regs + MT_TX_RING_BASE + idx * MT_RING_SIZE;
- q->ndesc = n_desc;
- q->hw_idx = idx;
-
- ret = mt76_queue_alloc(dev, q);
- if (ret)
- return ret;
+ err = mt76_queue_alloc(dev, q, idx, n_desc, 0,
+ MT_TX_RING_BASE);
+ if (err < 0)
+ return err;
mt76x02_irq_enable(dev, MT_INT_TX_DONE(idx));
@@ -174,15 +171,12 @@ static int
mt76x02_init_rx_queue(struct mt76x02_dev *dev, struct mt76_queue *q,
int idx, int n_desc, int bufsize)
{
- int ret;
+ int err;
- q->regs = dev->mt76.mmio.regs + MT_RX_RING_BASE + idx * MT_RING_SIZE;
- q->ndesc = n_desc;
- q->buf_size = bufsize;
-
- ret = mt76_queue_alloc(dev, q);
- if (ret)
- return ret;
+ err = mt76_queue_alloc(dev, q, idx, n_desc, bufsize,
+ MT_RX_RING_BASE);
+ if (err < 0)
+ return err;
mt76x02_irq_enable(dev, MT_INT_RX_DONE(idx));
--
2.20.1
^ permalink raw reply related
* [PATCH v3 1/2] mt76: mmio: move mt76x02_set_irq_mask in mt76 module
From: Lorenzo Bianconi @ 2019-02-28 16:54 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, lorenzo.bianconi
In-Reply-To: <cover.1551370209.git.lorenzo@kernel.org>
Move mt76x02_set_irq_mask in mt76 module in order to be reused
adding support for mt7603 driver and remove duplicated code
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mmio.c | 13 +++++++++++++
drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++
drivers/net/wireless/mediatek/mt76/mt7603/core.c | 11 -----------
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 6 ++----
drivers/net/wireless/mediatek/mt76/mt76x02.h | 5 ++---
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 12 ------------
6 files changed, 19 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c
index 1d6bbce76041..059f13bf9dff 100644
--- a/drivers/net/wireless/mediatek/mt76/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mmio.c
@@ -70,6 +70,19 @@ static int mt76_mmio_rd_rp(struct mt76_dev *dev, u32 base,
return 0;
}
+void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr,
+ u32 clear, u32 set)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->mmio.irq_lock, flags);
+ dev->mmio.irqmask &= ~clear;
+ dev->mmio.irqmask |= set;
+ mt76_mmio_wr(dev, addr, dev->mmio.irqmask);
+ spin_unlock_irqrestore(&dev->mmio.irq_lock, flags);
+}
+EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+
void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
{
static const struct mt76_bus_ops mt76_mmio_ops = {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 5dfb0601f101..6376592e3cfd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -766,4 +766,6 @@ void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb);
struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev,
unsigned long expires);
+void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
+
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/core.c b/drivers/net/wireless/mediatek/mt76/mt7603/core.c
index 1086dcd376a0..e32a16f2ebe8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/core.c
@@ -2,17 +2,6 @@
#include "mt7603.h"
-void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->mt76.mmio.irq_lock, flags);
- dev->mt76.mmio.irqmask &= ~clear;
- dev->mt76.mmio.irqmask |= set;
- mt76_wr(dev, MT_INT_MASK_CSR, dev->mt76.mmio.irqmask);
- spin_unlock_irqrestore(&dev->mt76.mmio.irq_lock, flags);
-}
-
void mt7603_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 79f332429432..dc9f2e9b20f6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -179,16 +179,14 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev);
int mt7603_mcu_init(struct mt7603_dev *dev);
void mt7603_init_debugfs(struct mt7603_dev *dev);
-void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set);
-
static inline void mt7603_irq_enable(struct mt7603_dev *dev, u32 mask)
{
- mt7603_set_irq_mask(dev, 0, mask);
+ mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, 0, mask);
}
static inline void mt7603_irq_disable(struct mt7603_dev *dev, u32 mask)
{
- mt7603_set_irq_mask(dev, mask, 0);
+ mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
}
void mt7603_mac_dma_start(struct mt7603_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 6915cce5def9..3d93017c3227 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -183,7 +183,6 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
extern const u16 mt76x02_beacon_offsets[16];
void mt76x02_init_beacon_config(struct mt76x02_dev *dev);
-void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set);
void mt76x02_mac_start(struct mt76x02_dev *dev);
void mt76x02_init_debugfs(struct mt76x02_dev *dev);
@@ -197,12 +196,12 @@ static inline bool is_mt76x2(struct mt76x02_dev *dev)
static inline void mt76x02_irq_enable(struct mt76x02_dev *dev, u32 mask)
{
- mt76x02_set_irq_mask(dev, 0, mask);
+ mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, 0, mask);
}
static inline void mt76x02_irq_disable(struct mt76x02_dev *dev, u32 mask)
{
- mt76x02_set_irq_mask(dev, mask, 0);
+ mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
}
static inline bool
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 1229f19f2b02..507f368ed3f7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -335,18 +335,6 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
}
EXPORT_SYMBOL_GPL(mt76x02_irq_handler);
-void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->mt76.mmio.irq_lock, flags);
- dev->mt76.mmio.irqmask &= ~clear;
- dev->mt76.mmio.irqmask |= set;
- mt76_wr(dev, MT_INT_MASK_CSR, dev->mt76.mmio.irqmask);
- spin_unlock_irqrestore(&dev->mt76.mmio.irq_lock, flags);
-}
-EXPORT_SYMBOL_GPL(mt76x02_set_irq_mask);
-
static void mt76x02_dma_enable(struct mt76x02_dev *dev)
{
u32 val;
--
2.20.1
^ permalink raw reply related
* [PATCH v3 0/2] move dma shared code in mt76 module
From: Lorenzo Bianconi @ 2019-02-28 16:54 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, lorenzo.bianconi
Move mt76x02/mt7603 dma shared code in mmio.c/dma.c in order to be
reused adding support for mt7603 driver
Changes since v2:
- squash mt7603 changes
Changes since v1:
- remove mt76_irq_enable/mt76_irq_disable
- move dma queue initialization in mt76_dma_alloc_queue
- move mt76_irq_enable call into the driver specific
inline functions
Lorenzo Bianconi (2):
mt76: mmio: move mt76x02_set_irq_mask in mt76 module
mt76: dma: move mt76x02_init_{tx,rx}_queue in mt76 module
drivers/net/wireless/mediatek/mt76/dma.c | 9 ++++-
drivers/net/wireless/mediatek/mt76/mmio.c | 13 +++++++
drivers/net/wireless/mediatek/mt76/mt76.h | 6 ++-
.../net/wireless/mediatek/mt76/mt7603/core.c | 11 ------
.../net/wireless/mediatek/mt76/mt7603/dma.c | 26 +++++--------
.../wireless/mediatek/mt76/mt7603/mt7603.h | 6 +--
drivers/net/wireless/mediatek/mt76/mt76x02.h | 5 +--
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 38 +++++--------------
8 files changed, 50 insertions(+), 64 deletions(-)
--
2.20.1
^ permalink raw reply
* [RFC] ath10k: Fix DMA errors related to beacons (CT FW only)
From: greearb @ 2019-02-28 15:58 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
I often saw the ath10k-ct wave-1 firmware spit DMA errors and
hang the entire system, requiring a hard power-cycle to revoer.
It appears the issue is that there is no beacon-tx callback in
stock firmware, so the driver can delete the beacon DMA buffer
while firmware is still trying to access it.
So, wave-1 ath10k-ct firmware now sends a beacon-tx-complete
wmi message and that allows the driver to safely know when it
can clean up the buffer.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
NOTE: This will not apply or work in upstream kernels since the
rest of the CT fw support will not be accepted. But, I'd appreciate
any technical feedback on this in case I missed any corner cases
on locking or similar.
drivers/net/wireless/ath/ath10k/core.c | 1 +
drivers/net/wireless/ath/ath10k/core.h | 6 ++++
drivers/net/wireless/ath/ath10k/mac.c | 14 +++++++++
drivers/net/wireless/ath/ath10k/wmi-ops.h | 12 +++++--
drivers/net/wireless/ath/ath10k/wmi.c | 38 +++++++++++++++++++++--
drivers/net/wireless/ath/ath10k/wmi.h | 8 +++++
6 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index e6664131fdee..929e0c059adc 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -623,6 +623,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
[ATH10K_FW_FEATURE_RETRY_GT2_CT] = "retry-gt2-CT",
[ATH10K_FW_FEATURE_CT_STA] = "CT-STA",
[ATH10K_FW_FEATURE_TXRATE2_CT] = "txrate2-CT",
+ [ATH10K_FW_FEATURE_BEACON_TX_CB_CT] = "beacon-cb-CT",
};
static unsigned int ath10k_core_get_fw_feature_str(char *buf,
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 15621a2af557..a70771170007 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -563,6 +563,7 @@ enum ath10k_beacon_state {
struct ath10k_vif {
struct list_head list;
+ struct completion beacon_tx_done;
u32 vdev_id;
u16 peer_id;
@@ -944,6 +945,11 @@ enum ath10k_fw_features {
/* TX-Rate v2 is reported. */
ATH10K_FW_FEATURE_TXRATE2_CT = 49,
+ /* Firmware will send a beacon-tx-callback message so driver knows when
+ * beacon buffer can be released.
+ */
+ ATH10K_FW_FEATURE_BEACON_TX_CB_CT = 50,
+
/* keep last */
ATH10K_FW_FEATURE_COUNT,
};
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 154dcdabc48a..02a8efa2e783 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -5811,6 +5811,10 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
arvif->ar = ar;
arvif->vif = vif;
+ init_completion(&arvif->beacon_tx_done);
+ /* start completed since we have not sent any beacons yet */
+ complete(&arvif->beacon_tx_done);
+
INIT_LIST_HEAD(&arvif->list);
INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
INIT_DELAYED_WORK(&arvif->connection_loss_work,
@@ -6147,6 +6151,16 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
arvif->vdev_id, ret);
+ if (test_bit(ATH10K_FW_FEATURE_BEACON_TX_CB_CT,
+ ar->running_fw->fw_file.fw_features)) {
+ int time_left;
+
+ time_left = wait_for_completion_timeout(&arvif->beacon_tx_done, (3 * HZ));
+ if (!time_left)
+ ath10k_warn(ar, "WARNING: failed to wait for beacon tx callback for vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ }
+
ar->free_vdev_map |= 1LL << arvif->vdev_id;
spin_lock_bh(&ar->data_lock);
list_del(&arvif->list);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 6c6f7db5b20b..dcba53575dfc 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -1000,25 +1000,33 @@ ath10k_wmi_peer_assoc(struct ath10k *ar,
}
static inline int
-ath10k_wmi_beacon_send_ref_nowait(struct ath10k *ar, u32 vdev_id,
+ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif,
const void *bcn, size_t bcn_len,
u32 bcn_paddr, bool dtim_zero,
bool deliver_cab)
{
struct sk_buff *skb;
int ret;
+ struct ath10k *ar = arvif->ar;
if (!ar->wmi.ops->gen_beacon_dma)
return -EOPNOTSUPP;
- skb = ar->wmi.ops->gen_beacon_dma(ar, vdev_id, bcn, bcn_len, bcn_paddr,
+ skb = ar->wmi.ops->gen_beacon_dma(ar, arvif->vdev_id, bcn, bcn_len, bcn_paddr,
dtim_zero, deliver_cab);
if (IS_ERR(skb))
return PTR_ERR(skb);
+ spin_lock_bh(&ar->data_lock);
+ reinit_completion(&arvif->beacon_tx_done);
+ spin_unlock_bh(&ar->data_lock);
+
ret = ath10k_wmi_cmd_send_nowait(ar, skb,
ar->wmi.cmd->pdev_send_bcn_cmdid);
if (ret) {
+ spin_lock_bh(&ar->data_lock);
+ complete(&arvif->beacon_tx_done);
+ spin_unlock_bh(&ar->data_lock);
dev_kfree_skb(skb);
return ret;
}
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 5d89482ffca8..6e9705d3a967 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1846,8 +1846,7 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
dtim_zero = !!(cb->flags & ATH10K_SKB_F_DTIM_ZERO);
deliver_cab = !!(cb->flags & ATH10K_SKB_F_DELIVER_CAB);
- ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
- arvif->vdev_id,
+ ret = ath10k_wmi_beacon_send_ref_nowait(arvif,
bcn->data, bcn->len,
cb->paddr,
dtim_zero,
@@ -5941,6 +5940,38 @@ static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
return 0;
}
+static void ath10k_wmi_event_beacon_tx(struct ath10k *ar, struct sk_buff *skb)
+{
+ struct ath10k_vif *arvif;
+ const struct wmi_beacon_tx_event *ev;
+ u32 vdev_id;
+
+ spin_lock_bh(&ar->data_lock);
+
+ ev = (struct wmi_beacon_tx_event *)skb->data;
+
+ if (WARN_ON_ONCE(skb->len < sizeof(*ev)))
+ goto exit;
+
+ vdev_id = __le32_to_cpu(ev->vdev_id);
+
+ /*ath10k_dbg(ar, ATH10K_DBG_WMI,
+ "wmi event beacon-tx-complete, vdev-id: %u completion-status: 0x%x\n",
+ vdev_id, __le32_to_cpu(ev->tx_status));*/
+
+ arvif = ath10k_get_arvif(ar, vdev_id);
+ if (!arvif) {
+ ath10k_warn(ar, "wmi-event-beacon-tx, could not find vdev for id: %u\n",
+ vdev_id);
+ goto exit;
+ }
+
+ complete(&arvif->beacon_tx_done);
+
+exit:
+ spin_unlock_bh(&ar->data_lock);
+}
+
static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
struct sk_buff *skb)
{
@@ -6269,6 +6300,9 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_10_1_PDEV_BSS_CHAN_INFO_EVENTID: /* Newer CT firmware supports this */
ath10k_wmi_event_pdev_bss_chan_info(ar, skb);
break;
+ case WMI_10_1_BEACON_TX_EVENTID: /* Feb 28, 2019 CT firmware supports this */
+ ath10k_wmi_event_beacon_tx(ar, skb);
+ break;
default:
ath10k_warn(ar, "Unknown (10.1) eventid: %d\n", id);
break;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 49466123b8fe..96066cc57f83 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1533,6 +1533,7 @@ enum wmi_10x_event_id {
WMI_10_1_PDEV_TEMPERATURE_EVENTID = 36898, /* Newer CT firmware */
WMI_10_1_PDEV_BSS_CHAN_INFO_EVENTID = 36900, /* Newer CT firmware */
+ WMI_10_1_BEACON_TX_EVENTID = WMI_10X_END_EVENTID - 4, /* CT FW, beacon tx completed */
WMI_10X_PDEV_UTF_EVENTID = WMI_10X_END_EVENTID - 1,
};
@@ -6223,6 +6224,13 @@ struct wmi_bcn_info {
struct wmi_p2p_noa_info p2p_noa_info;
} __packed;
+/* CT FW only */
+struct wmi_beacon_tx_event {
+ __le32 vdev_id;
+ __le32 tx_status;
+ __le32 future[4];
+};
+
struct wmi_host_swba_event {
__le32 vdev_map;
struct wmi_bcn_info bcn_info[0];
--
2.20.1
^ permalink raw reply related
* pull-request mwifiex-firmware 2019-02-28
From: Ganapathi Bhat @ 2019-02-28 15:55 UTC (permalink / raw)
To: linux-firmware@kernel.org
Cc: linux-wireless@vger.kernel.org, Cathy Luo, James Cao,
Rakesh Parmar, Zhiyuan Yang
The following changes since commit bd72387b8e49b1b7268ee60c97a131419284fb39:
linux-firmware: update Marvell PCIe-USB8997 firmware image (2019-02-12 11:42:24 +0530)
are available in the git repository at:
git://git.marvell.com/mwifiex-firmware.git
for you to fetch changes up to 1a5773c0c89ee44cee51a285d5c7c1063cdb0891:
linux-firmware: update Marvell 8897/8997 firmware images (2019-02-28 21:11:26 +0530)
----------------------------------------------------------------
Ganapathi Bhat (1):
linux-firmware: update Marvell 8897/8997 firmware images
WHENCE | 6 +++---
mrvl/pcie8897_uapsta.bin | Bin 843828 -> 723540 bytes
mrvl/pcie8997_wlan_v4.bin | Bin 428788 -> 456488 bytes
mrvl/usbusb8997_combo_v4.bin | Bin 604536 -> 610252 bytes
4 files changed, 3 insertions(+), 3 deletions(-)
^ permalink raw reply
* [PATCH AUTOSEL 4.20 14/81] wlcore: sdio: Fixup power on/off sequence
From: Sasha Levin @ 2019-02-28 15:07 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ulf Hansson, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190228150813.10256-1-sashal@kernel.org>
From: Ulf Hansson <ulf.hansson@linaro.org>
[ Upstream commit 13e62626c578d9889ebbda7c521be5adff9bef8e ]
During "wlan-up", we are programming the FW into the WiFi-chip. However,
re-programming the FW doesn't work, unless a power cycle of the WiFi-chip
is made in-between the programmings.
To conform to this requirement and to fix the regression in a simple way,
let's start by allowing that the SDIO card (WiFi-chip) may stay powered on
(runtime resumed) when wl12xx_sdio_power_off() returns. The intent with the
current code is to treat this scenario as an error, but unfortunate this
doesn't work as expected, so let's fix this.
The other part is to guarantee that a power cycle of the SDIO card has been
completed when wl12xx_sdio_power_on() returns, as to allow the FW
programming to succeed. However, relying solely on runtime PM to deal with
this isn't sufficient. For example, userspace may prevent runtime suspend
via sysfs for the device that represents the SDIO card, leading to that the
mmc core also keeps it powered on. For this reason, let's instead do a
brute force power cycle in wl12xx_sdio_power_on().
Fixes: 728a9dc61f13 ("wlcore: sdio: Fix flakey SDIO runtime PM handling")
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Tony Lindgren <tony@atomide.com>
Tested-by: Anders Roxell <anders.roxell@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ti/wlcore/sdio.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index bd10165d7eec5..4d4b077011497 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -164,6 +164,12 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
}
sdio_claim_host(func);
+ /*
+ * To guarantee that the SDIO card is power cycled, as required to make
+ * the FW programming to succeed, let's do a brute force HW reset.
+ */
+ mmc_hw_reset(card->host);
+
sdio_enable_func(func);
sdio_release_host(func);
@@ -174,20 +180,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
{
struct sdio_func *func = dev_to_sdio_func(glue->dev);
struct mmc_card *card = func->card;
- int error;
sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);
/* Let runtime PM know the card is powered off */
- error = pm_runtime_put(&card->dev);
- if (error < 0 && error != -EBUSY) {
- dev_err(&card->dev, "%s failed: %i\n", __func__, error);
-
- return error;
- }
-
+ pm_runtime_put(&card->dev);
return 0;
}
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.20 44/81] ath10k: correct bus type for WCN3990
From: Sasha Levin @ 2019-02-28 15:07 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Brian Norris, Kalle Valo, Sasha Levin, ath10k, linux-wireless,
netdev
In-Reply-To: <20190228150813.10256-1-sashal@kernel.org>
From: Brian Norris <briannorris@chromium.org>
[ Upstream commit 2c2008a63e482654ab137c84d3c61c03b75e7df6 ]
WCN3990 is SNOC, not PCI. This prevents probing WCN3990.
Fixes: 367c899f622c ("ath10k: add bus type check in ath10k_init_hw_params")
Signed-off-by: Brian Norris <briannorris@chromium.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath10k/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 59fdda67f89f4..0a3b2c45549eb 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -548,7 +548,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
{
.id = WCN3990_HW_1_0_DEV_VERSION,
.dev_id = 0,
- .bus = ATH10K_BUS_PCI,
+ .bus = ATH10K_BUS_SNOC,
.name = "wcn3990 hw1.0",
.continuous_frag_desc = true,
.tx_chain_mask = 0x7,
--
2.19.1
^ permalink raw reply related
* [PATCH] mt76x02: fix hdr pointer in write txwi for USB
From: Stanislaw Gruszka @ 2019-02-28 15:11 UTC (permalink / raw)
To: Kalle Valo; +Cc: Felix Fietkau, linux-wireless, Lorenzo Bianconi
Since we add txwi at the begining of skb->data, it no longer point
to ieee80211_hdr. This breaks settings TS bit for probe response and
beacons.
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
I do not cc: stable since it does not fix critical issue.
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index fdd6a021914d..bcf3126efda9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -85,8 +85,9 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
mt76x02_insert_hdr_pad(skb);
- txwi = skb_push(skb, sizeof(struct mt76x02_txwi));
+ txwi = (struct mt76x02_txwi *)(skb->data - sizeof(struct mt76x02_txwi));
mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
+ skb_push(skb, sizeof(struct mt76x02_txwi));
pid = mt76_tx_status_skb_add(mdev, wcid, skb);
txwi->pktid = pid;
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 12/64] wlcore: sdio: Fixup power on/off sequence
From: Sasha Levin @ 2019-02-28 15:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ulf Hansson, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190228151105.11277-1-sashal@kernel.org>
From: Ulf Hansson <ulf.hansson@linaro.org>
[ Upstream commit 13e62626c578d9889ebbda7c521be5adff9bef8e ]
During "wlan-up", we are programming the FW into the WiFi-chip. However,
re-programming the FW doesn't work, unless a power cycle of the WiFi-chip
is made in-between the programmings.
To conform to this requirement and to fix the regression in a simple way,
let's start by allowing that the SDIO card (WiFi-chip) may stay powered on
(runtime resumed) when wl12xx_sdio_power_off() returns. The intent with the
current code is to treat this scenario as an error, but unfortunate this
doesn't work as expected, so let's fix this.
The other part is to guarantee that a power cycle of the SDIO card has been
completed when wl12xx_sdio_power_on() returns, as to allow the FW
programming to succeed. However, relying solely on runtime PM to deal with
this isn't sufficient. For example, userspace may prevent runtime suspend
via sysfs for the device that represents the SDIO card, leading to that the
mmc core also keeps it powered on. For this reason, let's instead do a
brute force power cycle in wl12xx_sdio_power_on().
Fixes: 728a9dc61f13 ("wlcore: sdio: Fix flakey SDIO runtime PM handling")
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Tony Lindgren <tony@atomide.com>
Tested-by: Anders Roxell <anders.roxell@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ti/wlcore/sdio.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 750bea3574ee4..627df164b7b6d 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -164,6 +164,12 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
}
sdio_claim_host(func);
+ /*
+ * To guarantee that the SDIO card is power cycled, as required to make
+ * the FW programming to succeed, let's do a brute force HW reset.
+ */
+ mmc_hw_reset(card->host);
+
sdio_enable_func(func);
sdio_release_host(func);
@@ -174,20 +180,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
{
struct sdio_func *func = dev_to_sdio_func(glue->dev);
struct mmc_card *card = func->card;
- int error;
sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);
/* Let runtime PM know the card is powered off */
- error = pm_runtime_put(&card->dev);
- if (error < 0 && error != -EBUSY) {
- dev_err(&card->dev, "%s failed: %i\n", __func__, error);
-
- return error;
- }
-
+ pm_runtime_put(&card->dev);
return 0;
}
--
2.19.1
^ permalink raw reply related
* Re: [RFC 07/12] mt76x02: fix hdr pointer in write txwi for USB
From: Kalle Valo @ 2019-02-28 14:23 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, Felix Fietkau, linux-wireless
In-Reply-To: <20190228135208.GA8852@redhat.com>
Stanislaw Gruszka <sgruszka@redhat.com> writes:
> On Thu, Feb 28, 2019 at 10:38:20AM +0100, Lorenzo Bianconi wrote:
>> > Since we add txwi at the begining of skb->data, it no longer point
>> > to ieee80211_hdr. This breaks settings TS bit for probe response and
>> > beacons.
>> >
>> > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
>> > ---
>> > drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 3 ++-
>> > 1 file changed, 2 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
>> > index fdd6a021914d..bcf3126efda9 100644
>> > --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
>> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
>> > @@ -85,8 +85,9 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
>> >
>> > mt76x02_insert_hdr_pad(skb);
>> >
>> > - txwi = skb_push(skb, sizeof(struct mt76x02_txwi));
>> > + txwi = (struct mt76x02_txwi *)(skb->data - sizeof(struct mt76x02_txwi));
>> > mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
>> > + skb_push(skb, sizeof(struct mt76x02_txwi));
>> >
>> > pid = mt76_tx_status_skb_add(mdev, wcid, skb);
>> > txwi->pktid = pid;
>> > --
>> > 2.20.1
>> >
>>
>> Good catch :)
>> I think we should post it ontop of wireless-drivers since sw encryption is not
>> working now.
>>
>> Acked-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
>
> I can send it against 5.0, if Kalle will accept it, however
> I do not have practical bug associated with this. Maybe we
> sometimes can send ordinal frame with TS bit in txwi and it
> is then malformed by HW, but I'm not sure. IBSS work with
> this bug, not sure about MESH.
Too late for 5.0 as Linus will most likely release it on Sunday. I
recommend sending it to wireless-drivers-next so that I can queue it for
5.1.
--
Kalle Valo
^ permalink raw reply
* Re: [RFC 07/12] mt76x02: fix hdr pointer in write txwi for USB
From: Stanislaw Gruszka @ 2019-02-28 13:52 UTC (permalink / raw)
To: Lorenzo Bianconi, Kalle Valo; +Cc: Felix Fietkau, linux-wireless
In-Reply-To: <20190228093819.GA2768@localhost.localdomain>
On Thu, Feb 28, 2019 at 10:38:20AM +0100, Lorenzo Bianconi wrote:
> > Since we add txwi at the begining of skb->data, it no longer point
> > to ieee80211_hdr. This breaks settings TS bit for probe response and
> > beacons.
> >
> > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> > ---
> > drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> > index fdd6a021914d..bcf3126efda9 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> > @@ -85,8 +85,9 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
> >
> > mt76x02_insert_hdr_pad(skb);
> >
> > - txwi = skb_push(skb, sizeof(struct mt76x02_txwi));
> > + txwi = (struct mt76x02_txwi *)(skb->data - sizeof(struct mt76x02_txwi));
> > mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
> > + skb_push(skb, sizeof(struct mt76x02_txwi));
> >
> > pid = mt76_tx_status_skb_add(mdev, wcid, skb);
> > txwi->pktid = pid;
> > --
> > 2.20.1
> >
>
> Good catch :)
> I think we should post it ontop of wireless-drivers since sw encryption is not
> working now.
>
> Acked-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
I can send it against 5.0, if Kalle will accept it, however
I do not have practical bug associated with this. Maybe we
sometimes can send ordinal frame with TS bit in txwi and it
is then malformed by HW, but I'm not sure. IBSS work with
this bug, not sure about MESH.
Stanislaw
^ permalink raw reply
* Re: MT76x2U crashes XHCI driver on AMD Ryzen system
From: Joerg Roedel @ 2019-02-28 13:40 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Lorenzo Bianconi, Rosen Penev, linux-wireless, Samuel Sieb,
Alexander Duyck, iommu, linux-kernel
In-Reply-To: <20190228121948.GD6072@redhat.com>
On Thu, Feb 28, 2019 at 01:19:48PM +0100, Stanislaw Gruszka wrote:
> Nevermind, the patch is wrong, s->dma_address is initalized in sg_num_pages().
Yes, it is. In sg_num_pages() the offset into the IOMMU mapping is
stored in s->dma_address, taking also the segment boundary mask into
account. map_sg() later only adds the base-address to that.
Regards,
Joerg
^ permalink raw reply
* [PATCH v2] mt76: introduce q->stopped parameter
From: Lorenzo Bianconi @ 2019-02-28 13:31 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, lorenzo.bianconi
In-Reply-To: <cover.1551360035.git.lorenzo@kernel.org>
Introduce mt76_queue stopped parameter in order to run
ieee80211_wake_queue only when mac80211 queues have been
previously stopped and avoid to disable interrupts when
it is not necessary
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes since v1:
- move back ieee80211_stop_queue() inside q->lock critical section
---
drivers/net/wireless/mediatek/mt76/dma.c | 5 ++++-
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
drivers/net/wireless/mediatek/mt76/tx.c | 5 ++++-
drivers/net/wireless/mediatek/mt76/usb.c | 6 +++++-
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 6eedc0ec7661..99e341cb1f92 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -180,7 +180,10 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
else
mt76_dma_sync_idx(dev, q);
- wake = wake && qid < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
+ wake = wake && q->stopped &&
+ qid < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
+ if (wake)
+ q->stopped = false;
if (!q->queued)
wake_up(&dev->tx_wait);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 5dfb0601f101..3152b8c73c4a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -126,6 +126,7 @@ struct mt76_queue {
int ndesc;
int queued;
int buf_size;
+ bool stopped;
u8 buf_offset;
u8 hw_idx;
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 5a349fe3e576..4d38a54014e8 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -289,8 +289,11 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
dev->queue_ops->tx_queue_skb(dev, q, skb, wcid, sta);
dev->queue_ops->kick(dev, q);
- if (q->queued > q->ndesc - 8)
+ if (q->queued > q->ndesc - 8 && !q->stopped) {
ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
+ q->stopped = true;
+ }
+
spin_unlock_bh(&q->lock);
}
EXPORT_SYMBOL_GPL(mt76_tx);
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index ae6ada370597..4c1abd492405 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -655,7 +655,11 @@ static void mt76u_tx_tasklet(unsigned long data)
spin_lock_bh(&q->lock);
}
mt76_txq_schedule(dev, q);
- wake = i < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
+
+ wake = q->stopped && q->queued < q->ndesc - 8;
+ if (wake)
+ q->stopped = false;
+
if (!q->queued)
wake_up(&dev->tx_wait);
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] mt76: introduce q->stopped parameter
From: Lorenzo Bianconi @ 2019-02-28 12:31 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, nbd, linux-wireless
In-Reply-To: <20190228114551.GB6072@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 903 bytes --]
> On Wed, Feb 27, 2019 at 10:40:41PM +0100, Lorenzo Bianconi wrote:
> > @@ -289,9 +290,14 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
> > dev->queue_ops->tx_queue_skb(dev, q, skb, wcid, sta);
> > dev->queue_ops->kick(dev, q);
> >
> > - if (q->queued > q->ndesc - 8)
> > - ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
> > + stop = q->queued > q->ndesc - 8 && !q->stopped;
> > + if (stop)
> > + q->stopped = true;
> > +
> > spin_unlock_bh(&q->lock);
> > +
> > + if (stop)
> > + ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
>
> I don't think taking this outside of spin_lock section is beneficial.
> Actually is better to do this faster than slower to prevent enqueue
> frames by mac80211 and then dropped them due to lack of space in
> mt76 queue.
ack, I will send a v2 moving it back.
Regards,
Lorenzo
>
> Stanislaw
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: MT76x2U crashes XHCI driver on AMD Ryzen system
From: Stanislaw Gruszka @ 2019-02-28 12:19 UTC (permalink / raw)
To: Joerg Roedel
Cc: Lorenzo Bianconi, Rosen Penev, linux-wireless, Samuel Sieb,
Alexander Duyck, iommu, linux-kernel
In-Reply-To: <20190228104223.GA2749@redhat.com>
On Thu, Feb 28, 2019 at 11:42:24AM +0100, Stanislaw Gruszka wrote:
> On Thu, Feb 28, 2019 at 10:04:12AM +0100, Stanislaw Gruszka wrote:
> > On Tue, Feb 26, 2019 at 12:24:08PM +0100, Stanislaw Gruszka wrote:
> > > On Tue, Feb 26, 2019 at 11:44:13AM +0100, Joerg Roedel wrote:
> > > > On Tue, Feb 26, 2019 at 11:34:51AM +0100, Stanislaw Gruszka wrote:
> > > > > On Tue, Feb 26, 2019 at 11:05:36AM +0100, Joerg Roedel wrote:
> > > > > If sg->offset > PAGE_SIZE is fine then most likely we have problem with
> > > > > alignment.
> > > >
> > > > The map_sg implementation in the AMD IOMMU driver uses sg_phys() which
> > > > handles the sg->page + sg->offset calculation fine.
> > > >
> > > > > Note hat issue is with dma_map_sg(), switching to dma_map_single()
> > > > > by using urb->transfer_buffer instead of urb->sg make things work
> > > > > on AMD IOMMU.
> > > >
> > > > On the other hand this points to a bug in the driver, I'll look further
> > > > if I can spot something there.
> > >
> > > I think so too. And I have done some changes that avoid strange allocation
> > > scheme and use usb synchronous messages instead of allocating buffers
> > > with unaligned sizes. However things work ok on Intel IOMMU and
> > > there is no documentation what are dma_map_sg() requirement versus
> > > dma_map_single() which works. I think there are some unwritten
> > > requirements and things can work on some platforms and fails on others
> > > (different IOMMUs, no-IOMMU on some ARCHes)
> >
> > For the record: we have another bug report with this issue:
> > https://bugzilla.kernel.org/show_bug.cgi?id=202673
> >
> > I provided there patch that change alignment for page_frag_alloc() and
> > it did not fixed the problem. So this is not alignment issue.
> > Now I think it could be page->refcount issue ...
>
> I looked at the map_sg() in amd_iommu.c code and one line looks suspicious
> to me, seems we can use not correctly initialized s->dma_address (should be 0,
> but I think can be non-zero if SG was reused). The code also seems do
> not do correct thing if there is more than one SG with multiple pages
> on individual segments. Something like in below patch seems to be more
> appropriate to me (not tested nor compiled).
Nevermind, the patch is wrong, s->dma_address is initalized in sg_num_pages().
Stanislaw
^ permalink raw reply
* Re: [PATCH] mt76: usb: grab rx_page_lock for legacy mode in mt76u_refill_rx
From: Stanislaw Gruszka @ 2019-02-28 11:58 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: Lorenzo Bianconi, nbd, linux-wireless
In-Reply-To: <20190228113746.GC2768@localhost.localdomain>
On Thu, Feb 28, 2019 at 12:37:48PM +0100, Lorenzo Bianconi wrote:
> > On Thu, Feb 28, 2019 at 12:08:45PM +0100, Lorenzo Bianconi wrote:
> > > Grab rx_page_lock in mt76u_refill_rx allocating rx buffer for 'legacy'
> > > mode. Remove gfp from mt76u_refill_rx signature since we need to
> > > use GFP_ATOMIC
> > >
> > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> >
> > I'm doing some cleanup/optimization work which amongs other things
> > will remove rx_page_lock. Please drop this patch.
>
> Oh, ok. IIRC we need rx_page_lock to fix this:
> 481bb0432414f790066205fe77226b7d1877385d. Is it still necessary?
> Moreover maybe we need this patch for 5.1 since net-next is almost close, no?
It is not neccessery now in -next after removing concurrent access to
mt76u_buf_alloc(), can be removed.
Stanislaw
^ permalink raw reply
* Re: [PATCH] mt76: introduce q->stopped parameter
From: Stanislaw Gruszka @ 2019-02-28 11:45 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: nbd, linux-wireless, lorenzo.bianconi
In-Reply-To: <ec189b4ec030646d4dbfd0b7c41944ab383edc4e.1551301983.git.lorenzo@kernel.org>
On Wed, Feb 27, 2019 at 10:40:41PM +0100, Lorenzo Bianconi wrote:
> @@ -289,9 +290,14 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
> dev->queue_ops->tx_queue_skb(dev, q, skb, wcid, sta);
> dev->queue_ops->kick(dev, q);
>
> - if (q->queued > q->ndesc - 8)
> - ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
> + stop = q->queued > q->ndesc - 8 && !q->stopped;
> + if (stop)
> + q->stopped = true;
> +
> spin_unlock_bh(&q->lock);
> +
> + if (stop)
> + ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
I don't think taking this outside of spin_lock section is beneficial.
Actually is better to do this faster than slower to prevent enqueue
frames by mac80211 and then dropped them due to lack of space in
mt76 queue.
Stanislaw
^ permalink raw reply
* Re: [PATCH] mt76: usb: grab rx_page_lock for legacy mode in mt76u_refill_rx
From: Lorenzo Bianconi @ 2019-02-28 11:37 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, nbd, linux-wireless
In-Reply-To: <20190228112445.GA6072@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 722 bytes --]
> On Thu, Feb 28, 2019 at 12:08:45PM +0100, Lorenzo Bianconi wrote:
> > Grab rx_page_lock in mt76u_refill_rx allocating rx buffer for 'legacy'
> > mode. Remove gfp from mt76u_refill_rx signature since we need to
> > use GFP_ATOMIC
> >
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
>
> I'm doing some cleanup/optimization work which amongs other things
> will remove rx_page_lock. Please drop this patch.
Oh, ok. IIRC we need rx_page_lock to fix this:
481bb0432414f790066205fe77226b7d1877385d. Is it still necessary?
Moreover maybe we need this patch for 5.1 since net-next is almost close, no?
@Felix: are you planning to submit other patches for 5.1?
Regards,
Lorenzo
>
> Stanislaw
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH] mt76: usb: grab rx_page_lock for legacy mode in mt76u_refill_rx
From: Stanislaw Gruszka @ 2019-02-28 11:24 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: nbd, linux-wireless, lorenzo.bianconi
In-Reply-To: <ec679a39f00e9f8fabc698ef3d977ff97c841873.1551350717.git.lorenzo@kernel.org>
On Thu, Feb 28, 2019 at 12:08:45PM +0100, Lorenzo Bianconi wrote:
> Grab rx_page_lock in mt76u_refill_rx allocating rx buffer for 'legacy'
> mode. Remove gfp from mt76u_refill_rx signature since we need to
> use GFP_ATOMIC
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
I'm doing some cleanup/optimization work which amongs other things
will remove rx_page_lock. Please drop this patch.
Stanislaw
^ permalink raw reply
* [PATCH] mt76: usb: grab rx_page_lock for legacy mode in mt76u_refill_rx
From: Lorenzo Bianconi @ 2019-02-28 11:08 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, lorenzo.bianconi
In-Reply-To: <cover.1551350717.git.lorenzo@kernel.org>
Grab rx_page_lock in mt76u_refill_rx allocating rx buffer for 'legacy'
mode. Remove gfp from mt76u_refill_rx signature since we need to
use GFP_ATOMIC
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/usb.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index ae6ada370597..7ce3c7f9d5d8 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -325,15 +325,17 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
static int
mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
- struct mt76u_buf *buf, int nsgs, gfp_t gfp)
+ struct mt76u_buf *buf, int nsgs)
{
- if (dev->usb.sg_en) {
+ if (dev->usb.sg_en)
return mt76u_fill_rx_sg(dev, buf, nsgs, q->buf_size,
SKB_WITH_OVERHEAD(q->buf_size));
- } else {
- buf->buf = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
- return buf->buf ? 0 : -ENOMEM;
- }
+
+ spin_lock_bh(&q->rx_page_lock);
+ buf->buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
+ spin_unlock_bh(&q->rx_page_lock);
+
+ return buf->buf ? 0 : -ENOMEM;
}
static int
@@ -358,7 +360,7 @@ mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
sg_init_table(buf->urb->sg, MT_SG_MAX_SIZE);
}
- return mt76u_refill_rx(dev, q, buf, MT_SG_MAX_SIZE, GFP_KERNEL);
+ return mt76u_refill_rx(dev, q, buf, MT_SG_MAX_SIZE);
}
static void mt76u_buf_free(struct mt76u_buf *buf)
@@ -529,8 +531,7 @@ static void mt76u_rx_tasklet(unsigned long data)
count = mt76u_process_rx_entry(dev, buf);
if (count > 0) {
- err = mt76u_refill_rx(dev, q, buf, count,
- GFP_ATOMIC);
+ err = mt76u_refill_rx(dev, q, buf, count);
if (err < 0)
break;
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 0/4] mwifiex PCI/wake-up interrupt fixes
From: Rafael J. Wysocki @ 2019-02-28 11:03 UTC (permalink / raw)
To: Brian Norris
Cc: Rafael J. Wysocki, Ard Biesheuvel, Marc Zyngier, Ganapathi Bhat,
Jeffy Chen, Heiko Stuebner, Devicetree List, Xinming Hu,
<netdev@vger.kernel.org>, linux-pm,
<linux-wireless@vger.kernel.org>, Linux Kernel Mailing List,
Amitkumar Karwar, open list:ARM/Rockchip SoC...,
Nishant Sarmukadam, Rob Herring, Rafael J. Wysocki,
linux-arm-kernel, Enric Balletbo i Serra, Lorenzo Pieralisi,
David S. Miller, Kalle Valo, Tony Lindgren, Mark Rutland
In-Reply-To: <CA+ASDXNT9Taqfoz7R1Z926Vi1fMNNLYg5vqcZTw2m6JvXk+75w@mail.gmail.com>
On Thu, Feb 28, 2019 at 3:29 AM Brian Norris <briannorris@chromium.org> wrote:
>
> Hi Rafael,
>
> On Wed, Feb 27, 2019 at 3:04 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Wed, Feb 27, 2019 at 9:58 PM Brian Norris <briannorris@chromium.org> wrote:
> > > On Wed, Feb 27, 2019 at 11:16:12AM +0100, Ard Biesheuvel wrote:
> > > > So I'd argue that we should add an optional 'wake-gpio' DT property
> > > > instead to the generic PCI device binding, and leave the interrupt
> > > > binding and discovery alone.
> > >
> > > So I think Mark Rutland already shot that one down; it's conceptually an
> > > interrupt from the device's perspective.
>
> Perhaps I shouldn't speak for Mark, but I am basically quoting him off IRC.
>
> > Which device are you talking about? The one that signals wakeup? If
> > so, then I beg to differ.
>
> Yes, the endpoint device.
>
> > On ACPI platforms WAKE# is represented as an ACPI GPE that is signaled
> > through SCI and handled at a different level (on HW-reduced ACPI it
> > actually can be a GPIO interrupt, but it still is handled with the
> > help of AML). The driver of the device signaling wakeup need not even
> > be aware that WAKE# has been asserted.
>
> Frankly, ACPI is not relevant to how we represent WAKE# in DT, IMO.
I mentioned ACPI as an example of how WAKE# can be handled.
> Also, we're talking about the *device*, not the driver. When talking
> about Device Tree, that distinction is relevant.
I'm not sure what you mean, really.
I guess we are talking about information in DT and some of it is
consumed by the driver while some of it is consumed by some other
pieces of code.
> So while the driver need not be aware (and I agree! it only needs to
> care about enabling/disabling wake),
Not even that. Actually, PME enable is handled by the PCI bus type code.
> *something* should be aware,
Right.
> and the signal that "something" should be receiving is simply "did WAKE
> happen"?
Right. But it may not be clear which device signaled it, because
WAKE# may be shared in general.
> That sounds basically like the device is signalling an interrupt to me.
Well, consider the native PME here. In there, the device sends an
in-band message over the PCIe hierarchy to a root port and the
interrupt is signaled from there. There is a PME driver in the kernel
that requests that IRQ and handles it (for all ports that can trigger
it), but for each port it binds to a separate device (or "service" if
you will) that takes care of all PME messages coming from all devices
under that port.
At an abstract level, WAKE# is expected to be similar AFAICS except
that there is a physical signal going from the device(s) (in low-power
states) that have detected external activity (wakeup) to an entity
that can trigger an interrupt.
The original idea in the PCI PM spec regarding WAKE# seems to be to
wire up WAKE# from all devices on the bus to one input that will cause
an interrupt to trigger when one of them drives WAKE# and whatever
handled that interrupt was expected to walk the bus, find the
device(s) with PME Status set and put it (or them) into D0 (clearing
PME Status in the process). That still is a valid case to consider
IMO.
However, designers of some boards decided to provide dedicated
per-device interrupts for WAKE# and you may regard them as "wakeup
IRQs" except that the handling of each of them is the same as for the
"global WAKE#" above: if the PME Status of the device is set, put it
into D0 etc. That part belongs to the PCI bus type layer IMO.
Of course, because nothing is easy and simple, there is a third case
in which one WAKE# line (and interrupt) can be shared by a subset of
devices on the bus and there are multiple (say two or three) subsets.
> Maybe this goes back to some confusion we had elsewhere: what is the
> meaning of "interrupt" in device tree?
Maybe.
> > > We just need to figure out a good way of representing it that doesn't stomp on the existing INTx
> > > definitions.
> >
> > WAKE# is a signal that is converted into an interrupt, but that
> > interrupt may arrive at some place your driver has nothing to do with.
>
> I could agree with that, perhaps. But that's also what Device Tree is
> all about, really. We describe the relation between devices. So some
> other <foo> handles events that are triggered by <bar>, so we use a
> phandle to relate <bar> to <foo>.
So you have a PCI endpoint on the one hand and the "wakeup serivce"
device on the other.
> > It generally doesn't make sense to represent it as an interrupt for
> > the target device.
>
> What would you suggest then? I'm not clearly understanding how you
> think we should (a) describe (in DT) and (b) implement this WAKE#
> handling.
I would introduce a "wakeup service" concept (along the lines of the
native PME) and make it request all interrupts associated with WAKE#.
In the case when the WAKE# interrupts are dedicated per-device, it
would be good to avoid walking the bus and use some
"wakeup-IRQ-to-device" mapping if available.
But as I said above, IMO the *handling* of all WAKE# interrupts
belongs to the PCI bus type as it is the same for all PCI devices.
^ permalink raw reply
* Re: [RFC 12/12] mt76x02: remove set_tim
From: Felix Fietkau @ 2019-02-28 10:51 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: linux-wireless, Lorenzo Bianconi
In-Reply-To: <1551341013-24519-13-git-send-email-sgruszka@redhat.com>
On 2019-02-28 09:03, Stanislaw Gruszka wrote:
> set_tim callback is not used by mac80211 if AP_LINK_PS hw flag is set.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
There's a check in __sta_info_recalc_tim:
/* No need to do anything if the driver does all */
if (ieee80211_hw_check(&local->hw, AP_LINK_PS) && !local->ops->set_tim)
return;
At the moment we need this dummy callback to ensure that the
beacon TIM bits are set.
- Felix
^ permalink raw reply
* Re: MT76x2U crashes XHCI driver on AMD Ryzen system
From: Stanislaw Gruszka @ 2019-02-28 10:42 UTC (permalink / raw)
To: Joerg Roedel
Cc: Lorenzo Bianconi, Rosen Penev, linux-wireless, Samuel Sieb,
Alexander Duyck, iommu, linux-kernel
In-Reply-To: <20190228090411.GA24938@redhat.com>
On Thu, Feb 28, 2019 at 10:04:12AM +0100, Stanislaw Gruszka wrote:
> On Tue, Feb 26, 2019 at 12:24:08PM +0100, Stanislaw Gruszka wrote:
> > On Tue, Feb 26, 2019 at 11:44:13AM +0100, Joerg Roedel wrote:
> > > On Tue, Feb 26, 2019 at 11:34:51AM +0100, Stanislaw Gruszka wrote:
> > > > On Tue, Feb 26, 2019 at 11:05:36AM +0100, Joerg Roedel wrote:
> > > > If sg->offset > PAGE_SIZE is fine then most likely we have problem with
> > > > alignment.
> > >
> > > The map_sg implementation in the AMD IOMMU driver uses sg_phys() which
> > > handles the sg->page + sg->offset calculation fine.
> > >
> > > > Note hat issue is with dma_map_sg(), switching to dma_map_single()
> > > > by using urb->transfer_buffer instead of urb->sg make things work
> > > > on AMD IOMMU.
> > >
> > > On the other hand this points to a bug in the driver, I'll look further
> > > if I can spot something there.
> >
> > I think so too. And I have done some changes that avoid strange allocation
> > scheme and use usb synchronous messages instead of allocating buffers
> > with unaligned sizes. However things work ok on Intel IOMMU and
> > there is no documentation what are dma_map_sg() requirement versus
> > dma_map_single() which works. I think there are some unwritten
> > requirements and things can work on some platforms and fails on others
> > (different IOMMUs, no-IOMMU on some ARCHes)
>
> For the record: we have another bug report with this issue:
> https://bugzilla.kernel.org/show_bug.cgi?id=202673
>
> I provided there patch that change alignment for page_frag_alloc() and
> it did not fixed the problem. So this is not alignment issue.
> Now I think it could be page->refcount issue ...
I looked at the map_sg() in amd_iommu.c code and one line looks suspicious
to me, seems we can use not correctly initialized s->dma_address (should be 0,
but I think can be non-zero if SG was reused). The code also seems do
not do correct thing if there is more than one SG with multiple pages
on individual segments. Something like in below patch seems to be more
appropriate to me (not tested nor compiled).
Stanislaw
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 34c9aa76a7bd..9c8887250b82 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2517,6 +2517,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
prot = dir2prot(direction);
/* Map all sg entries */
+ npages = 0;
for_each_sg(sglist, s, nelems, i) {
int j, pages = iommu_num_pages(sg_phys(s), s->length, PAGE_SIZE);
@@ -2524,7 +2525,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
unsigned long bus_addr, phys_addr;
int ret;
- bus_addr = address + s->dma_address + (j << PAGE_SHIFT);
+ bus_addr = address + ((npages + j) << PAGE_SHIFT);
phys_addr = (sg_phys(s) & PAGE_MASK) + (j << PAGE_SHIFT);
ret = iommu_map_page(domain, bus_addr, phys_addr, PAGE_SIZE, prot, GFP_ATOMIC);
if (ret)
@@ -2532,6 +2533,8 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
mapped_pages += 1;
}
+
+ npages += mapped_pages;
}
/* Everything is mapped - write the right values into s->dma_address */
^ permalink raw reply related
* Re: [PATCH 03/21] wil6210: support up to 20 stations in AP mode
From: merez @ 2019-02-28 10:36 UTC (permalink / raw)
To: Kalle Valo; +Cc: Ahmad Masri, linux-wireless, wil6210
In-Reply-To: <87va14z2zg.fsf@purkki.adurom.net>
On 2019-02-28 11:17, Kalle Valo wrote:
> Maya Erez <merez@codeaurora.org> writes:
>
>> From: Ahmad Masri <amasri@codeaurora.org>
>>
>> +
>> + max_assoc_sta = min_t(uint, max_assoc_sta, fw_max_assoc_sta);
>
> You shouldn't modify max_assoc_sta like this. If you have two wil6210
> devices on the same host they will share that variable and there's a
> race condition. Sure, I guess currently they will use the same firmware
> so the values will be the same, but still this is a bug. I think you
> should have wil->max_assoc_sta to make this device specific value.
>
> I'll apply this anyway as it breaks all other patches if I remove this
> patch. But please fix this in a follow up patch.
we'll fix that.
--
Maya Erez
Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a
Linux Foundation Collaborative Project
^ 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