* [RFC v3 07/11] ath10k: various fixes for high latency devices
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
Several DMA related functions (such as the dma_map_xxx functions)
are not used with high latency devices and don't need to be invoked
in this case.
A few other execution paths are not applicable for high latency
devices and can be skipped.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/htc.c | 19 ++++++++++++-------
drivers/net/wireless/ath/ath10k/htt_rx.c | 3 ++-
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +++++++--
drivers/net/wireless/ath/ath10k/txrx.c | 5 +++--
4 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index e5c80f582ff5..75c2a3ea7ec9 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -53,7 +53,8 @@ static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
{
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
- dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
+ if (!htc->ar->is_high_latency)
+ dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
skb_pull(skb, sizeof(struct ath10k_htc_hdr));
}
@@ -137,11 +138,14 @@ int ath10k_htc_send(struct ath10k_htc *htc,
ath10k_htc_prepare_tx_skb(ep, skb);
skb_cb->eid = eid;
- skb_cb->paddr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
- ret = dma_mapping_error(dev, skb_cb->paddr);
- if (ret) {
- ret = -EIO;
- goto err_credits;
+ if (!ar->is_high_latency) {
+ skb_cb->paddr = dma_map_single(dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ ret = dma_mapping_error(dev, skb_cb->paddr);
+ if (ret) {
+ ret = -EIO;
+ goto err_credits;
+ }
}
sg_item.transfer_id = ep->eid;
@@ -157,7 +161,8 @@ int ath10k_htc_send(struct ath10k_htc *htc,
return 0;
err_unmap:
- dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
+ if (!ar->is_high_latency)
+ dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
err_credits:
if (ep->tx_credit_flow_enabled) {
spin_lock_bh(&htc->tx_lock);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 7461555ccad5..569edd0720c6 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2541,7 +2541,8 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
break;
}
case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
- ath10k_htt_rx_tx_compl_ind(htt->ar, skb);
+ if (!ar->is_high_latency)
+ ath10k_htt_rx_tx_compl_ind(htt->ar, skb);
break;
case HTT_T2H_MSG_TYPE_SEC_IND: {
struct ath10k *ar = htt->ar;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a3d69f852e38..82d01139ff92 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -409,6 +409,9 @@ int ath10k_htt_tx_start(struct ath10k_htt *htt)
if (htt->tx_mem_allocated)
return 0;
+ if (ar->is_high_latency)
+ return 0;
+
ret = ath10k_htt_tx_alloc_buf(htt);
if (ret)
goto free_idr_pending_tx;
@@ -445,7 +448,8 @@ void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
return;
ath10k_htt_tx_free_cont_txbuf(htt);
- ath10k_htt_tx_free_txq(htt);
+ if (!htt->ar->is_high_latency)
+ ath10k_htt_tx_free_txq(htt);
ath10k_htt_tx_free_cont_frag_desc(htt);
ath10k_htt_tx_free_txdone_fifo(htt);
htt->tx_mem_allocated = false;
@@ -935,7 +939,8 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
return 0;
err_unmap_msdu:
- dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+ if (!ar->is_high_latency)
+ dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_txdesc:
dev_kfree_skb_any(txdesc);
err_free_msdu_id:
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index d4986f626c35..fae143e4dcfa 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -90,11 +90,12 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
ath10k_htt_tx_dec_pending(htt);
- if (htt->num_pending_tx == 0)
+ if (!ar->is_high_latency && (htt->num_pending_tx == 0))
wake_up(&htt->empty_tx_wq);
spin_unlock_bh(&htt->tx_lock);
- dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+ if (!ar->is_high_latency)
+ dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
ath10k_report_offchan_tx(htt->ar, msdu);
--
2.14.1
^ permalink raw reply related
* [RFC v3 06/11] ath10k: htt: High latency RX support
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
Special HTT RX handling for high latency interfaces.
Since no DMA physical addresses are used in the RX ring
config message (this is not supported by the high latency
devices), no RX ring is allocated.
All RX skb's are allocated by the driver and passed directly
to mac80211 in the HTT RX indication handler.
A nice side effect of this is that no huge buffer will be
allocated with dma_alloc_coherent. On embedded systems with
limited memory resources, the allocation of the RX ring is
prone to fail.
Some tweaks made to "make it work":
Removal of protected bit in 802.11 header frame control field.
The chipset seems to do hw decryption but the frame_control
protected bit is still set.
This is necessary for mac80211 not to drop the frame.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/core.c | 27 ++++---
drivers/net/wireless/ath/ath10k/htt.h | 47 ++++++++++++
drivers/net/wireless/ath/ath10k/htt_rx.c | 119 +++++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath10k/rx_desc.h | 15 ++++
4 files changed, 195 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index c21227a74996..1880570989ae 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2083,10 +2083,12 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
ar->wmi.svc_map));
- status = ath10k_htt_rx_alloc(&ar->htt);
- if (status) {
- ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
- goto err_htt_tx_detach;
+ if (!ar->is_high_latency) {
+ status = ath10k_htt_rx_alloc(&ar->htt);
+ if (status) {
+ ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
+ goto err_htt_tx_detach;
+ }
}
status = ath10k_hif_start(ar);
@@ -2203,10 +2205,13 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
}
}
- status = ath10k_htt_rx_ring_refill(ar);
- if (status) {
- ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
- goto err_hif_stop;
+ if (!ar->is_high_latency) {
+ status = ath10k_htt_rx_ring_refill(ar);
+ if (status) {
+ ath10k_err(ar, "failed to refill htt rx ring: %d\n",
+ status);
+ goto err_hif_stop;
+ }
}
if (ar->max_num_vdevs >= 64)
@@ -2235,7 +2240,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
err_hif_stop:
ath10k_hif_stop(ar);
err_htt_rx_detach:
- ath10k_htt_rx_free(&ar->htt);
+ if (!ar->is_high_latency)
+ ath10k_htt_rx_free(&ar->htt);
err_htt_tx_detach:
ath10k_htt_tx_free(&ar->htt);
err_wmi_detach:
@@ -2280,7 +2286,8 @@ void ath10k_core_stop(struct ath10k *ar)
ath10k_hif_stop(ar);
ath10k_htt_tx_stop(&ar->htt);
- ath10k_htt_rx_free(&ar->htt);
+ if (!ar->is_high_latency)
+ ath10k_htt_rx_free(&ar->htt);
ath10k_wmi_detach(ar);
ar->is_started = false;
}
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index bac453f5753e..ac5603ef4ba5 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -646,6 +646,15 @@ struct htt_rx_indication {
struct htt_rx_indication_mpdu_range mpdu_ranges[0];
} __packed;
+/* High latency version of the RX indication */
+struct htt_rx_indication_hl {
+ struct htt_rx_indication_hdr hdr;
+ struct htt_rx_indication_ppdu ppdu;
+ struct htt_rx_indication_prefix prefix;
+ struct fw_rx_desc_hl fw_desc;
+ struct htt_rx_indication_mpdu_range mpdu_ranges[0];
+} __packed;
+
static inline struct htt_rx_indication_mpdu_range *
htt_rx_ind_get_mpdu_ranges(struct htt_rx_indication *rx_ind)
{
@@ -658,6 +667,18 @@ static inline struct htt_rx_indication_mpdu_range *
return ptr;
}
+static inline struct htt_rx_indication_mpdu_range *
+ htt_rx_ind_get_mpdu_ranges_hl(struct htt_rx_indication_hl *rx_ind)
+{
+ void *ptr = rx_ind;
+
+ ptr += sizeof(rx_ind->hdr)
+ + sizeof(rx_ind->ppdu)
+ + sizeof(rx_ind->prefix)
+ + sizeof(rx_ind->fw_desc);
+ return ptr;
+}
+
enum htt_rx_flush_mpdu_status {
HTT_RX_FLUSH_MPDU_DISCARD = 0,
HTT_RX_FLUSH_MPDU_REORDER = 1,
@@ -1530,6 +1551,7 @@ struct htt_resp {
struct htt_mgmt_tx_completion mgmt_tx_completion;
struct htt_data_tx_completion data_tx_completion;
struct htt_rx_indication rx_ind;
+ struct htt_rx_indication_hl rx_ind_hl;
struct htt_rx_fragment_indication rx_frag_ind;
struct htt_rx_peer_map peer_map;
struct htt_rx_peer_unmap peer_unmap;
@@ -1754,6 +1776,31 @@ struct htt_rx_desc {
u8 msdu_payload[0];
};
+#define HTT_RX_DESC_HL_INFO_SEQ_NUM_MASK 0x00000fff
+#define HTT_RX_DESC_HL_INFO_SEQ_NUM_LSB 0
+#define HTT_RX_DESC_HL_INFO_ENCRYPTED_MASK 0x00001000
+#define HTT_RX_DESC_HL_INFO_ENCRYPTED_LSB 12
+#define HTT_RX_DESC_HL_INFO_CHAN_INFO_PRESENT_MASK 0x00002000
+#define HTT_RX_DESC_HL_INFO_CHAN_INFO_PRESENT_LSB 13
+#define HTT_RX_DESC_HL_INFO_MCAST_BCAST_MASK 0x00008000
+#define HTT_RX_DESC_HL_INFO_MCAST_BCAST_LSB 15
+#define HTT_RX_DESC_HL_INFO_FRAGMENT_MASK 0x00010000
+#define HTT_RX_DESC_HL_INFO_FRAGMENT_LSB 16
+#define HTT_RX_DESC_HL_INFO_KEY_ID_OCT_MASK 0x01fe0000
+#define HTT_RX_DESC_HL_INFO_KEY_ID_OCT_LSB 17
+
+struct htt_rx_desc_base_hl {
+ __le32 info; /* HTT_RX_DESC_HL_INFO_ */
+};
+
+struct htt_rx_chan_info {
+ __le16 primary_chan_center_freq_mhz;
+ __le16 contig_chan1_center_freq_mhz;
+ __le16 contig_chan2_center_freq_mhz;
+ u8 phy_mode;
+ u8 reserved;
+} __packed;
+
#define HTT_RX_DESC_ALIGN 8
#define HTT_MAC_ADDR_LEN 6
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a3f5dc78353f..7461555ccad5 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1590,8 +1590,116 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
return num_msdus;
}
-static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt,
- struct htt_rx_indication *rx)
+static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
+ struct htt_rx_indication_hl *rx,
+ struct sk_buff *skb)
+{
+ struct ath10k *ar = htt->ar;
+ struct ath10k_peer *peer;
+ struct htt_rx_indication_mpdu_range *mpdu_ranges;
+ struct fw_rx_desc_hl *fw_desc;
+ struct ieee80211_hdr *hdr;
+ struct ieee80211_rx_status *rx_status;
+ u16 peer_id;
+ u8 rx_desc_len;
+ int num_mpdu_ranges;
+ size_t tot_hdr_len;
+ struct ieee80211_channel *ch;
+
+ peer_id = __le16_to_cpu(rx->hdr.peer_id);
+
+ peer = ath10k_peer_find_by_id(ar, peer_id);
+ if (!peer)
+ ath10k_warn(ar, "Got RX ind from invalid peer: %u\n", peer_id);
+
+ num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
+ HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
+ mpdu_ranges = htt_rx_ind_get_mpdu_ranges_hl(rx);
+ fw_desc = &rx->fw_desc;
+ rx_desc_len = fw_desc->len;
+
+ /* I have not yet seen any case where num_mpdu_ranges > 1.
+ * qcacld does not seem handle that case either, so we introduce the
+ * same limitiation here as well.
+ */
+ if (num_mpdu_ranges > 1)
+ ath10k_warn(ar,
+ "Unsupported number of MPDU ranges: %d, ignoring all but the first\n",
+ num_mpdu_ranges);
+
+ if (mpdu_ranges->mpdu_range_status !=
+ HTT_RX_IND_MPDU_STATUS_OK) {
+ ath10k_warn(ar, "MPDU range status: %d\n",
+ mpdu_ranges->mpdu_range_status);
+ goto err;
+ }
+
+ /* Strip off all headers before the MAC header before delivery to
+ * mac80211
+ */
+ tot_hdr_len = sizeof(struct htt_resp_hdr) + sizeof(rx->hdr) +
+ sizeof(rx->ppdu) + sizeof(rx->prefix) +
+ sizeof(rx->fw_desc) +
+ sizeof(*mpdu_ranges) * num_mpdu_ranges + rx_desc_len;
+ skb_pull(skb, tot_hdr_len);
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ rx_status = IEEE80211_SKB_RXCB(skb);
+ rx_status->chains |= BIT(0);
+ rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
+ rx->ppdu.combined_rssi;
+ rx_status->flag &= ~RX_FLAG_NO_SIGNAL_VAL;
+
+ spin_lock_bh(&ar->data_lock);
+ ch = ar->scan_channel;
+ if (!ch)
+ ch = ar->rx_channel;
+ if (!ch)
+ ch = ath10k_htt_rx_h_any_channel(ar);
+ if (!ch)
+ ch = ar->tgt_oper_chan;
+ spin_unlock_bh(&ar->data_lock);
+
+ if (ch) {
+ rx_status->band = ch->band;
+ rx_status->freq = ch->center_freq;
+ }
+ if (rx->fw_desc.flags & FW_RX_DESC_FLAGS_LAST_MSDU)
+ rx_status->flag &= ~RX_FLAG_AMSDU_MORE;
+ else
+ rx_status->flag |= RX_FLAG_AMSDU_MORE;
+
+ /* Not entirely sure about this, but all frames from the chipset has
+ * the protected flag set even though they have already been decrypted.
+ * Unmasking this flag is necessary in order for mac80211 not to drop
+ * the frame.
+ * TODO: Verify this is always the case or find out a way to check
+ * if there has been hw decryption.
+ */
+ if (ieee80211_has_protected(hdr->frame_control)) {
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ rx_status->flag |= RX_FLAG_DECRYPTED |
+ RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED;
+ }
+
+ local_bh_disable();
+ ieee80211_rx(ar->hw, skb);
+ local_bh_enable();
+
+ /* We have delivered the skb to the upper layers (mac80211) so we
+ * must not free it.
+ */
+ return false;
+err:
+ /* Tell the caller that it must free the skb since we have not
+ * consumed it
+ */
+ return true;
+}
+
+static void ath10k_htt_rx_proc_rx_ind_ll(struct ath10k_htt *htt,
+ struct htt_rx_indication *rx)
{
struct ath10k *ar = htt->ar;
struct htt_rx_indication_mpdu_range *mpdu_ranges;
@@ -2383,7 +2491,12 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
break;
}
case HTT_T2H_MSG_TYPE_RX_IND:
- ath10k_htt_rx_proc_rx_ind(htt, &resp->rx_ind);
+ if (ar->is_high_latency)
+ return ath10k_htt_rx_proc_rx_ind_hl(htt,
+ &resp->rx_ind_hl,
+ skb);
+ else
+ ath10k_htt_rx_proc_rx_ind_ll(htt, &resp->rx_ind);
break;
case HTT_T2H_MSG_TYPE_PEER_MAP: {
struct htt_peer_map_event ev = {
diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h
index c1022a1cf855..76b2fe51ddac 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -1222,4 +1222,19 @@ struct fw_rx_desc_base {
u8 info0;
} __packed;
+#define FW_RX_DESC_FLAGS_FIRST_MSDU (1 << 0)
+#define FW_RX_DESC_FLAGS_LAST_MSDU (1 << 1)
+#define FW_RX_DESC_C3_FAILED (1 << 2)
+#define FW_RX_DESC_C4_FAILED (1 << 3)
+#define FW_RX_DESC_IPV6 (1 << 4)
+#define FW_RX_DESC_TCP (1 << 5)
+#define FW_RX_DESC_UDP (1 << 6)
+
+struct fw_rx_desc_hl {
+ u8 info0;
+ u8 version;
+ u8 len;
+ u8 flags;
+} __packed;
+
#endif /* _RX_DESC_H_ */
--
2.14.1
^ permalink raw reply related
* [RFC v3 05/11] ath10k: htt: High latency TX support
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
Add HTT TX function for HL interfaces.
Intended for SDIO and USB.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/htt.h | 9 ++--
drivers/net/wireless/ath/ath10k/htt_tx.c | 91 +++++++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath10k/mac.c | 5 +-
3 files changed, 99 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 7ffa1d41f478..bac453f5753e 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1830,9 +1830,12 @@ int ath10k_htt_tx_mgmt_inc_pending(struct ath10k_htt *htt, bool is_mgmt,
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu);
-int ath10k_htt_tx(struct ath10k_htt *htt,
- enum ath10k_hw_txrx_mode txmode,
- struct sk_buff *msdu);
+int ath10k_htt_tx_ll(struct ath10k_htt *htt,
+ enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu);
+int ath10k_htt_tx_hl(struct ath10k_htt *htt,
+ enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu);
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
struct sk_buff *skb);
int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 8d85f82ad8f8..a3d69f852e38 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -946,8 +946,95 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
return res;
}
-int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
- struct sk_buff *msdu)
+#define HTT_TX_HL_NEEDED_HEADROOM \
+ (unsigned int)(sizeof(struct htt_cmd_hdr) + \
+ sizeof(struct htt_data_tx_desc) + \
+ sizeof(struct ath10k_htc_hdr))
+
+int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu)
+{
+ struct ath10k *ar = htt->ar;
+ int res, data_len;
+ struct htt_cmd_hdr *cmd_hdr;
+ struct htt_data_tx_desc *tx_desc;
+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
+ bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
+ u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth);
+ u8 flags0 = 0;
+ u16 flags1 = 0;
+
+ data_len = msdu->len;
+
+ switch (txmode) {
+ case ATH10K_HW_TXRX_RAW:
+ case ATH10K_HW_TXRX_NATIVE_WIFI:
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
+ /* fall through */
+ case ATH10K_HW_TXRX_ETHERNET:
+ flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+ break;
+ case ATH10K_HW_TXRX_MGMT:
+ flags0 |= SM(ATH10K_HW_TXRX_MGMT,
+ HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
+ break;
+ }
+
+ if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
+
+ flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
+ flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
+ if (msdu->ip_summed == CHECKSUM_PARTIAL &&
+ !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD;
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD;
+ }
+
+ /* Prepend the HTT header and TX desc struct to the data message
+ * and realloc the skb if it does not have enough headroom.
+ */
+ if (skb_headroom(msdu) < HTT_TX_HL_NEEDED_HEADROOM) {
+ struct sk_buff *tmp_skb = msdu;
+
+ ath10k_dbg(htt->ar, ATH10K_DBG_HTT,
+ "Not enough headroom in skb. Current headroom: %u, needed: %u. Reallocating...\n",
+ skb_headroom(msdu), HTT_TX_HL_NEEDED_HEADROOM);
+ msdu = skb_realloc_headroom(msdu, HTT_TX_HL_NEEDED_HEADROOM);
+ kfree_skb(tmp_skb);
+ if (!msdu) {
+ ath10k_warn(htt->ar, "htt hl tx: Unable to realloc skb!\n");
+ res = -ENOMEM;
+ goto out;
+ }
+ }
+
+ skb_push(msdu, sizeof(*cmd_hdr));
+ skb_push(msdu, sizeof(*tx_desc));
+ cmd_hdr = (struct htt_cmd_hdr *)msdu->data;
+ tx_desc = (struct htt_data_tx_desc *)(msdu->data + sizeof(*cmd_hdr));
+
+ cmd_hdr->msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
+ tx_desc->flags0 = flags0;
+ tx_desc->flags1 = __cpu_to_le16(flags1);
+ tx_desc->len = __cpu_to_le16(data_len);
+ tx_desc->id = 0;
+ tx_desc->frags_paddr = 0; /* always zero */
+ /* Initialize peer_id to INVALID_PEER because this is NOT
+ * Reinjection path
+ */
+ tx_desc->peerid = __cpu_to_le32(HTT_INVALID_PEERID);
+
+ res = ath10k_htc_send(&htt->ar->htc, htt->eid, msdu);
+
+out:
+ return res;
+}
+
+int ath10k_htt_tx_ll(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
+ struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 5683f1a5330e..aa817b8fcae4 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3585,7 +3585,10 @@ static int ath10k_mac_tx_submit(struct ath10k *ar,
switch (txpath) {
case ATH10K_MAC_TX_HTT:
- ret = ath10k_htt_tx(htt, txmode, skb);
+ if (ar->is_high_latency)
+ ret = ath10k_htt_tx_hl(htt, txmode, skb);
+ else
+ ret = ath10k_htt_tx_ll(htt, txmode, skb);
break;
case ATH10K_MAC_TX_HTT_MGMT:
ret = ath10k_htt_mgmt_tx(htt, skb);
--
2.14.1
^ permalink raw reply related
* [RFC v3 04/11] ath10k: add start_once support
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
Add possibility to configure the driver to only start target once.
This can reduce startup time of SDIO devices significantly since
loading the firmware can take a substantial amount of time.
The patch is also necessary for high latency devices in general
since it does not seem to be possible to rerun the BMI phase
(fw upload) without power-cycling the device.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/core.c | 19 +++++++++++++++----
drivers/net/wireless/ath/ath10k/core.h | 2 ++
drivers/net/wireless/ath/ath10k/hw.h | 6 ++++++
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index a4a326c89e0d..c21227a74996 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1999,6 +1999,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
int status;
u32 val;
+ if (ar->is_started && ar->hw_params.start_once)
+ return 0;
+
lockdep_assert_held(&ar->conf_mutex);
clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
@@ -2226,6 +2229,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
if (status)
goto err_hif_stop;
+ ar->is_started = true;
return 0;
err_hif_stop:
@@ -2278,6 +2282,7 @@ void ath10k_core_stop(struct ath10k *ar)
ath10k_htt_tx_stop(&ar->htt);
ath10k_htt_rx_free(&ar->htt);
ath10k_wmi_detach(ar);
+ ar->is_started = false;
}
EXPORT_SYMBOL(ath10k_core_stop);
@@ -2380,12 +2385,18 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_unlock;
}
- ath10k_debug_print_boot_info(ar);
- ath10k_core_stop(ar);
+ /* Leave target running if hw_params.start_once is set */
+ if (ar->hw_params.start_once) {
+ mutex_unlock(&ar->conf_mutex);
+ } else {
+ ath10k_debug_print_boot_info(ar);
+ ath10k_core_stop(ar);
- mutex_unlock(&ar->conf_mutex);
+ mutex_unlock(&ar->conf_mutex);
+
+ ath10k_hif_power_down(ar);
+ }
- ath10k_hif_power_down(ar);
return 0;
err_unlock:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 64dadcd6e531..0b5b1dd00e16 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -784,6 +784,8 @@ struct ath10k {
bool is_high_latency;
+ bool is_started;
+
struct {
enum ath10k_bus bus;
const struct ath10k_hif_ops *ops;
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 8cf7b963f3d4..fd0536077404 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -569,6 +569,12 @@ struct ath10k_hw_params {
bool is_high_latency;
enum ath10k_bus bus;
+
+ /* Specifies whether or not the device should be started once.
+ * If set, the device will be started once by the early fw probe
+ * and it will not be terminated afterwards.
+ */
+ bool start_once;
};
struct htt_rx_desc;
--
2.14.1
^ permalink raw reply related
* [RFC v3 03/11] ath10k: per target configurablity of various items
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
Added ability to set bus type and configure the max number of
peers in the ath10k_hw_params struct.
With this functionality it is possible to have a different
hw configuration depending on bus type for the same radio
chipset.
E.g. SDIO and USB devices using the same chipset as PCIe
devices will potentially use different board files and perhaps
other configuration parameters.
One such parameter is the max number of peers.
Instead of using a default value (suitable for PCIe devices)
derived from the WMI op version, a per target value can be
used instead.
This is needed by the QCA9377 USB device in order to prevent
the target fw to crash after HTT RX ring cfg is issued.
Apparently, the QCA9377 HL device does not seem to handle the
same amount of peers as the LL devices.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/core.c | 33 +++++++++++++++++++++++--------
drivers/net/wireless/ath/ath10k/core.h | 7 -------
drivers/net/wireless/ath/ath10k/hw.h | 22 +++++++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 4 ++--
4 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index f1924c974a12..a4a326c89e0d 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1663,9 +1663,19 @@ static int ath10k_init_hw_params(struct ath10k *ar)
for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
hw_params = &ath10k_hw_params_list[i];
- if (hw_params->id == ar->target_version &&
- hw_params->dev_id == ar->dev_id)
- break;
+ if (ar->is_high_latency) {
+ /* High latency devices will use different fw depending
+ * on if it is a USB or SDIO device.
+ */
+ if (hw_params->bus == ar->hif.bus &&
+ hw_params->id == ar->target_version &&
+ hw_params->dev_id == ar->dev_id)
+ break;
+ } else {
+ if (hw_params->id == ar->target_version &&
+ hw_params->dev_id == ar->dev_id)
+ break;
+ }
}
if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
@@ -1764,6 +1774,7 @@ static void ath10k_core_set_coverage_class_work(struct work_struct *work)
static int ath10k_core_init_firmware_features(struct ath10k *ar)
{
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
+ int max_num_peers;
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&
!test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
@@ -1843,7 +1854,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
switch (fw_file->wmi_op_version) {
case ATH10K_FW_WMI_OP_VERSION_MAIN:
- ar->max_num_peers = TARGET_NUM_PEERS;
+ max_num_peers = TARGET_NUM_PEERS;
ar->max_num_stations = TARGET_NUM_STATIONS;
ar->max_num_vdevs = TARGET_NUM_VDEVS;
ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
@@ -1855,10 +1866,10 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
case ATH10K_FW_WMI_OP_VERSION_10_2:
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
if (ath10k_peer_stats_enabled(ar)) {
- ar->max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
+ max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;
} else {
- ar->max_num_peers = TARGET_10X_NUM_PEERS;
+ max_num_peers = TARGET_10X_NUM_PEERS;
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
}
ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
@@ -1867,7 +1878,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
break;
case ATH10K_FW_WMI_OP_VERSION_TLV:
- ar->max_num_peers = TARGET_TLV_NUM_PEERS;
+ max_num_peers = TARGET_TLV_NUM_PEERS;
ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
@@ -1878,7 +1889,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
break;
case ATH10K_FW_WMI_OP_VERSION_10_4:
- ar->max_num_peers = TARGET_10_4_NUM_PEERS;
+ max_num_peers = TARGET_10_4_NUM_PEERS;
ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
@@ -1896,10 +1907,16 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
break;
case ATH10K_FW_WMI_OP_VERSION_UNSET:
case ATH10K_FW_WMI_OP_VERSION_MAX:
+ default:
WARN_ON(1);
return -EINVAL;
}
+ if (ar->hw_params.max_num_peers)
+ ar->max_num_peers = ar->hw_params.max_num_peers;
+ else
+ ar->max_num_peers = max_num_peers;
+
/* Backwards compatibility for firmwares without
* ATH10K_FW_IE_HTT_OP_VERSION.
*/
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index dc9ecf773d51..64dadcd6e531 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -88,13 +88,6 @@
struct ath10k;
-enum ath10k_bus {
- ATH10K_BUS_PCI,
- ATH10K_BUS_AHB,
- ATH10K_BUS_SDIO,
- ATH10K_BUS_USB,
-};
-
static inline const char *ath10k_bus_str(enum ath10k_bus bus)
{
switch (bus) {
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 0c089f6dd3d9..8cf7b963f3d4 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -20,6 +20,13 @@
#include "targaddrs.h"
+enum ath10k_bus {
+ ATH10K_BUS_PCI,
+ ATH10K_BUS_AHB,
+ ATH10K_BUS_SDIO,
+ ATH10K_BUS_USB,
+};
+
#define ATH10K_FW_DIR "ath10k"
#define QCA988X_2_0_DEVICE_ID (0x003c)
@@ -550,6 +557,18 @@ struct ath10k_hw_params {
*/
int vht160_mcs_rx_highest;
int vht160_mcs_tx_highest;
+
+ /* max_num_peers can be used to override the setting derived from
+ * the WMI op version. If this value is non-zero, it will always
+ * be used instead of the default value derived from the WMI op
+ * version.
+ */
+ int max_num_peers;
+
+ /* Specifies whether or not the device is a high latency device */
+ bool is_high_latency;
+
+ enum ath10k_bus bus;
};
struct htt_rx_desc;
@@ -660,6 +679,9 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
#define TARGET_TLV_NUM_WOW_PATTERNS 22
+/* Target specific defines for QCA9377 high latency firmware */
+#define TARGET_QCA9377_HL_NUM_PEERS 15
+
/* Diagnostic Window */
#define CE_DIAG_PIPE 7
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 7616c1c4bbd3..34e977049f00 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1406,7 +1406,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
- cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS);
+ cfg->num_peers = __cpu_to_le32(ar->max_num_peers);
if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) {
cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
@@ -1417,7 +1417,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
}
cfg->num_peer_keys = __cpu_to_le32(2);
- cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
+ cfg->num_tids = __cpu_to_le32(ar->max_num_peers * 2);
cfg->ast_skid_limit = __cpu_to_le32(0x10);
cfg->tx_chain_mask = __cpu_to_le32(0x7);
cfg->rx_chain_mask = __cpu_to_le32(0x7);
--
2.14.1
^ permalink raw reply related
* [RFC v3 02/11] ath10k: htt: RX ring config HL support
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
Special HTT RX ring config message used by high latency
devices.
The main difference between HL and LL is that HL devices
do not use shared memory between device and host and thus,
no host paddr's are added to the RX config message.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/htt.c | 5 +++-
drivers/net/wireless/ath/ath10k/htt.h | 1 +
drivers/net/wireless/ath/ath10k/htt_tx.c | 51 ++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index cd160b16db1e..29ed4afe52a4 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -258,7 +258,10 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
if (status)
return status;
- status = ath10k_htt_send_rx_ring_cfg_ll(htt);
+ if (ar->is_high_latency)
+ status = ath10k_htt_send_rx_ring_cfg_hl(htt);
+ else
+ status = ath10k_htt_send_rx_ring_cfg_ll(htt);
if (status) {
ath10k_warn(ar, "failed to setup rx ring: %d\n",
status);
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 6305308422c4..7ffa1d41f478 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1805,6 +1805,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt);
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
+int ath10k_htt_send_rx_ring_cfg_hl(struct ath10k_htt *htt);
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 685faac1368f..8d85f82ad8f8 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -693,6 +693,57 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
return 0;
}
+int ath10k_htt_send_rx_ring_cfg_hl(struct ath10k_htt *htt)
+{
+ struct ath10k *ar = htt->ar;
+ struct sk_buff *skb;
+ struct htt_cmd *cmd;
+ struct htt_rx_ring_setup_ring *ring;
+ const int num_rx_ring = 1;
+ u16 flags;
+ int len;
+ int ret;
+
+ /*
+ * the HW expects the buffer to be an integral number of 4-byte
+ * "words"
+ */
+ BUILD_BUG_ON(!IS_ALIGNED(HTT_RX_BUF_SIZE, 4));
+ BUILD_BUG_ON((HTT_RX_BUF_SIZE & HTT_MAX_CACHE_LINE_SIZE_MASK) != 0);
+
+ len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup.hdr)
+ + (sizeof(*ring) * num_rx_ring);
+ skb = ath10k_htc_alloc_skb(ar, len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, len);
+
+ cmd = (struct htt_cmd *)skb->data;
+ ring = &cmd->rx_setup.rings[0];
+
+ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_RX_RING_CFG;
+ cmd->rx_setup.hdr.num_rings = 1;
+
+ flags = 0;
+ flags |= HTT_RX_RING_FLAGS_MSDU_PAYLOAD;
+ flags |= HTT_RX_RING_FLAGS_UNICAST_RX;
+ flags |= HTT_RX_RING_FLAGS_MULTICAST_RX;
+
+ memset(ring, 0, sizeof(*ring));
+ ring->rx_ring_len = __cpu_to_le16(HTT_RX_RING_SIZE_MIN);
+ ring->rx_ring_bufsize = __cpu_to_le16(HTT_RX_BUF_SIZE);
+ ring->flags = __cpu_to_le16(flags);
+
+ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
+ if (ret) {
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+
+ return 0;
+}
+
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu)
--
2.14.1
^ permalink raw reply related
* [RFC v3 00/11] ath10k high latency
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
This is the third version of the high latency patches (stuff common for
usb and sdio).
One major difference between this version and the previous is that the
num_pending_tx counter has been disabled for high latency devices (last patch).
This fixes the previous issue with the halted USB RX.
I have tested these patches with a Linksys WUSB6100M and it looks
much better than the previous version.
High latency devices does not seem to send HTT_T2H_MSG_TYPE_TX_COMPL_IND's
to the host for outgoing packets, resulting in a transmit stop when the
upper limit of num_pending_tx is reached.
The qcacld driver mentions that the TX_COMPL_IND can be disabled for HL
devices in order to achieve better throughput:
/*
* HTT option TLV for specifying whether HL systems should indicate
* over-the-air tx completion for individual frames, or should instead
* send a bulk TX_CREDIT_UPDATE_IND except when the host explicitly
* requests an OTA tx completion for a particular tx frame.
* This option does not apply to LL systems, where the TX_COMPL_IND
* is mandatory.
* This option is primarily intended for HL systems in which the tx frame
* downloads over the host --> target bus are as slow as or slower than
* the transmissions over the WLAN PHY. For cases where the bus is faster
* than the WLAN PHY, the target will transmit relatively large A-MPDUs,
* and consquently will send one TX_COMPL_IND message that covers several
* tx frames. For cases where the WLAN PHY is faster than the bus,
* the target will end up transmitting very short A-MPDUs, and consequently
* sending many TX_COMPL_IND messages, which each cover a very small number
* of tx frames.
* The HL_SUPPRESS_TX_COMPL_IND TLV can be sent by the host to the target as
* a suffix to the VERSION_REQ message to request whether the host desires to
* use TX_CREDIT_UPDATE_IND rather than TX_COMPL_IND. The target can then
* send a HTT_SUPPRESS_TX_COMPL_IND TLV to the host as a suffix to the
* VERSION_CONF message to confirm whether TX_CREDIT_UPDATE_IND will be used
* rather than TX_COMPL_IND. TX_CREDIT_UPDATE_IND shall only be used if the
* host sends a HL_SUPPRESS_TX_COMPL_IND TLV requesting use of
* TX_CREDIT_UPDATE_IND, and the target sends a HL_SUPPRESS_TX_COMPLE_IND TLV
* back to the host confirming use of TX_CREDIT_UPDATE_IND.
* Lack of a HL_SUPPRESS_TX_COMPL_IND TLV from either host --> target or
* target --> host is equivalent to a HL_SUPPRESS_TX_COMPL_IND that
* explicitly specifies HL_ALLOW_TX_COMPL_IND in the value payload of the
* TLV.
*/
I am suspecting this is the default behavior in the firmware.
I have tried a simple wget test where I download a Linux kernel tar ball
from kernel.org. I got the below results:
wget --no-check-certificate \
https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.4.tar.xz
2017-09-17 16:46:20 (13.3 MB/s) - 'linux-4.11.4.tar.xz' saved
[95549228/95549228]
13.3 MB/s is a fairly OK result since I have a 100 Mbit/s internet
connection.
Changes since v2:
- Disabled htt num_pending_tx counter for HL.
- Fixed transmit flags for HL HTT TX.
- Proper marking of aggregated frames in the HL HTT RX handler.
- A few other minor fixes
Erik Stromdahl (11):
ath10k: high_latency detection
ath10k: htt: RX ring config HL support
ath10k: per target configurablity of various items
ath10k: add start_once support
ath10k: htt: High latency TX support
ath10k: htt: High latency RX support
ath10k: various fixes for high latency devices
ath10k: add QCA9377 usb hw_param item
ath10k: add QCA9377 sdio hw_param item
ath10k: wmi: disable softirq's while calling ieee80211_rx
ath10k: remove htt pending TX count for high latency
drivers/net/wireless/ath/ath10k/core.c | 128 +++++++++++++++++++-----
drivers/net/wireless/ath/ath10k/core.h | 16 +--
drivers/net/wireless/ath/ath10k/htc.c | 19 ++--
drivers/net/wireless/ath/ath10k/htt.c | 5 +-
drivers/net/wireless/ath/ath10k/htt.h | 57 ++++++++++-
drivers/net/wireless/ath/ath10k/htt_rx.c | 122 ++++++++++++++++++++++-
drivers/net/wireless/ath/ath10k/htt_tx.c | 157 +++++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath10k/hw.h | 30 ++++++
drivers/net/wireless/ath/ath10k/mac.c | 5 +-
drivers/net/wireless/ath/ath10k/rx_desc.h | 15 +++
drivers/net/wireless/ath/ath10k/txrx.c | 5 +-
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 4 +-
drivers/net/wireless/ath/ath10k/wmi.c | 3 +
13 files changed, 513 insertions(+), 53 deletions(-)
--
2.14.1
^ permalink raw reply
* [RFC v3 01/11] ath10k: high_latency detection
From: Erik Stromdahl @ 2017-09-17 19:40 UTC (permalink / raw)
To: kvalo, linux-wireless, ath10k; +Cc: Erik Stromdahl
In-Reply-To: <20170917194013.8658-1-erik.stromdahl@gmail.com>
The setup of high latency chips (USB and SDIO) is
sometimes different than for chips using low latency
interfaces.
The bus type is used to determine if the interface is
a high latency interface.
Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
---
drivers/net/wireless/ath/ath10k/core.c | 1 +
drivers/net/wireless/ath/ath10k/core.h | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index a4f635820f35..f1924c974a12 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2496,6 +2496,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
ar->hw_rev = hw_rev;
ar->hif.ops = hif_ops;
ar->hif.bus = bus;
+ ar->is_high_latency = ath10k_is_high_latency(bus);
switch (hw_rev) {
case ATH10K_HW_QCA988X:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 949ebb3e967b..dc9ecf773d51 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -789,6 +789,8 @@ struct ath10k {
bool p2p;
+ bool is_high_latency;
+
struct {
enum ath10k_bus bus;
const struct ath10k_hif_ops *ops;
@@ -1013,6 +1015,11 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
return false;
}
+static inline bool ath10k_is_high_latency(enum ath10k_bus bus)
+{
+ return ((bus == ATH10K_BUS_SDIO) || (bus == ATH10K_BUS_USB));
+}
+
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
enum ath10k_bus bus,
enum ath10k_hw_rev hw_rev,
--
2.14.1
^ permalink raw reply related
* Re: Wifi driver for RTL8191SU
From: Xose Vazquez Perez @ 2017-09-17 16:05 UTC (permalink / raw)
To: linux-wireless, Charles Chambers
Charles Chambers wrote:
> I have a USB wifi adapter based on the subject chipset. Debian Linux
> for its new release (9.x) incorporates version 4.9 of the kernel, which
> does not work with the existing driver for this USB wifi adapter. The
> driver for it (under Debian 8.x) shows as "r8712U". There's a movement
> afoot to update the driver.
>
> Any idea when an updated driver (or a wide beta restoring *some*
> functionality) could be expected?
There are three drivers:
- r8712u from staging, crappy with no future in staging or drivers/net/wireless
- r92su or rtl8192su from https://github.com/chunkeey/rtl8192su
More info about Realtek at: https://wireless.wiki.kernel.org/en/users/Drivers/rtl819x
^ permalink raw reply
* Wifi driver for RTL8191SU
From: Charles Chambers @ 2017-09-17 14:28 UTC (permalink / raw)
To: linux-wireless
I have a USB wifi adapter based on the subject chipset. Debian Linux
for its new release (9.x) incorporates version 4.9 of the kernel, which
does not work with the existing driver for this USB wifi adapter. The
driver for it (under Debian 8.x) shows as "r8712U". There's a movement
afoot to update the driver.
Any idea when an updated driver (or a wide beta restoring *some*
functionality) could be expected?
^ permalink raw reply
* [PATCH V3 3/3] brcmfmac: Add check for short event packets
From: Kevin Cernekee @ 2017-09-17 4:08 UTC (permalink / raw)
To: arend.vanspriel, franky.lin
Cc: brcm80211-dev-list.pdl, linux-wireless, mnissler
In-Reply-To: <20170917040824.22237-1-cernekee@chromium.org>
The length of the data in the received skb is currently passed into
brcmf_fweh_process_event() as packet_len, but this value is not checked.
event_packet should be followed by DATALEN bytes of additional event
data. Ensure that the received packet actually contains at least
DATALEN bytes of additional data, to avoid copying uninitialized memory
into event->data.
Suggested-by: Mattias Nissler <mnissler@chromium.org>
Signed-off-by: Kevin Cernekee <cernekee@chromium.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
V2->V3: Change '<' to '>' and retest
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
index 27e661fa356f..e7eaa57d11d9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
@@ -424,7 +424,8 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
if (code != BRCMF_E_IF && !fweh->evt_handler[code])
return;
- if (datalen > BRCMF_DCMD_MAXLEN)
+ if (datalen > BRCMF_DCMD_MAXLEN ||
+ datalen + sizeof(*event_packet) > packet_len)
return;
if (in_interrupt())
--
2.14.1.690.gbb1197296e-goog
^ permalink raw reply related
* [PATCH V3 2/3] brcmfmac: Delete redundant length check
From: Kevin Cernekee @ 2017-09-17 4:08 UTC (permalink / raw)
To: arend.vanspriel, franky.lin
Cc: brcm80211-dev-list.pdl, linux-wireless, mnissler
In-Reply-To: <20170917040824.22237-1-cernekee@chromium.org>
brcmf_fweh_process_event() sets event->datalen to the
endian-swapped value of event_packet->msg.datalen, which is the
same as emsg.datalen. This length is already validated in
brcmf_fweh_process_event(), so there is no need to check it
again upon dequeuing the event.
Suggested-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kevin Cernekee <cernekee@chromium.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 5 -----
1 file changed, 5 deletions(-)
V2->V3: No change
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
index 4eb1e1ce9ace..27e661fa356f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
@@ -257,11 +257,6 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
min_t(u32, emsg.datalen, 64),
"event payload, len=%d\n", emsg.datalen);
- if (emsg.datalen > event->datalen) {
- brcmf_err("event invalid length header=%d, msg=%d\n",
- event->datalen, emsg.datalen);
- goto event_free;
- }
/* special handling of interface event */
if (event->code == BRCMF_E_IF) {
--
2.14.1.690.gbb1197296e-goog
^ permalink raw reply related
* [PATCH V3 1/3] brcmfmac: Avoid possible out-of-bounds read
From: Kevin Cernekee @ 2017-09-17 4:08 UTC (permalink / raw)
To: arend.vanspriel, franky.lin
Cc: brcm80211-dev-list.pdl, linux-wireless, mnissler
In brcmf_p2p_notify_rx_mgmt_p2p_probereq(), chanspec is assigned before
the length of rxframe is validated. This could lead to uninitialized
data being accessed (but not printed). Since we already have a
perfectly good endian-swapped copy of rxframe->chanspec in ch.chspec,
and ch.chspec is not modified by decchspec(), avoid the extra
assignment and use ch.chspec in the debug print.
Suggested-by: Mattias Nissler <mnissler@chromium.org>
Signed-off-by: Kevin Cernekee <cernekee@chromium.org>
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
V2->V3: No change
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 2ce675ab40ef..1c450c0727cb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -1853,7 +1853,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
struct afx_hdl *afx_hdl = &p2p->afx_hdl;
struct brcmf_cfg80211_vif *vif = ifp->vif;
struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
- u16 chanspec = be16_to_cpu(rxframe->chanspec);
struct brcmu_chan ch;
u8 *mgmt_frame;
u32 mgmt_frame_len;
@@ -1906,7 +1905,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0);
brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
- mgmt_frame_len, e->datalen, chanspec, freq);
+ mgmt_frame_len, e->datalen, ch.chspec, freq);
return 0;
}
--
2.14.1.690.gbb1197296e-goog
^ permalink raw reply related
* Re: iwlwifi firmware load broken in current -git
From: Jens Axboe @ 2017-09-16 18:53 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Luca Coelho, Linus Torvalds, Srinath Mannam, Bjorn Helgaas,
Johannes Berg, Grumbach, Emmanuel, linuxwifi,
linux-wireless@vger.kernel.org, linux-pci@vger.kernel.org
In-Reply-To: <20170916030311.GB16731@bhelgaas-glaptop.roam.corp.google.com>
On 09/15/2017 09:03 PM, Bjorn Helgaas wrote:
> On Fri, Sep 15, 2017 at 01:55:57PM -0600, Jens Axboe wrote:
>> On 09/15/2017 01:51 PM, Luca Coelho wrote:
>>> On Fri, 2017-09-15 at 13:48 -0600, Jens Axboe wrote:
>>>> On 09/15/2017 01:38 PM, Linus Torvalds wrote:
>>>>> On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>>>>
>>>>>>> In any case, your patch introduces a regression on systems. Please get
>>>>>>> it reverted now, and then you can come up with a new approach to fix the
>>>>>>> double enable of the upstream bridge.
>>>>>>
>>>>>> Who's sending in the revert? I can certainly do it if no one else does,
>>>>>> but it needs to be done.
>>>>>>
>>>>>> I'm not seeing any patches coming out of Srinath to fix up the
>>>>>> situation, so we should revert the broken patch until a better solution
>>>>>> exists.
>>>>>
>>>>> Hmm. I don't have the history here (apparently it never made lkml, for
>>>>> example), so I don't even know which commit you're talking about.
>>>>>
>>>>> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
>>>>> Avoid race while enabling upstream bridges"), is that correct?
>>>>
>>>> Yes, Luca says that Bjorn already sent in the revert request, I just
>>>> didn't see it since I wasn't CC'ed on it. So looks like we're all
>>>> good, provided that makes it into -rc1. 40f11adc7cd9 is the broken
>>>> commit.
>>>
>>> Strange... AFAICT you *were* CCed on it. And so was everyone else in
>>> the original thread (+LKML)...
>>
>> Hmm, never showed up here. Very odd!
>
> Sorry, I think this is probably because I'm an idiot and sent it from
> an @google.com account and it got rejected because the DMARC check
> failed.
Ah, good to know why it didn't show up. Thanks.
--
Jens Axboe
^ permalink raw reply
* Re: RTL8192EE PCIe Wireless Network Adapter crashed with linux-4.13
From: Larry Finger @ 2017-09-16 17:26 UTC (permalink / raw)
To: Zwindl
Cc: linux-wireless@vger.kernel.org, chaoming_li@realsil.com.cn,
kvalo@codeaurora.org, pkshih@realtek.com, johannes.berg@intel.com,
gregkh@linuxfoundation.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <2_UKRQjXR9_CXy_99R7fqRbs4VDG0hfFCMvvf4ll2BQV5C_zNiPTnHHNtoYstAGy_UF9X85pl4siU7fnXefmqbhlErxR6FqZQfIf0tADKNg=@protonmail.com>
On 09/16/2017 06:27 AM, Zwindl wrote:
> Hi, I've done the test, and the weird thing happened. The kernel buit with this
> config file https://ptpb.pw/HF1g which is from
> https://aur.archlinux.org/packages/linux-git/ can run properly, the wifi can
> connect, despite which version it is, but, with this config file
> https://ptpb.pw/7GuV which comes from the archlinux's official package build
> repo(linux-package
> <https://git.archlinux.org/svntogit/packages.git/tree/trunk?h=packages/linux>),
> all the version begin with 4.13 was failed to connect wifi.
> So, I think the issue is not caused by the kernel code, is caused by some
> options in the config file, but I can't fully understand the meaning of these
> options so that I can't determine which option caused that issue, what should I
> do now, maybe report this bug to archlinux's maintainer?
> By the way, maybe I'll lost internet connection tomorrow, it's time to back to
> university, but I'm happy to help to push the debug progress.
Yes, you need to report this to archlinux's bugzilla or maintainer, whichever is
appropriate. I have seen a configuration error cause some feature to be silently
missing, but leading to a WARN is rare.
I looked at your two configurations, but did not see a definitive difference.
Larry
^ permalink raw reply
* [PATCH] mwifiex: make const arrays static to shink object code size
From: Colin King @ 2017-09-16 15:34 UTC (permalink / raw)
To: Amitkumar Karwar, Nishant Sarmukadam, Ganapathi Bhat, Xinming Hu,
Kalle Valo, linux-wireless, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Don't populate const arrays on the stack, instead make them static
Makes the object code smaller by nearly 300 bytes:
Before:
text data bss dec hex filename
69260 16149 576 85985 14fe1 cfg80211.o
After:
text data bss dec hex filename
68385 16725 576 85686 14eb6 cfg80211.o
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 32c5074da84c..c45b86fcfd8d 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -142,7 +142,7 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
- const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
@@ -454,7 +454,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
struct mwifiex_wep_key *wep_key;
- const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
@@ -3250,8 +3250,8 @@ static int mwifiex_set_wowlan_mef_entry(struct mwifiex_private *priv,
int i, filt_num = 0, ret = 0;
bool first_pat = true;
u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
- const u8 ipv4_mc_mac[] = {0x33, 0x33};
- const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
+ static const u8 ipv4_mc_mac[] = {0x33, 0x33};
+ static const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
mef_entry->mode = MEF_MODE_HOST_SLEEP;
mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
@@ -3544,9 +3544,9 @@ static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
static int mwifiex_get_coalesce_pkt_type(u8 *byte_seq)
{
- const u8 ipv4_mc_mac[] = {0x33, 0x33};
- const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
- const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff};
+ static const u8 ipv4_mc_mac[] = {0x33, 0x33};
+ static const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
+ static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff};
if ((byte_seq[0] & 0x01) &&
(byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 1))
--
2.14.1
^ permalink raw reply related
* Re: iwlwifi firmware load broken in current -git
From: Bjorn Helgaas @ 2017-09-16 3:03 UTC (permalink / raw)
To: Jens Axboe
Cc: Luca Coelho, Linus Torvalds, Srinath Mannam, Bjorn Helgaas,
Johannes Berg, Grumbach, Emmanuel, linuxwifi,
linux-wireless@vger.kernel.org, linux-pci@vger.kernel.org
In-Reply-To: <79b26165-7baf-c6ee-7552-1ccccb3b7192@kernel.dk>
On Fri, Sep 15, 2017 at 01:55:57PM -0600, Jens Axboe wrote:
> On 09/15/2017 01:51 PM, Luca Coelho wrote:
> > On Fri, 2017-09-15 at 13:48 -0600, Jens Axboe wrote:
> >> On 09/15/2017 01:38 PM, Linus Torvalds wrote:
> >>> On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
> >>>>>
> >>>>> In any case, your patch introduces a regression on systems. Please get
> >>>>> it reverted now, and then you can come up with a new approach to fix the
> >>>>> double enable of the upstream bridge.
> >>>>
> >>>> Who's sending in the revert? I can certainly do it if no one else does,
> >>>> but it needs to be done.
> >>>>
> >>>> I'm not seeing any patches coming out of Srinath to fix up the
> >>>> situation, so we should revert the broken patch until a better solution
> >>>> exists.
> >>>
> >>> Hmm. I don't have the history here (apparently it never made lkml, for
> >>> example), so I don't even know which commit you're talking about.
> >>>
> >>> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
> >>> Avoid race while enabling upstream bridges"), is that correct?
> >>
> >> Yes, Luca says that Bjorn already sent in the revert request, I just
> >> didn't see it since I wasn't CC'ed on it. So looks like we're all
> >> good, provided that makes it into -rc1. 40f11adc7cd9 is the broken
> >> commit.
> >
> > Strange... AFAICT you *were* CCed on it. And so was everyone else in
> > the original thread (+LKML)...
>
> Hmm, never showed up here. Very odd!
Sorry, I think this is probably because I'm an idiot and sent it from
an @google.com account and it got rejected because the DMARC check
failed.
Bjorn
^ permalink raw reply
* [GIT PULL] PCI fixes for v4.14
From: Bjorn Helgaas @ 2017-09-16 2:59 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-pci, linux-kernel, linuxwifi, linux-wireless,
Srinath Mannam, Jens Axboe, Luca Coelho, Johannes Berg,
Emmanuel Grumbach, Konstantin Khlebnikov
PCI fix:
- revert an attempt to fix a race while enabling upstream bridges because
it broke iwlwifi firmware loading
The following changes since commit 711aab1dbb324d321e3d84368a435a78908c7bce:
vfs: constify path argument to kernel_read_file_from_path (2017-09-14 20:18:45 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git tags/pci-v4.14-fixes-1
for you to fetch changes up to 0f50a49e3008597abed0fff052d487f77db89093:
Revert "PCI: Avoid race while enabling upstream bridges" (2017-09-15 01:33:51 -0500)
----------------------------------------------------------------
pci-v4.14-fixes-1
----------------------------------------------------------------
Bjorn Helgaas (1):
Revert "PCI: Avoid race while enabling upstream bridges"
drivers/pci/pci.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Jens Axboe @ 2017-09-15 19:57 UTC (permalink / raw)
To: Linus Torvalds, Luca Coelho
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel,
linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <CA+55aFxUUTJo=EPHqHB8qEm_72mrM6P0pzbLqL0PQ8s2SM+ZiQ@mail.gmail.com>
On 09/15/2017 01:51 PM, Linus Torvalds wrote:
> On Fri, Sep 15, 2017 at 12:43 PM, Luca Coelho <luca@coelho.fi> wrote:
>> On Fri, 2017-09-15 at 12:38 -0700, Linus Torvalds wrote:
>>>
>>> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
>>> Avoid race while enabling upstream bridges"), is that correct?
>>
>> Yes, that's the one. And Bjorn already sent a revert:
>>
>> https://lkml.org/lkml/2017/9/15/46
>
> Well, he may have sent a revert to lkml, but not to me. I'm assuming
> it's in his tree and I'll get a pull request. Hopefully soon, so that
> it makes rc.
That was my hope, and why I emailed again today on the topic.
> Jens, you were actually cc'd on that revert according to the email
> headers, so check your spam-box.
Yeah, Luca says so too. Which is making me a little worried on behalf
of my email, since it's not sitting in spam.
--
Jens Axboe
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Jens Axboe @ 2017-09-15 19:55 UTC (permalink / raw)
To: Luca Coelho, Linus Torvalds
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel,
linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <1505505062.32032.1.camel@coelho.fi>
On 09/15/2017 01:51 PM, Luca Coelho wrote:
> On Fri, 2017-09-15 at 13:48 -0600, Jens Axboe wrote:
>> On 09/15/2017 01:38 PM, Linus Torvalds wrote:
>>> On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>>
>>>>> In any case, your patch introduces a regression on systems. Please get
>>>>> it reverted now, and then you can come up with a new approach to fix the
>>>>> double enable of the upstream bridge.
>>>>
>>>> Who's sending in the revert? I can certainly do it if no one else does,
>>>> but it needs to be done.
>>>>
>>>> I'm not seeing any patches coming out of Srinath to fix up the
>>>> situation, so we should revert the broken patch until a better solution
>>>> exists.
>>>
>>> Hmm. I don't have the history here (apparently it never made lkml, for
>>> example), so I don't even know which commit you're talking about.
>>>
>>> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
>>> Avoid race while enabling upstream bridges"), is that correct?
>>
>> Yes, Luca says that Bjorn already sent in the revert request, I just
>> didn't see it since I wasn't CC'ed on it. So looks like we're all
>> good, provided that makes it into -rc1. 40f11adc7cd9 is the broken
>> commit.
>
> Strange... AFAICT you *were* CCed on it. And so was everyone else in
> the original thread (+LKML)...
Hmm, never showed up here. Very odd!
--
Jens Axboe
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Luca Coelho @ 2017-09-15 19:51 UTC (permalink / raw)
To: Jens Axboe, Linus Torvalds
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel,
linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <fe610637-ecfd-8096-8c44-4f78b4a5811a@kernel.dk>
On Fri, 2017-09-15 at 13:48 -0600, Jens Axboe wrote:
> On 09/15/2017 01:38 PM, Linus Torvalds wrote:
> > On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
> > > >
> > > > In any case, your patch introduces a regression on systems. Please get
> > > > it reverted now, and then you can come up with a new approach to fix the
> > > > double enable of the upstream bridge.
> > >
> > > Who's sending in the revert? I can certainly do it if no one else does,
> > > but it needs to be done.
> > >
> > > I'm not seeing any patches coming out of Srinath to fix up the
> > > situation, so we should revert the broken patch until a better solution
> > > exists.
> >
> > Hmm. I don't have the history here (apparently it never made lkml, for
> > example), so I don't even know which commit you're talking about.
> >
> > From some of the context it looks like commit 40f11adc7cd9 ("PCI:
> > Avoid race while enabling upstream bridges"), is that correct?
>
> Yes, Luca says that Bjorn already sent in the revert request, I just
> didn't see it since I wasn't CC'ed on it. So looks like we're all
> good, provided that makes it into -rc1. 40f11adc7cd9 is the broken
> commit.
Strange... AFAICT you *were* CCed on it. And so was everyone else in
the original thread (+LKML)...
--
Luca.
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Linus Torvalds @ 2017-09-15 19:51 UTC (permalink / raw)
To: Luca Coelho
Cc: Jens Axboe, Srinath Mannam, Bjorn Helgaas, Johannes Berg,
Grumbach, Emmanuel, linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <1505504598.5400.296.camel@coelho.fi>
On Fri, Sep 15, 2017 at 12:43 PM, Luca Coelho <luca@coelho.fi> wrote:
> On Fri, 2017-09-15 at 12:38 -0700, Linus Torvalds wrote:
>>
>> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
>> Avoid race while enabling upstream bridges"), is that correct?
>
> Yes, that's the one. And Bjorn already sent a revert:
>
> https://lkml.org/lkml/2017/9/15/46
Well, he may have sent a revert to lkml, but not to me. I'm assuming
it's in his tree and I'll get a pull request. Hopefully soon, so that
it makes rc.
Jens, you were actually cc'd on that revert according to the email
headers, so check your spam-box.
Linus
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Jens Axboe @ 2017-09-15 19:48 UTC (permalink / raw)
To: Linus Torvalds
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Luca Coelho,
Grumbach, Emmanuel, linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <CA+55aFzjz2c=q4Uatso1Lp6HAUOAyGdbZLWorFW56MiapoF5Sg@mail.gmail.com>
On 09/15/2017 01:38 PM, Linus Torvalds wrote:
> On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>
>>> In any case, your patch introduces a regression on systems. Please get
>>> it reverted now, and then you can come up with a new approach to fix the
>>> double enable of the upstream bridge.
>>
>> Who's sending in the revert? I can certainly do it if no one else does,
>> but it needs to be done.
>>
>> I'm not seeing any patches coming out of Srinath to fix up the
>> situation, so we should revert the broken patch until a better solution
>> exists.
>
> Hmm. I don't have the history here (apparently it never made lkml, for
> example), so I don't even know which commit you're talking about.
>
> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
> Avoid race while enabling upstream bridges"), is that correct?
Yes, Luca says that Bjorn already sent in the revert request, I just
didn't see it since I wasn't CC'ed on it. So looks like we're all
good, provided that makes it into -rc1. 40f11adc7cd9 is the broken
commit.
--
Jens Axboe
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Jens Axboe @ 2017-09-15 19:46 UTC (permalink / raw)
To: Luca Coelho, Srinath Mannam
Cc: Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel, linuxwifi,
linux-wireless@vger.kernel.org, linux-pci@vger.kernel.org,
Linus Torvalds
In-Reply-To: <1505504195.5400.295.camel@coelho.fi>
On 09/15/2017 01:36 PM, Luca Coelho wrote:
> On Fri, 2017-09-15 at 13:32 -0600, Jens Axboe wrote:
>> On 09/14/2017 02:36 PM, Jens Axboe wrote:
>>> On 09/14/2017 02:04 PM, Srinath Mannam wrote:
>>>> Hi Jens Axboe,
>>>>
>>>>
>>>> On Thu, Sep 14, 2017 at 11:14 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>> On 09/14/2017 11:35 AM, Jens Axboe wrote:
>>>>>> On 09/14/2017 11:28 AM, Srinath Mannam wrote:
>>>>>>> Hi Bjorn,
>>>>>>>
>>>>>>> On Thu, Sep 14, 2017 at 10:52 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>>>>>
>>>>>>>> On 09/14/2017 11:11 AM, Bjorn Helgaas wrote:
>>>>>>>>> [+cc linux-pci]
>>>>>>>>>
>>>>>>>>> On Thu, Sep 14, 2017 at 12:00 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>>>>>>> On 09/12/2017 02:04 PM, Johannes Berg wrote:
>>>>>>>>>>> On Tue, 2017-09-12 at 13:43 -0600, Jens Axboe wrote:
>>>>>>>>>>>
>>>>>>>>>>>> CC'ing the guilty part and Bjorn. I'm assuming it's the
>>>>>>>>>>>> pci_is_enabled() check, since the rest of the patch shouldn't have
>>>>>>>>>>>> functional changes.
>>>>>>>>>>>
>>>>>>>>>>> and pci_enable_bridge() already checks if it's already enabled, but
>>>>>>>>>>> still enables mastering in that case if it isn't:
>>>>>>>>>>>
>>>>>>>>>>> static void pci_enable_bridge(struct pci_dev *dev)
>>>>>>>>>>> {
>>>>>>>>>>> [...]
>>>>>>>>>>> if (pci_is_enabled(dev)) {
>>>>>>>>>>> if (!dev->is_busmaster)
>>>>>>>>>>> pci_set_master(dev);
>>>>>>>>>>> return;
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> so I guess due to the new check we end up with mastering disabled, and
>>>>>>>>>>> thus the firmware can't load since that's a DMA thing?
>>>>>>>>>>
>>>>>>>>>> Bjorn/Srinath, any input here? This is a regression that prevents wifi
>>>>>>>>>> from working on a pretty standard laptop. It'd suck to have this be in
>>>>>>>>>> -rc1. Seems like the trivial fix would be:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
>>>>>>>>>> index b0002daa50f3..ffbe11dbdd61 100644
>>>>>>>>>> --- a/drivers/pci/pci.c
>>>>>>>>>> +++ b/drivers/pci/pci.c
>>>>>>>>>> @@ -1394,7 +1394,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
>>>>>>>>>> return 0; /* already enabled */
>>>>>>>>>>
>>>>>>>>>> bridge = pci_upstream_bridge(dev);
>>>>>>>>>> - if (bridge && !pci_is_enabled(bridge))
>>>>>>>>>> + if (bridge)
>>>>>>>
>>>>>>> With this change and keeping "mutex_lock(&pci_bridge_mutex);" in
>>>>>>> pci_enable_bridge functoin will causes a nexted lock.
>>>>>>
>>>>>> Took a look, and looks like you are right. That code looks like a mess,
>>>>>> fwiw.
>>>>>>
>>>>>> I'd strongly suggest that the bad commit is reverted until a proper
>>>>>> solution is found, since the simple one-liner could potentially
>>>>>> introduce a deadlock with your patch applied.
>>>>>
>>>>> BTW, your patch looks pretty bad too, introducing a random mutex
>>>>> deep on code that can be recursive. Why isn't this check in
>>>>> pci_enable_device_flags() enough to prevent double-enable of
>>>>> an upstream bridge?
>>>>>
>>>>> if (atomic_inc_return(&dev->enable_cnt) > 1)
>>>>> return 0; /* already enabled */
>>>>>
>>>>
>>>> This check only to verify device enable not for the bus master check.
>>>> But device enable function calls the bridge enable if it has the bridge.
>>>> Bridge enable function enables both device and bus master.
>>>>
>>>> Here the issue might be because, bridge of endpoint has already set
>>>> device enable without set bus master in some other context. which is
>>>> wrong.
>>>> because all bridges should enable with bridge_enable function only.
>>>> So we see the problem In this context, because "if (bridge &&
>>>> !pci_is_enabled(bridge))" check stops bridge enable which intern stops
>>>> bus master.
>>>> pci_enable_bridge function always makes sure that both device and bus
>>>> master are enabled in any case. If pci_enable_bridge function is not
>>>> called means, that bridge is already has device enable flag set. which
>>>> is not from pci_enable_bridge function.
>>>
>>> In any case, your patch introduces a regression on systems. Please get
>>> it reverted now, and then you can come up with a new approach to fix the
>>> double enable of the upstream bridge.
>>
>> Who's sending in the revert? I can certainly do it if no one else does,
>> but it needs to be done.
>>
>> I'm not seeing any patches coming out of Srinath to fix up the
>> situation, so we should revert the broken patch until a better solution
>> exists.
>
> Bjorn already sent it:
>
> https://lkml.org/lkml/2017/9/15/46
Huh ok, I would have thought the various folks in this discussion would
have been CC'ed on that. But good to know, that takes care of my
concern.
--
Jens Axboe
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Luca Coelho @ 2017-09-15 19:43 UTC (permalink / raw)
To: Linus Torvalds, Jens Axboe
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel,
linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <CA+55aFzjz2c=q4Uatso1Lp6HAUOAyGdbZLWorFW56MiapoF5Sg@mail.gmail.com>
On Fri, 2017-09-15 at 12:38 -0700, Linus Torvalds wrote:
> On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
> > >
> > > In any case, your patch introduces a regression on systems. Please get
> > > it reverted now, and then you can come up with a new approach to fix the
> > > double enable of the upstream bridge.
> >
> > Who's sending in the revert? I can certainly do it if no one else does,
> > but it needs to be done.
> >
> > I'm not seeing any patches coming out of Srinath to fix up the
> > situation, so we should revert the broken patch until a better solution
> > exists.
>
> Hmm. I don't have the history here (apparently it never made lkml, for
> example), so I don't even know which commit you're talking about.
>
> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
> Avoid race while enabling upstream bridges"), is that correct?
Yes, that's the one. And Bjorn already sent a revert:
https://lkml.org/lkml/2017/9/15/46
--
Luca.
^ 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