* Re: [PATCH] ath10k: hide kernel addresses from logs using %pK format specifier
From: Joe Perches @ 2016-08-05 17:57 UTC (permalink / raw)
To: c_mkenna, ath10k, Andrew Morton; +Cc: linux-wireless, mkenna, Kees Cook, LKML
In-Reply-To: <1470318711-28986-1-git-send-email-c_mkenna@qti.qualcomm.com>
On Thu, 2016-08-04 at 19:21 +0530, c_mkenna@qti.qualcomm.com wrote:
> From: Maharaja Kennadyrajan <c_mkenna@qti.qualcomm.com>
>
> With the %pK format specifier we hide the kernel addresses
> with the help of kptr_restrict sysctl.
> In this patch, %p is changed to %pK in the driver code.
>
> The sysctl is documented in Documentation/sysctl/kernel.txt.
Maybe %p should follow %pK and only show kernel .text addresses
by default and any other address as 0 unless the sysctl is set.
^ permalink raw reply
* [PATCH v4] ath9k: Switch to using mac80211 intermediate software queues.
From: Toke Høiland-Jørgensen @ 2016-08-05 16:03 UTC (permalink / raw)
To: linux-wireless, make-wifi-fast, ath9k-devel
Cc: Toke Høiland-Jørgensen, Tim Shepard, Felix Fietkau
In-Reply-To: <20160706193417.13080-1-toke@toke.dk>
This switches ath9k over to using the mac80211 intermediate software
queueing mechanism for data packets. It removes the queueing inside the
driver, except for the retry queue, and instead pulls from mac80211 when
a packet is needed. The retry queue is used to store a packet that was
pulled but can't be sent immediately.
The old code path in ath_tx_start that would queue packets has been
removed completely, as has the qlen limit tunables (since there's no
longer a queue in the driver to limit).
Based on Tim's original patch set, but reworked quite thoroughly.
Cc: Tim Shepard <shep@alum.mit.edu>
Cc: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
---
Changes since v3 (most due to Felix; thanks!):
- Correctly notify mac80211 when there are packets in the retry queue
on powersave start/stop.
- Get rid of ath_tx_aggr_resume().
- Some readability changes and additional WARN_ON/BUG_ON in
appropriate places.
drivers/net/wireless/ath/ath9k/ath9k.h | 27 ++-
drivers/net/wireless/ath/ath9k/channel.c | 2 -
drivers/net/wireless/ath/ath9k/debug.c | 14 +-
drivers/net/wireless/ath/ath9k/debug.h | 2 -
drivers/net/wireless/ath/ath9k/debug_sta.c | 4 +-
drivers/net/wireless/ath/ath9k/init.c | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 9 +-
drivers/net/wireless/ath/ath9k/xmit.c | 332 +++++++++++------------------
8 files changed, 157 insertions(+), 235 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 5294595..7e0a976 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -91,7 +91,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_RXBUF 512
#define ATH_TXBUF 512
#define ATH_TXBUF_RESERVE 5
-#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
#define ATH_TXMAXTRY 13
#define ATH_MAX_SW_RETRIES 30
@@ -145,7 +144,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define BAW_WITHIN(_start, _bawsz, _seqno) \
((((_seqno) - (_start)) & 4095) < (_bawsz))
-#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
+#define ATH_AN_2_TID(_an, _tidno) ath_node_to_tid(_an, _tidno)
#define IS_HT_RATE(rate) (rate & 0x80)
#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
@@ -164,7 +163,6 @@ struct ath_txq {
spinlock_t axq_lock;
u32 axq_depth;
u32 axq_ampdu_depth;
- bool stopped;
bool axq_tx_inprogress;
struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
u8 txq_headidx;
@@ -232,7 +230,6 @@ struct ath_buf {
struct ath_atx_tid {
struct list_head list;
- struct sk_buff_head buf_q;
struct sk_buff_head retry_q;
struct ath_node *an;
struct ath_txq *txq;
@@ -247,13 +244,13 @@ struct ath_atx_tid {
s8 bar_index;
bool active;
bool clear_ps_filter;
+ bool has_queued;
};
struct ath_node {
struct ath_softc *sc;
struct ieee80211_sta *sta; /* station struct we're part of */
struct ieee80211_vif *vif; /* interface with which we're associated */
- struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
u16 maxampdu;
u8 mpdudensity;
@@ -276,7 +273,6 @@ struct ath_tx_control {
struct ath_node *an;
struct ieee80211_sta *sta;
u8 paprd;
- bool force_channel;
};
@@ -293,7 +289,6 @@ struct ath_tx {
struct ath_descdma txdma;
struct ath_txq *txq_map[IEEE80211_NUM_ACS];
struct ath_txq *uapsdq;
- u32 txq_max_pending[IEEE80211_NUM_ACS];
u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32];
};
@@ -421,6 +416,22 @@ struct ath_offchannel {
int duration;
};
+static inline struct ath_atx_tid *
+ath_node_to_tid(struct ath_node *an, u8 tidno)
+{
+ struct ieee80211_sta *sta = an->sta;
+ struct ieee80211_vif *vif = an->vif;
+ struct ieee80211_txq *txq;
+
+ BUG_ON(!vif);
+ if (sta)
+ txq = sta->txq[tidno % ARRAY_SIZE(sta->txq)];
+ else
+ txq = vif->txq;
+
+ return (struct ath_atx_tid *) txq->drv_priv;
+}
+
#define case_rtn_string(val) case val: return #val
#define ath_for_each_chanctx(_sc, _ctx) \
@@ -575,7 +586,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc);
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
@@ -585,6 +595,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
u16 tids, int nframes,
enum ieee80211_frame_release_type reason,
bool more_data);
+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue);
/********/
/* VIFs */
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 319cb5f..a5ce016 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1007,7 +1007,6 @@ static void ath_scan_send_probe(struct ath_softc *sc,
goto error;
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
- txctl.force_channel = true;
if (ath_tx_start(sc->hw, skb, &txctl))
goto error;
@@ -1130,7 +1129,6 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
memset(&txctl, 0, sizeof(txctl));
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
txctl.sta = sta;
- txctl.force_channel = true;
if (ath_tx_start(sc->hw, skb, &txctl)) {
ieee80211_free_txskb(sc->hw, skb);
return false;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 6de64cf..48b181d 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -600,7 +600,6 @@ static int read_file_xmit(struct seq_file *file, void *data)
PR("MPDUs XRetried: ", xretries);
PR("Aggregates: ", a_aggr);
PR("AMPDUs Queued HW:", a_queued_hw);
- PR("AMPDUs Queued SW:", a_queued_sw);
PR("AMPDUs Completed:", a_completed);
PR("AMPDUs Retried: ", a_retries);
PR("AMPDUs XRetried: ", a_xretries);
@@ -629,8 +628,7 @@ static void print_queue(struct ath_softc *sc, struct ath_txq *txq,
seq_printf(file, "%s: %d ", "qnum", txq->axq_qnum);
seq_printf(file, "%s: %2d ", "qdepth", txq->axq_depth);
seq_printf(file, "%s: %2d ", "ampdu-depth", txq->axq_ampdu_depth);
- seq_printf(file, "%s: %3d ", "pending", txq->pending_frames);
- seq_printf(file, "%s: %d\n", "stopped", txq->stopped);
+ seq_printf(file, "%s: %3d\n", "pending", txq->pending_frames);
ath_txq_unlock(sc, txq);
}
@@ -1190,7 +1188,6 @@ static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
AMKSTR(d_tx_mpdu_xretries),
AMKSTR(d_tx_aggregates),
AMKSTR(d_tx_ampdus_queued_hw),
- AMKSTR(d_tx_ampdus_queued_sw),
AMKSTR(d_tx_ampdus_completed),
AMKSTR(d_tx_ampdu_retries),
AMKSTR(d_tx_ampdu_xretries),
@@ -1270,7 +1267,6 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
AWDATA(xretries);
AWDATA(a_aggr);
AWDATA(a_queued_hw);
- AWDATA(a_queued_sw);
AWDATA(a_completed);
AWDATA(a_retries);
AWDATA(a_xretries);
@@ -1328,14 +1324,6 @@ int ath9k_init_debug(struct ath_hw *ah)
read_file_xmit);
debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy,
read_file_queues);
- debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
- &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
- debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
- &sc->tx.txq_max_pending[IEEE80211_AC_BE]);
- debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
- &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
- debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
- &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy,
read_file_misc);
debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index cd68c5f..a078cdd 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -147,7 +147,6 @@ struct ath_interrupt_stats {
* @completed: Total MPDUs (non-aggr) completed
* @a_aggr: Total no. of aggregates queued
* @a_queued_hw: Total AMPDUs queued to hardware
- * @a_queued_sw: Total AMPDUs queued to software queues
* @a_completed: Total AMPDUs completed
* @a_retries: No. of AMPDUs retried (SW)
* @a_xretries: No. of AMPDUs dropped due to xretries
@@ -174,7 +173,6 @@ struct ath_tx_stats {
u32 xretries;
u32 a_aggr;
u32 a_queued_hw;
- u32 a_queued_sw;
u32 a_completed;
u32 a_retries;
u32 a_xretries;
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c
index c2ca57a..2e8371a 100644
--- a/drivers/net/wireless/ath/ath9k/debug_sta.c
+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
@@ -52,8 +52,8 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf,
"TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
"BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
- for (tidno = 0, tid = &an->tid[tidno];
- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
+ tid = ath_node_to_tid(an, tidno);
txq = tid->txq;
ath_txq_lock(sc, txq);
if (tid->active) {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 1c226d6..752cacb 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -354,7 +354,6 @@ static int ath9k_init_queues(struct ath_softc *sc)
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
sc->tx.txq_map[i]->mac80211_qnum = i;
- sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH;
}
return 0;
}
@@ -867,6 +866,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->max_rate_tries = 10;
hw->sta_data_size = sizeof(struct ath_node);
hw->vif_data_size = sizeof(struct ath_vif);
+ hw->txq_data_size = sizeof(struct ath_atx_tid);
hw->extra_tx_headroom = 4;
hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3aed43a..eb48f91 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1874,9 +1874,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
bool flush = false;
int ret = 0;
struct ieee80211_sta *sta = params->sta;
+ struct ath_node *an = (struct ath_node *)sta->drv_priv;
enum ieee80211_ampdu_mlme_action action = params->action;
u16 tid = params->tid;
u16 *ssn = ¶ms->ssn;
+ struct ath_atx_tid *atid;
mutex_lock(&sc->mutex);
@@ -1909,9 +1911,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
ath9k_ps_restore(sc);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
- ath9k_ps_wakeup(sc);
- ath_tx_aggr_resume(sc, sta, tid);
- ath9k_ps_restore(sc);
+ atid = ath_node_to_tid(an, tid);
+ atid->baw_size = IEEE80211_MIN_AMPDU_BUF <<
+ sta->ht_cap.ampdu_factor;
break;
default:
ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
@@ -2673,4 +2675,5 @@ struct ieee80211_ops ath9k_ops = {
.sw_scan_start = ath9k_sw_scan_start,
.sw_scan_complete = ath9k_sw_scan_complete,
.get_txpower = ath9k_get_txpower,
+ .wake_tx_queue = ath9k_wake_tx_queue,
};
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index fe795fc..8103954 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -65,6 +65,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
struct sk_buff *skb);
+static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath_tx_control *txctl);
enum {
MCS_HT20,
@@ -118,6 +120,26 @@ static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
list_add_tail(&tid->list, list);
}
+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_atx_tid *tid = (struct ath_atx_tid *) queue->drv_priv;
+ struct ath_txq *txq = tid->txq;
+
+ ath_dbg(common, QUEUE, "Waking TX queue: %pM (%d)\n",
+ queue->sta ? queue->sta->addr : queue->vif->addr,
+ tid->tidno);
+
+ ath_txq_lock(sc, txq);
+
+ tid->has_queued = true;
+ ath_tx_queue_tid(sc, txq, tid);
+ ath_txq_schedule(sc, txq);
+
+ ath_txq_unlock(sc, txq);
+}
+
static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -145,7 +167,6 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
struct sk_buff *skb)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath_frame_info *fi = get_frame_info(skb);
int q = fi->txq;
@@ -156,14 +177,6 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
if (WARN_ON(--txq->pending_frames < 0))
txq->pending_frames = 0;
- if (txq->stopped &&
- txq->pending_frames < sc->tx.txq_max_pending[q]) {
- if (ath9k_is_chanctx_enabled())
- ieee80211_wake_queue(sc->hw, info->hw_queue);
- else
- ieee80211_wake_queue(sc->hw, q);
- txq->stopped = false;
- }
}
static struct ath_atx_tid *
@@ -173,9 +186,48 @@ ath_get_skb_tid(struct ath_softc *sc, struct ath_node *an, struct sk_buff *skb)
return ATH_AN_2_TID(an, tidno);
}
+static struct sk_buff *
+ath_tid_pull(struct ath_atx_tid *tid)
+{
+ struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv);
+ struct ath_softc *sc = tid->an->sc;
+ struct ieee80211_hw *hw = sc->hw;
+ struct ath_tx_control txctl = {
+ .txq = tid->txq,
+ .sta = tid->an->sta,
+ };
+ struct sk_buff *skb;
+ struct ath_frame_info *fi;
+ int q;
+
+ if (!tid->has_queued)
+ return NULL;
+
+ skb = ieee80211_tx_dequeue(hw, txq);
+ if (!skb) {
+ tid->has_queued = false;
+ return NULL;
+ }
+
+ if (ath_tx_prepare(hw, skb, &txctl)) {
+ ieee80211_free_txskb(hw, skb);
+ return NULL;
+ }
+
+ q = skb_get_queue_mapping(skb);
+ if (tid->txq == sc->tx.txq_map[q]) {
+ fi = get_frame_info(skb);
+ fi->txq = q;
+ ++tid->txq->pending_frames;
+ }
+
+ return skb;
+ }
+
+
static bool ath_tid_has_buffered(struct ath_atx_tid *tid)
{
- return !skb_queue_empty(&tid->buf_q) || !skb_queue_empty(&tid->retry_q);
+ return !skb_queue_empty(&tid->retry_q) || tid->has_queued;
}
static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid)
@@ -184,46 +236,11 @@ static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid)
skb = __skb_dequeue(&tid->retry_q);
if (!skb)
- skb = __skb_dequeue(&tid->buf_q);
+ skb = ath_tid_pull(tid);
return skb;
}
-/*
- * ath_tx_tid_change_state:
- * - clears a-mpdu flag of previous session
- * - force sequence number allocation to fix next BlockAck Window
- */
-static void
-ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
- struct ath_txq *txq = tid->txq;
- struct ieee80211_tx_info *tx_info;
- struct sk_buff *skb, *tskb;
- struct ath_buf *bf;
- struct ath_frame_info *fi;
-
- skb_queue_walk_safe(&tid->buf_q, skb, tskb) {
- fi = get_frame_info(skb);
- bf = fi->bf;
-
- tx_info = IEEE80211_SKB_CB(skb);
- tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-
- if (bf)
- continue;
-
- bf = ath_tx_setup_buffer(sc, txq, tid, skb);
- if (!bf) {
- __skb_unlink(skb, &tid->buf_q);
- ath_txq_skb_done(sc, txq, skb);
- ieee80211_free_txskb(sc->hw, skb);
- continue;
- }
- }
-
-}
-
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = tid->txq;
@@ -858,20 +875,16 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf *
ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid, struct sk_buff_head **q)
+ struct ath_atx_tid *tid)
{
struct ieee80211_tx_info *tx_info;
struct ath_frame_info *fi;
- struct sk_buff *skb;
+ struct sk_buff *skb, *first_skb = NULL;
struct ath_buf *bf;
u16 seqno;
while (1) {
- *q = &tid->retry_q;
- if (skb_queue_empty(*q))
- *q = &tid->buf_q;
-
- skb = skb_peek(*q);
+ skb = ath_tid_dequeue(tid);
if (!skb)
break;
@@ -883,7 +896,6 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
bf->bf_state.stale = false;
if (!bf) {
- __skb_unlink(skb, *q);
ath_txq_skb_done(sc, txq, skb);
ieee80211_free_txskb(sc->hw, skb);
continue;
@@ -912,8 +924,20 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
seqno = bf->bf_state.seqno;
/* do not step over block-ack window */
- if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno))
+ if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
+ __skb_queue_tail(&tid->retry_q, skb);
+
+ /* If there are other skbs in the retry q, they are
+ * probably within the BAW, so loop immediately to get
+ * one of them. Otherwise the queue can get stuck. */
+ if (!skb_queue_is_first(&tid->retry_q, skb) &&
+ !WARN_ON(skb == first_skb)) {
+ if(!first_skb) /* infinite loop prevention */
+ first_skb = skb;
+ continue;
+ }
break;
+ }
if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
struct ath_tx_status ts = {};
@@ -921,7 +945,6 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
INIT_LIST_HEAD(&bf_head);
list_add(&bf->list, &bf_head);
- __skb_unlink(skb, *q);
ath_tx_update_baw(sc, tid, seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
continue;
@@ -933,11 +956,10 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
return NULL;
}
-static bool
+static int
ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid, struct list_head *bf_q,
- struct ath_buf *bf_first, struct sk_buff_head *tid_q,
- int *aggr_len)
+ struct ath_buf *bf_first)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
struct ath_buf *bf = bf_first, *bf_prev = NULL;
@@ -947,12 +969,13 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ieee80211_tx_info *tx_info;
struct ath_frame_info *fi;
struct sk_buff *skb;
- bool closed = false;
+
bf = bf_first;
aggr_limit = ath_lookup_rate(sc, bf, tid);
- do {
+ while (bf)
+ {
skb = bf->bf_mpdu;
fi = get_frame_info(skb);
@@ -961,12 +984,12 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
if (nframes) {
if (aggr_limit < al + bpad + al_delta ||
ath_lookup_legacy(bf) || nframes >= h_baw)
- break;
+ goto stop;
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
if ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) ||
!(tx_info->flags & IEEE80211_TX_CTL_AMPDU))
- break;
+ goto stop;
}
/* add padding for previous frame to aggregation length */
@@ -988,20 +1011,18 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_addto_baw(sc, tid, bf);
bf->bf_state.ndelim = ndelim;
- __skb_unlink(skb, tid_q);
list_add_tail(&bf->list, bf_q);
if (bf_prev)
bf_prev->bf_next = bf;
bf_prev = bf;
- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
- if (!bf) {
- closed = true;
- break;
- }
- } while (ath_tid_has_buffered(tid));
-
+ bf = ath_tx_get_tid_subframe(sc, txq, tid);
+ }
+ goto finish;
+stop:
+ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
+finish:
bf = bf_first;
bf->bf_lastbf = bf_prev;
@@ -1012,9 +1033,7 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
TX_STAT_INC(txq->axq_qnum, a_aggr);
}
- *aggr_len = al;
-
- return closed;
+ return al;
#undef PADBYTES
}
@@ -1391,18 +1410,15 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
static void
ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid, struct list_head *bf_q,
- struct ath_buf *bf_first, struct sk_buff_head *tid_q)
+ struct ath_buf *bf_first)
{
struct ath_buf *bf = bf_first, *bf_prev = NULL;
- struct sk_buff *skb;
int nframes = 0;
do {
struct ieee80211_tx_info *tx_info;
- skb = bf->bf_mpdu;
nframes++;
- __skb_unlink(skb, tid_q);
list_add_tail(&bf->list, bf_q);
if (bf_prev)
bf_prev->bf_next = bf;
@@ -1411,13 +1427,15 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
if (nframes >= 2)
break;
- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
+ bf = ath_tx_get_tid_subframe(sc, txq, tid);
if (!bf)
break;
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
break;
+ }
ath_set_rates(tid->an->vif, tid->an->sta, bf);
} while (1);
@@ -1428,34 +1446,33 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
{
struct ath_buf *bf;
struct ieee80211_tx_info *tx_info;
- struct sk_buff_head *tid_q;
struct list_head bf_q;
int aggr_len = 0;
- bool aggr, last = true;
+ bool aggr;
if (!ath_tid_has_buffered(tid))
return false;
INIT_LIST_HEAD(&bf_q);
- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
+ bf = ath_tx_get_tid_subframe(sc, txq, tid);
if (!bf)
return false;
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
- (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
+ (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
+ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
*stop = true;
return false;
}
ath_set_rates(tid->an->vif, tid->an->sta, bf);
if (aggr)
- last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
- tid_q, &aggr_len);
+ aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf);
else
- ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q);
+ ath_tx_form_burst(sc, txq, tid, &bf_q, bf);
if (list_empty(&bf_q))
return false;
@@ -1498,9 +1515,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
an->mpdudensity = density;
}
- /* force sequence number allocation for pending frames */
- ath_tx_tid_change_state(sc, txtid);
-
txtid->active = true;
*ssn = txtid->seq_start = txtid->seq_next;
txtid->bar_index = -1;
@@ -1525,7 +1539,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
ath_txq_lock(sc, txq);
txtid->active = false;
ath_tx_flush_tid(sc, txtid);
- ath_tx_tid_change_state(sc, txtid);
ath_txq_unlock_complete(sc, txq);
}
@@ -1535,14 +1548,12 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_atx_tid *tid;
struct ath_txq *txq;
- bool buffered;
int tidno;
ath_dbg(common, XMIT, "%s called\n", __func__);
- for (tidno = 0, tid = &an->tid[tidno];
- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-
+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
+ tid = ath_node_to_tid(an, tidno);
txq = tid->txq;
ath_txq_lock(sc, txq);
@@ -1552,13 +1563,12 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
continue;
}
- buffered = ath_tid_has_buffered(tid);
+ if (!skb_queue_empty(&tid->retry_q))
+ ieee80211_sta_set_buffered(sta, tid->tidno, true);
list_del_init(&tid->list);
ath_txq_unlock(sc, txq);
-
- ieee80211_sta_set_buffered(sta, tidno, buffered);
}
}
@@ -1571,49 +1581,20 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
ath_dbg(common, XMIT, "%s called\n", __func__);
- for (tidno = 0, tid = &an->tid[tidno];
- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-
+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
+ tid = ath_node_to_tid(an, tidno);
txq = tid->txq;
ath_txq_lock(sc, txq);
tid->clear_ps_filter = true;
-
if (ath_tid_has_buffered(tid)) {
ath_tx_queue_tid(sc, txq, tid);
ath_txq_schedule(sc, txq);
}
-
ath_txq_unlock_complete(sc, txq);
}
}
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tidno)
-{
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_atx_tid *tid;
- struct ath_node *an;
- struct ath_txq *txq;
-
- ath_dbg(common, XMIT, "%s called\n", __func__);
-
- an = (struct ath_node *)sta->drv_priv;
- tid = ATH_AN_2_TID(an, tidno);
- txq = tid->txq;
-
- ath_txq_lock(sc, txq);
-
- tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-
- if (ath_tid_has_buffered(tid)) {
- ath_tx_queue_tid(sc, txq, tid);
- ath_txq_schedule(sc, txq);
- }
-
- ath_txq_unlock_complete(sc, txq);
-}
-
void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
u16 tids, int nframes,
@@ -1626,7 +1607,6 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info;
struct list_head bf_q;
struct ath_buf *bf_tail = NULL, *bf;
- struct sk_buff_head *tid_q;
int sent = 0;
int i;
@@ -1641,11 +1621,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
ath_txq_lock(sc, tid->txq);
while (nframes > 0) {
- bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
+ bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid);
if (!bf)
break;
- __skb_unlink(bf->bf_mpdu, tid_q);
list_add_tail(&bf->list, &bf_q);
ath_set_rates(tid->an->vif, tid->an->sta, bf);
if (bf_isampdu(bf)) {
@@ -1660,7 +1639,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
sent++;
TX_STAT_INC(txq->axq_qnum, a_queued_hw);
- if (an->sta && !ath_tid_has_buffered(tid))
+ if (an->sta && skb_queue_empty(&tid->retry_q))
ieee80211_sta_set_buffered(an->sta, i, false);
}
ath_txq_unlock_complete(sc, tid->txq);
@@ -1887,13 +1866,7 @@ bool ath_drain_all_txq(struct ath_softc *sc)
if (!ATH_TXQ_SETUP(sc, i))
continue;
- /*
- * The caller will resume queues with ieee80211_wake_queues.
- * Mark the queue as not stopped to prevent ath_tx_complete
- * from waking the queue too early.
- */
txq = &sc->tx.txq[i];
- txq->stopped = false;
ath_draintxq(sc, txq);
}
@@ -2293,15 +2266,12 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_txq *txq = txctl->txq;
struct ath_atx_tid *tid = NULL;
struct ath_buf *bf;
- bool queue, skip_uapsd = false, ps_resp;
+ bool ps_resp;
int q, ret;
if (vif)
avp = (void *)vif->drv_priv;
- if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
- txctl->force_channel = true;
-
ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE);
ret = ath_tx_prepare(hw, skb, txctl);
@@ -2316,63 +2286,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
q = skb_get_queue_mapping(skb);
+ if (ps_resp)
+ txq = sc->tx.uapsdq;
+
ath_txq_lock(sc, txq);
if (txq == sc->tx.txq_map[q]) {
fi->txq = q;
- if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
- !txq->stopped) {
- if (ath9k_is_chanctx_enabled())
- ieee80211_stop_queue(sc->hw, info->hw_queue);
- else
- ieee80211_stop_queue(sc->hw, q);
- txq->stopped = true;
- }
- }
-
- queue = ieee80211_is_data_present(hdr->frame_control);
-
- /* If chanctx, queue all null frames while NOA could be there */
- if (ath9k_is_chanctx_enabled() &&
- ieee80211_is_nullfunc(hdr->frame_control) &&
- !txctl->force_channel)
- queue = true;
-
- /* Force queueing of all frames that belong to a virtual interface on
- * a different channel context, to ensure that they are sent on the
- * correct channel.
- */
- if (((avp && avp->chanctx != sc->cur_chan) ||
- sc->cur_chan->stopped) && !txctl->force_channel) {
- if (!txctl->an)
- txctl->an = &avp->mcast_node;
- queue = true;
- skip_uapsd = true;
- }
-
- if (txctl->an && queue)
- tid = ath_get_skb_tid(sc, txctl->an, skb);
-
- if (!skip_uapsd && ps_resp) {
- ath_txq_unlock(sc, txq);
- txq = sc->tx.uapsdq;
- ath_txq_lock(sc, txq);
- } else if (txctl->an && queue) {
- WARN_ON(tid->txq != txctl->txq);
-
- if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
- tid->clear_ps_filter = true;
-
- /*
- * Add this frame to software queue for scheduling later
- * for aggregation.
- */
- TX_STAT_INC(txq->axq_qnum, a_queued_sw);
- __skb_queue_tail(&tid->buf_q, skb);
- if (!txctl->an->sleeping)
- ath_tx_queue_tid(sc, txq, tid);
-
- ath_txq_schedule(sc, txq);
- goto out;
+ ++txq->pending_frames;
}
bf = ath_tx_setup_buffer(sc, txq, tid, skb);
@@ -2856,9 +2776,8 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_tid *tid;
int tidno, acno;
- for (tidno = 0, tid = &an->tid[tidno];
- tidno < IEEE80211_NUM_TIDS;
- tidno++, tid++) {
+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
+ tid = ath_node_to_tid(an, tidno);
tid->an = an;
tid->tidno = tidno;
tid->seq_start = tid->seq_next = 0;
@@ -2866,11 +2785,14 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
tid->baw_head = tid->baw_tail = 0;
tid->active = false;
tid->clear_ps_filter = true;
- __skb_queue_head_init(&tid->buf_q);
+ tid->has_queued = false;
__skb_queue_head_init(&tid->retry_q);
INIT_LIST_HEAD(&tid->list);
acno = TID_TO_WME_AC(tidno);
tid->txq = sc->tx.txq_map[acno];
+
+ if (!an->sta)
+ break; /* just one multicast ath_atx_tid */
}
}
@@ -2880,9 +2802,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
struct ath_txq *txq;
int tidno;
- for (tidno = 0, tid = &an->tid[tidno];
- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-
+ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
+ tid = ath_node_to_tid(an, tidno);
txq = tid->txq;
ath_txq_lock(sc, txq);
@@ -2894,6 +2815,9 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
tid->active = false;
ath_txq_unlock(sc, txq);
+
+ if (!an->sta)
+ break; /* just one multicast ath_atx_tid */
}
}
--
2.9.2
^ permalink raw reply related
* [RFC][PATCH] RANDOM: ATH9K RNG delivers zero bits of entropy
From: Stephan Mueller @ 2016-08-05 15:08 UTC (permalink / raw)
To: Ted Tso, herbert
Cc: linux-kernel, linux-crypto, ath9k-devel, linux-wireless,
ath9k-devel, Kalle Valo
Hi Ted, Herbert,
I sent a question to the ATH9K RNG some time ago to the developers.
See https://www.mail-archive.com/linux-crypto@vger.kernel.org/msg19115.html
I have not yet received a word and I think this issue should be resolved.
Thanks
Stephan
---8<---
The ATH9K driver implements an RNG which is completely bypassing the
standard Linux HW generator logic.
The RNG may or may not deliver entropy. Considering the conservative
approach in treating entropy with respect to non-auditable sources, this
patch changes the delivered entropy value to zero. The RNG still feeds
data into the input_pool but it is assumed to have no entropy.
When the ATH9K RNG changes to use the HW RNG framework, it may re-enable
the entropy estimation considering that a user can change that value at
boot and runtime.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
drivers/net/wireless/ath/ath9k/rng.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c
index d38e50f..d63dc48 100644
--- a/drivers/net/wireless/ath/ath9k/rng.c
+++ b/drivers/net/wireless/ath/ath9k/rng.c
@@ -92,8 +92,7 @@ static int ath9k_rng_kthread(void *data)
fail_stats = 0;
/* sleep until entropy bits under write_wakeup_threshold */
- add_hwgenerator_randomness((void *)rng_buf, bytes_read,
- ATH9K_RNG_ENTROPY(bytes_read));
+ add_hwgenerator_randomness((void *)rng_buf, bytes_read, 0);
}
kfree(rng_buf);
--
2.7.4
^ permalink raw reply related
* RE: [v5.1] ucc_fast: Fix to avoid IS_ERR_VALUE abuses and dead code on 64bit systems.
From: David Laight @ 2016-08-05 13:04 UTC (permalink / raw)
To: 'Arvind Yadav', zajec5@gmail.com, leoli@freescale.com
Cc: qiang.zhao@freescale.com, arnd@arndb.de, viresh.kumar@linaro.org,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
scottwood@freescale.com, akpm@linux-foundation.org,
linuxppc-dev@lists.ozlabs.org, linux@roeck-us.net
In-Reply-To: <1470329563-5464-1-git-send-email-arvind.yadav.cs@gmail.com>
From: Arvind Yadav
> Sent: 04 August 2016 17:53
> IS_ERR_VALUE() assumes that parameter is an unsigned long.
> It can not be used to check if 'unsigned int' is passed insted.
> Which tends to reflect an error.
> In 64bit architectures sizeof (int) == 4 && sizeof (long) == 8.
> IS_ERR_VALUE(x) is ((x) >= (unsigned long)-4095).
> IS_ERR_VALUE() of 'unsigned int' is always false because the 32bit
> value is zero extended to 64 bits.
>
> Now Problem In UCC fast protocols -: drivers/soc/fsl/qe/ucc_fast.c
>
> /* Allocate memory for Tx Virtual Fifo */
> uccf->ucc_fast_tx_virtual_fifo_base_offset =
> qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
> if (IS_ERR_VALUE(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
> printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n",
> __func__);
> uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
> ucc_fast_free(uccf);
> return -ENOMEM;
> }
>
> /* Allocate memory for Rx Virtual Fifo */
> uccf->ucc_fast_rx_virtual_fifo_base_offset =
> qe_muram_alloc(uf_info->urfs +
> UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
> UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
> if (IS_ERR_VALUE(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
> printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n",
> __func__);
> uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
> ucc_fast_free(uccf);
> return -ENOMEM;
> }
>
> qe_muram_alloc (a.k.a. cpm_muram_alloc) returns unsigned long.
> Return value store in a u32 (ucc_fast_tx_virtual_fifo_base_offset
> and ucc_fast_rx_virtual_fifo_base_offset).If qe_muram_alloc will
> return any error, Then IS_ERR_VALUE will always return 0. it'll not
> call ucc_fast_free for any failure. Inside 'if code' will be a dead
> code on 64bit.
> This patch is to avoid this problem on 64bit machine.
That is really far too wordy for a commit message.
My suspicion is that qe_muram_alloc() always returns a value that is much
less than 2^32 - even though the return type is 'long'.
Looking further all this code is a bag of worms.
The 'fail' return value from qe_muram_alloc() (aka cpm_muram_alloc()) is
never returned to an outer level.
It might be better to return a constant CPM_MURAL_ALLOC_FAIL (say 0x7fffffff)
and have the callers check that (via a #define).
That is only the start of the problems...
It looks very likely that cpm_muram_free() will be called in tidy up paths
when cpm_muram_alloc() either failed, or hasn't been called.
Since 0 is a valid return value, and there is no check for -ENOMEM it is
all an 'accident waiting to happen'.
>From my quick scan (grep -B2 -A6) I'm not at all sure most of the error paths
at best leak memory.
David
^ permalink raw reply
* pull-request: mac80211 2016-08-05
From: Johannes Berg @ 2016-08-05 12:32 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-wireless
Hi Dave,
Here's a first set of fixes for the current cycle. See the tag message
for more information.
I'll probably have a follow-up fix for the real problem in mac80211
that caused the crash later, but for now we have this patch and it
makes sense and fixes the crash, even if the behaviour isn't quite
right (afaict.)
Let me know if there's any problem.
Thanks,
johannes
The following changes since commit ecd5a32318280133e8ae93f10ea693293a04a786:
phy/micrel: Change phy_id_mask for KSZ8721 (2016-07-31 20:37:12 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2016-08-05
for you to fetch changes up to 2439ca0402091badb24415e1b073ba12b34ba423:
mac80211: Add ieee80211_hw pointer to get_expected_throughput (2016-08-05 14:23:25 +0200)
----------------------------------------------------------------
First set of fixes for the current cycle:
* fix 80+80 bandwidth warning
* fix powersave with mac80211 TXQ implementation
* use correct way to free SKBs from multicast buffering
* mesh: fix operation ordering to work with all drivers
* mesh: end service period even when peer goes away
* mesh: correct HT opmode validity checks
* pass hw pointer from mac80211 to driver in TPT method,
fixing a bug (in a bit the wrong way, but that's what
we have right now)
----------------------------------------------------------------
Colin Ian King (1):
cfg80211: fix missing break in NL8211_CHAN_WIDTH_80P80 case
Felix Fietkau (2):
mac80211: fix check for buffered powersave frames with txq
mac80211: fix purging multicast PS buffer queue
Maital Hahn (1):
mac80211: mesh: flush stations before beacons are stopped
Masashi Honma (2):
mac80211: End the MPSP even if EOSP frame was not acked
nl80211: correct checks for NL80211_MESHCONF_HT_OPMODE value
Maxim Altshul (1):
mac80211: Add ieee80211_hw pointer to get_expected_throughput
drivers/net/wireless/ti/wlcore/main.c | 5 +++--
include/net/mac80211.h | 3 ++-
net/mac80211/cfg.c | 2 +-
net/mac80211/driver-ops.h | 2 +-
net/mac80211/mesh.c | 10 ++++++----
net/mac80211/rx.c | 2 +-
net/mac80211/status.c | 14 +++++++-------
net/mac80211/tx.c | 6 +++---
net/wireless/chan.c | 1 +
net/wireless/nl80211.c | 34 +++++++++++++++++++++++++++++++---
10 files changed, 56 insertions(+), 23 deletions(-)
^ permalink raw reply
* Re: [PATCH v3] nl80211: Receive correct value for NL80211_MESHCONF_HT_OPMODE command
From: Johannes Berg @ 2016-08-05 12:15 UTC (permalink / raw)
To: Masashi Honma; +Cc: linux-wireless, j, me
In-Reply-To: <1470186464-4224-1-git-send-email-masashi.honma@gmail.com>
On Wed, 2016-08-03 at 10:07 +0900, Masashi Honma wrote:
> Previously, NL80211_MESHCONF_HT_OPMODE rejected correct flag
> combination, ex) IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED |
> IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT.
>
> This was caused by simple comparison with value 16. This causes
> setting
> non-existent flag (like 0x08) and invalid flag combinations. So this
> commit implements some checks based on IEEE 802.11 2012 8.4.2.59 HT
> Operation element.
>
Applied, with some minor changes.
johannes
^ permalink raw reply
* Re: Buggy rhashtable walking
From: Ben Greear @ 2016-08-05 11:46 UTC (permalink / raw)
To: Johannes Berg, Herbert Xu
Cc: David S. Miller, netdev, linux-wireless, Thomas Graf, tom
In-Reply-To: <1470394233.2977.37.camel@sipsolutions.net>
On 08/05/2016 03:50 AM, Johannes Berg wrote:
> On Fri, 2016-08-05 at 18:48 +0800, Herbert Xu wrote:
>> On Fri, Aug 05, 2016 at 08:16:53AM +0200, Johannes Berg wrote:
>>>
>>> Hm. Would you rather allocate a separate head entry for the
>>> hashtable,
>>> or chain the entries?
>>
>> My plan is to build support for this directly into rhashtable.
>> So I'm adding a struct rhlist_head that would be used in place
>> of rhash_head for these cases and it'll carry an extra pointer
>> for the list of identical entries.
>>
>> I will then add an additional layer of insert/lookup interfaces
>> for rhlist_head.
Herbert, thank you for fixing this!
It would not be fun to have to revert to the old way of hashing
stations in mac80211...
I'll be happy to test the patches when you have them ready.
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: Buggy rhashtable walking
From: Johannes Berg @ 2016-08-05 10:50 UTC (permalink / raw)
To: Herbert Xu; +Cc: David S. Miller, netdev, linux-wireless, Thomas Graf, tom
In-Reply-To: <20160805104858.GA9297@gondor.apana.org.au>
On Fri, 2016-08-05 at 18:48 +0800, Herbert Xu wrote:
> On Fri, Aug 05, 2016 at 08:16:53AM +0200, Johannes Berg wrote:
> >
> > Hm. Would you rather allocate a separate head entry for the
> > hashtable,
> > or chain the entries?
>
> My plan is to build support for this directly into rhashtable.
> So I'm adding a struct rhlist_head that would be used in place
> of rhash_head for these cases and it'll carry an extra pointer
> for the list of identical entries.
>
> I will then add an additional layer of insert/lookup interfaces
> for rhlist_head.
Oh, ok.
> So bottom-line is that if you have no identical entries that you
> only incur an extra 8 bytes per-object.
>
Right.
Thanks!
johannes
^ permalink raw reply
* Re: Buggy rhashtable walking
From: Herbert Xu @ 2016-08-05 10:48 UTC (permalink / raw)
To: Johannes Berg; +Cc: David S. Miller, netdev, linux-wireless, Thomas Graf, tom
In-Reply-To: <1470377813.2977.14.camel@sipsolutions.net>
On Fri, Aug 05, 2016 at 08:16:53AM +0200, Johannes Berg wrote:
>
> Hm. Would you rather allocate a separate head entry for the hashtable,
> or chain the entries?
My plan is to build support for this directly into rhashtable.
So I'm adding a struct rhlist_head that would be used in place
of rhash_head for these cases and it'll carry an extra pointer
for the list of identical entries.
I will then add an additional layer of insert/lookup interfaces
for rhlist_head.
So bottom-line is that if you have no identical entries that you
only incur an extra 8 bytes per-object.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [v5.2] ucc_slow: Fix to avoid IS_ERR_VALUE abuses and dead code on 64bit systems.
From: Arvind Yadav @ 2016-08-05 8:40 UTC (permalink / raw)
To: zajec5, leoli
Cc: qiang.zhao, scottwood, viresh.kumar, akpm, linux-wireless, netdev,
linuxppc-dev, linux, arnd, Arvind Yadav
IS_ERR_VALUE() assumes that parameter is an unsigned long.
It can not be used to check if 'unsigned int' is passed insted.
Which tends to reflect an error.
In 64bit architectures sizeof (int) == 4 && sizeof (long) == 8.
IS_ERR_VALUE(x) is ((x) >= (unsigned long)-4095).
IS_ERR_VALUE() of 'unsigned int' is always false because the 32bit
value is zero extended to 64 bits.
Now Problem In UCC slow protocols -: drivers/soc/fsl/qe/ucc_slow.c
/* Get PRAM base */
uccs->us_pram_offset =
qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM);
if (IS_ERR_VALUE(uccs->us_pram_offset)) {
printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __func__);
ucc_slow_free(uccs);
return -ENOMEM;
}
id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, us_info->protocol,
uccs->us_pram_offset);
uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
/* Allocate BDs. */
uccs->rx_base_offset =
qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
QE_ALIGNMENT_OF_BD);
if (IS_ERR_VALUE(uccs->rx_base_offset)) {
printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __func__,
us_info->rx_bd_ring_len);
uccs->rx_base_offset = 0;
ucc_slow_free(uccs);
return -ENOMEM;
}
uccs->tx_base_offset =
qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
QE_ALIGNMENT_OF_BD);
if (IS_ERR_VALUE(uccs->tx_base_offset)) {
printk(KERN_ERR "%s: cannot allocate TX BDs", __func__);
uccs->tx_base_offset = 0;
ucc_slow_free(uccs);
return -ENOMEM;
}
qe_muram_alloc (a.k.a. cpm_muram_alloc) returns unsigned long.
Return value store in a u32 (us_pram_offset, rx_base_offset
and tx_base_offset).If qe_muram_alloc will return any error,
Then IS_ERR_VALUE will always return 0. it'll not call ucc_fast_free
for any failure. Inside 'if code' will be a dead code on 64bit.
Even qe_muram_addr will return wrong virtual address. Which
can cause an error.
This patch is to avoid this problem on 64bit machine.
Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
---
include/soc/fsl/qe/ucc_slow.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/soc/fsl/qe/ucc_slow.h b/include/soc/fsl/qe/ucc_slow.h
index 6c0573a..fca30a1 100644
--- a/include/soc/fsl/qe/ucc_slow.h
+++ b/include/soc/fsl/qe/ucc_slow.h
@@ -189,7 +189,7 @@ struct ucc_slow_private {
struct ucc_slow_info *us_info;
struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */
- u32 us_pram_offset;
+ unsigned long us_pram_offset;
int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
int stopped_tx; /* Whether channel has been stopped for Tx
@@ -198,8 +198,12 @@ struct ucc_slow_private {
struct list_head confQ; /* frames passed to chip waiting for tx */
u32 first_tx_bd_mask; /* mask is used in Tx routine to save status
and length for first BD in a frame */
- u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */
- u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */
+ unsigned long tx_base_offset; /* first BD in Tx BD table offset
+ * (In MURAM)
+ */
+ unsigned long rx_base_offset; /* first BD in Rx BD table offset
+ * (In MURAM)
+ */
struct qe_bd *confBd; /* next BD for confirm after Tx */
struct qe_bd *tx_bd; /* next BD for new Tx request */
struct qe_bd *rx_bd; /* next BD to collect after Rx */
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 4/4] ath10k: Enable support for QCA9984
From: Thiagarajan, Vasanthakumar @ 2016-08-05 10:06 UTC (permalink / raw)
To: bharath yadav
Cc: Archisman Maitra, Valo, Kalle, linux-wireless@vger.kernel.org,
ath10k@lists.infradead.org
In-Reply-To: <CAH1sOKUgb0pGmzN4pAy5GHseAW4QHHgyqJx4kgze5_27R8SKxg@mail.gmail.com>
T24gVGh1cnNkYXkgMDQgQXVndXN0IDIwMTYgMDc6NTAgUE0sIGJoYXJhdGggeWFkYXYgd3JvdGU6
DQo+IEhpLiwNCj4gSSBhbSB0cnlpbmcgdG8gZW5hYmxlIHN1cHBvcnQgZm9yIFFDQTk5ODQgb24g
bGF0ZXN0IHN0YWJsZSBiYWNrcG9ydHMtNC40LjItMSB1c2luZyB0aGUgYWJvdmUgcGF0Y2guDQo+
DQo+IGRvd25sb2FkZWQgImh0dHBzOi8va2VybmVsLmdvb2dsZXNvdXJjZS5jb20vcHViL3NjbS9s
aW51eC9rZXJuZWwvZ2l0L2t2YWxvL2F0aC8iIChhdGguZ2l0KSBoYXMgdGhlIHBhdGNoDQo+IGFw
cGxpZWQgZm9yIHFjYTk5ODQgYnV0IGl0IGhhcyBkb3dubG9hZGVkIHRoZSBrZXJuZWwgdHJlZS4N
Cj4NCj4gcGxlYXNlIGdpdmUgbWUgaW5mbyBvbiB3aGljaCB2ZXJzaW9uIG9mIGJhY2twb3J0cyB3
ZSBuZWVkIHRvIHVzZSBmb3IgUUNBOTk4NCBvciBob3cgdG8gYnVpbGQgYXRoMTBrIGFsb25lIGZy
b20NCj4gYXRoLmdpdCBrZXJuZWwgdHJlZS4NCg0KSSBkb250IHRoaW5rIHRoZXJlIGlzIGFueSBu
ZXcgYmFja3BvcnRzIHRhcmJhbGwgZm9yIHJlY2VudCBhdGguZ2l0IGF2YWlsYWJsZS4gWW91IG1h
eSBuZWVkIHRvIGNyZWF0ZSBvbmUsDQpwbGVhc2UgcmVmZXIgaHR0cHM6Ly93aXJlbGVzcy53aWtp
Lmtlcm5lbC5vcmcvZW4vdXNlcnMvZHJpdmVycy9hdGgxMGsvYmFja3BvcnRzIGZvciBpbmZvcm1h
dGlvbg0KdG8gY3JlYXRlIHlvdXIgb3duIGJhY2twb3J0cyB0YXJiYWxsLg0KDQpWYXNhbnRoDQoN
Cj4NCj4gT24gV2VkLCBNYXkgMTEsIDIwMTYgYXQgMTI6NDMgUE0sIFRoaWFnYXJhamFuLCBWYXNh
bnRoYWt1bWFyIDx2dGhpYWdhckBxdGkucXVhbGNvbW0uY29tDQo+IDxtYWlsdG86dnRoaWFnYXJA
cXRpLnF1YWxjb21tLmNvbT4+IHdyb3RlOg0KPg0KPiAgICAgT24gV2VkbmVzZGF5IDExIE1heSAy
MDE2IDEyOjIzIFBNLCBBcmNoaXNtYW4gTWFpdHJhIHdyb3RlOg0KPiAgICAgID4gSGksDQo+ICAg
ICAgPg0KPiAgICAgID4gVGhhbmsgeW91IGZvciBwcm92aWRpbmcgbWUgdGhlIGJpbmFyaWVzLg0K
PiAgICAgID4NCj4gICAgICA+IEkgaGF2ZSBzdGFydGVkIHdvcmtpbmcgb24gdGhlIG1hYzgwMjEx
IGRyaXZlciBhbmQgaGF2ZSBzb21lIHF1ZXN0aW9uczotDQo+ICAgICAgPg0KPiAgICAgID4gYSkg
SSBhbSB3b3JraW5nIHdpdGggT3BlbldSVCBmcmFtZXdvcmssIHdoaWNoIHVzZXMgbWFjODAyMTEg
ZHJpdmVyIGRhdGVkIDEtMTAtMjAxNi4gSSBoYXZlIG5vdGljZWQgdGhhdCB0aGUNCj4gICAgICA+
IHBhdGNoIHRoYXQgeW91IGhhdmUgcHJvdmlkZWQsIHVzZXMgYSBkaWZmZXJlbnQgbWFjODAyMTEg
ZHJpdmVyLiBXb3VsZCB0aGF0IGJlIGEgcHJvYmxlbT8NCj4gICAgICA+DQo+ICAgICAgPiBFeDot
DQo+ICAgICAgPiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCj4gICAg
ICA+ICAgICAgICAgIC5pZCA9IFFDQTk5ODRfSFdfMV8wX0RFVl9WRVJTSU9OLA0KPiAgICAgID4g
ICAgICAgICAgLmRldl9pZCA9IFFDQTk5ODRfMV8wX0RFVklDRV9JRCwNCj4gICAgID4gICAgICAg
ICAgLm5hbWUgPSAicWNhOTk4NC9xY2E5OTk0IGh3MS4wIiwNCj4gICAgICA+ICAgICAgICAgIC5w
YXRjaF9sb2FkX2FkZHIgPSBRQ0E5OTg0X0hXXzFfMF9QQVRDSF9MT0FEX0FERFIsDQo+ICAgICAg
PiAgICAgICAgICAudWFydF9waW4gPSA3LA0KPiAgICAgID4gICAgICAgICAgLm90cF9leGVfcGFy
YW0gPSAweDAwMDAwNzAwLA0KPiAgICAgID4gICAgICAgICAgLmNvbnRpbnVvdXNfZnJhZ19kZXNj
ID0gdHJ1ZSwNCj4gICAgICA+ICAgICAgICAgIC5jaGFubmVsX2NvdW50ZXJzX2ZyZXFfaHogPSAx
NTAwMDAsDQo+ICAgICAgPiAgICAgICAgICAubWF4X3Byb2JlX3Jlc3BfZGVzY190aHJlcyA9IDI0
LA0KPiAgICAgID4gICAgICAgICAgLmh3XzRhZGRyX3BhZCA9IEFUSDEwS19IV180QUREUl9QQURf
QkVGT1JFLA0KPiAgICAgID4gICAgICAgICAgLyoNCj4gICAgICA+ICAgICAgICAgIC50eF9jaGFp
bl9tYXNrID0gMHhmLA0KPiAgICAgID4gICAgICAgICAgLnJ4X2NoYWluX21hc2sgPSAweGYsDQo+
ICAgICAgPiAgICAgICAgICAubWF4X3NwYXRpYWxfc3RyZWFtID0gNCwNCj4gICAgICA+ICAgICAg
ICAgIC5jYWxfZGF0YV9sZW4gPSAxMjA2NCwgKi8NCj4gICAgICA+ICAgICAgICAgIC5mdyA9IHsN
Cj4gICAgICA+ICAgICAgICAgICAgICAuZGlyID0gUUNBOTk4NF9IV18xXzBfRldfRElSLA0KPiAg
ICAgID4gICAgICAgICAgICAgIC5mdyA9IFFDQTk5ODRfSFdfMV8wX0ZXX0ZJTEUsDQo+ICAgICAg
PiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQo+ICAgICAgPiAgIEhl
cmUsIHRoZSBjb21tZW50ZWQgb3V0IG1lbWJlcnMgYXJlIG5vdCBwcmVzZW50IGluIG15IGRyaXZl
ciBzb3VyY2UgY29kZS4NCj4gICAgICA+DQo+ICAgICAgPiBiKSAgImF0aDEwa19wY2kgMDAwMTow
MTowMC4wOiB1bmFibGUgdG8gcmVhZCBmcm9tIHRoZSBkZXZpY2UiIFRoaXMgaXMgZW5jb3VudGVy
ZWQgYXQgcnVudGltZS4gVXBvbg0KPiAgICAgID4gaW52ZXN0aWdhdGluZywgaXQgaXMgc2VlbiB0
aGF0ICBhdGgxMGtfYm1pX2V4ZWN1dGUoYXIsIGFkZHJlc3MsIEJNSV9QQVJBTV9HRVRfRUVQUk9N
X0JPQVJEX0lELCAmcmVzdWx0KQ0KPiAgICAgID4gcmV0dXJucyAwIGluIGRyaXZlcnMvbmV0L3dp
cmVsZXNzL2F0aC9hdGgxMGsvY29yZS5jIHdoZW4gY2FsbGVkIGZyb20gYXRoMTBrX2NvcmVfZ2V0
X2JvYXJkX2lkX2Zyb21fb3RwDQo+ICAgICAgPg0KPiAgICAgID4gT24gYnJvd3NpbmcgdGhlIHNv
dXJjZSBvZiB0aGUgZXJyb3IgSSBoYXZlIGZvdW5kIHRoZSBjb250cm9sIHRvIGdvIGZyb20gYXRo
MTBrX2JtaV9leGVjdXRlIC0tLS0+DQo+ICAgICAgPiAgIGF0aDEwa19wY2lfaGlmX2V4Y2hhbmdl
X2JtaV9tc2cgaW4gZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDEway9wY2kuYyAtLS0tLS0+
ICBhdGgxMGtfcGNpX2JtaV93YWl0IGluDQo+ICAgICAgPiBkcml2ZXJzL25ldC93aXJlbGVzcy9h
dGgvYXRoMTBrL3BjaS5jIHdoZXJlIGl0IHJldHVybnMgIC1FVElNRURPVVQNCj4NCj4gICAgIENh
biB5b3UgcGxlYXNlIG1vdmUgdG8gdGhlIGxhdGVzdCBhdGgxMGsgc3JjIChhdGguZ2l0KSBhbmQg
ZW5hYmxlIDB4NDIwIChibWkgYW5kIGJvb3QgcmVsYXRlZCBkZWJ1ZykgYXRoMTBrDQo+ICAgICBk
ZWJ1ZyBtYXNrPy4NCj4NCj4gICAgIFlvdSBjYW4gZW5hYmxlIHRoZSBkZWJ1ZyB0aHJvdWdoIG1v
ZHBhcmFtLCBpbnNtb2QgYXRoMTBrX2NvcmUgZGVidWdfbWFzaz0weDQyMC4NCj4NCj4NCj4gICAg
IFZhc2FudGgNCj4NCj4gICAgIF9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fDQo+ICAgICBhdGgxMGsgbWFpbGluZyBsaXN0DQo+ICAgICBhdGgxMGtAbGlzdHMu
aW5mcmFkZWFkLm9yZyA8bWFpbHRvOmF0aDEwa0BsaXN0cy5pbmZyYWRlYWQub3JnPg0KPiAgICAg
aHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9hdGgxMGsNCj4NCj4N
Cg==
^ permalink raw reply
* Re: [PATCH] cfg80211: Add support for user configurable beacon data rate
From: Johannes Berg @ 2016-08-05 9:03 UTC (permalink / raw)
To: Purushottam Kushwaha
Cc: linux-wireless, jouni, usdutt, ganeshk, mkalikot, amarnath
In-Reply-To: <1470371701-13074-1-git-send-email-pkushwah@qti.qualcomm.com>
On Fri, 2016-08-05 at 10:05 +0530, Purushottam Kushwaha wrote:
>
> +static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
> + struct cfg80211_bitrate_mask *mask);
I think you should move the function instead.
> @@ -3457,6 +3459,11 @@ static int nl80211_start_ap(struct sk_buff
> *skb, struct genl_info *info)
> err = cfg80211_validate_beacon_int(rdev,
> params.beacon_interval);
> if (err)
> return err;
> + if (info->attrs[NL80211_ATTR_TX_RATES]) {
> + err = nl80211_parse_tx_bitrate_mask(info,
> ¶ms.beacon_rate);
> + if (err)
> + return err;
> + }
Doesn't this have to check that it actually got information for the
right band?
johannes
^ permalink raw reply
* Re: [v5.1] ucc_fast: Fix to avoid IS_ERR_VALUE abuses and dead code on 64bit systems.
From: arvind Yadav @ 2016-08-05 8:48 UTC (permalink / raw)
To: Arnd Bergmann, linuxppc-dev
Cc: zajec5, leoli, qiang.zhao, viresh.kumar, linux-wireless, netdev,
scottwood, akpm, linux
In-Reply-To: <2376517.GXv6XVOdDd@wuerfel>
On Friday 05 August 2016 02:01 AM, Arnd Bergmann wrote:
> On Thursday, August 4, 2016 10:22:43 PM CEST Arvind Yadav wrote:
>> index df8ea79..ada9070 100644
>> --- a/include/soc/fsl/qe/ucc_fast.h
>> +++ b/include/soc/fsl/qe/ucc_fast.h
>> @@ -165,10 +165,12 @@ struct ucc_fast_private {
>> int stopped_tx; /* Whether channel has been stopped for Tx
>> (STOP_TX, etc.) */
>> int stopped_rx; /* Whether channel has been stopped for Rx */
>> - u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
>> - virtual fifo */
>> - u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
>> - virtual fifo */
>> + unsigned long ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of
>> + * Tx virtual fifo
>> + */
>> + unsigned long ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of
>> + * Rx virtual fifo
>> + */
>> #ifdef STATISTICS
>> u32 tx_frames; /* Transmitted frames counter. */
>> u32 rx_frames; /* Received frames counter (only frames
>>
> This change seems ok, but what about the other u32 variables in ucc_geth.c
> that get checked for IS_ERR_VALUE?
>
> Arnd
> I have send separate patch for ucc_geth ans ucc_slow.
> -Arvind
^ permalink raw reply
* Re: [PATCH v4] cfg80211: Provision to allow the support for different beacon intervals
From: Johannes Berg @ 2016-08-05 8:48 UTC (permalink / raw)
To: Purushottam Kushwaha
Cc: linux-wireless, jouni, usdutt, ganeshk, mkalikot, amarnath
In-Reply-To: <1470374768-22297-1-git-send-email-pkushwah@qti.qualcomm.com>
On Fri, 2016-08-05 at 10:56 +0530, Purushottam Kushwaha wrote:
> This commit provides the option for the host drivers to advertise the
> support for different beacon intervals among the respective interface
> combinations, through supp_diff_beacon_int (bool).
Neither your commit message nor the documentation makes a direct
reference to this affecting only AP/GO interface. However, you then go
and require that at least 2 interfaces with AP/GO are present.
What if you have AP,GO,mesh in the same interface combination? Either
your documentation needs to very very clearly state that the mesh must
match (either one of them?) and I'd go as far as renaming the APIs, or
you shouldn't require multiple APs and make this apply on mesh and IBSS
as well.
Are there really no restrictions whatsoever, btw?
It seems to me that if I were to specify beacon intervals which have a
very small GCD, you'll run into trouble when actually sending beacons.
Perhaps there should be a requirement on the GCD?
johannes
^ permalink raw reply
* Re: Buggy rhashtable walking
From: Johannes Berg @ 2016-08-05 6:16 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, netdev, linux-wireless; +Cc: Thomas Graf, tom
In-Reply-To: <20160804074546.GA996@gondor.apana.org.au>
> So I'm going to fix this by consolidating identical objects into
> a single rhashtable entry which also lets us get rid of the
> insecure_elasticity setting.
Hm. Would you rather allocate a separate head entry for the hashtable,
or chain the entries?
(Luckily) the colliding key case practically never happens, and some
drivers don't even allow it, so that's perhaps something to keep in
mind for this. Perhaps we should just generally disallow it - but a few
people (hi Ben) would be really unhappy about that I guess.
I think this might affect more than one use of rhashtable in mac80211
now, since the mesh paths also use it.
johannes
^ permalink raw reply
* [PATCH v4] cfg80211: Provision to allow the support for different beacon intervals
From: Purushottam Kushwaha @ 2016-08-05 5:26 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, jouni, usdutt, ganeshk, mkalikot, amarnath,
pkushwah
This commit provides the option for the host drivers to advertise the
support for different beacon intervals among the respective interface
combinations, through supp_diff_beacon_int (bool).
Signed-off-by: Purushottam Kushwaha <pkushwah@qti.qualcomm.com>
---
include/net/cfg80211.h | 4 ++++
include/uapi/linux/nl80211.h | 7 +++++--
net/wireless/core.c | 13 ++++++++++++-
net/wireless/nl80211.c | 3 +++
net/wireless/util.c | 24 +++++++++++++++++++++++-
5 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9c23f4d3..1b7cd42 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2939,6 +2939,8 @@ struct ieee80211_iface_limit {
* only in special cases.
* @radar_detect_widths: bitmap of channel widths supported for radar detection
* @radar_detect_regions: bitmap of regions supported for radar detection
+ * @supp_diff_beacon_int: In this combination, the interface combinations
+ * support different beacon intervals.
*
* With this structure the driver can describe which interface
* combinations it supports concurrently.
@@ -2970,6 +2972,7 @@ struct ieee80211_iface_limit {
* .n_limits = ARRAY_SIZE(limits2),
* .max_interfaces = 8,
* .num_different_channels = 1,
+ * .supp_diff_beacon_int = true,
* };
*
*
@@ -2997,6 +3000,7 @@ struct ieee80211_iface_combination {
bool beacon_int_infra_match;
u8 radar_detect_widths;
u8 radar_detect_regions;
+ bool supp_diff_beacon_int;
};
struct ieee80211_txrx_stypes {
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 2206941..b8d147c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4203,6 +4203,8 @@ enum nl80211_iface_limit_attrs {
* of supported channel widths for radar detection.
* @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
* of supported regulatory regions for radar detection.
+ * @NL80211_IFACE_COMB_DIFF_BEACON_INTERVAL: flag attribute specifying that
+ * different beacon interval within this group is allowed.
* @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number
*
@@ -4210,8 +4212,8 @@ enum nl80211_iface_limit_attrs {
* limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
* => allows an AP and a STA that must match BIs
*
- * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8
- * => allows 8 of AP/GO
+ * numbers = [ #{AP, P2P-GO} <= 8 ], different BI, channels = 1, max = 8,
+ * => allows 8 of AP/GO that may have different beacon interval
*
* numbers = [ #{STA} <= 2 ], channels = 2, max = 2
* => allows two STAs on different channels
@@ -4237,6 +4239,7 @@ enum nl80211_if_combination_attrs {
NL80211_IFACE_COMB_NUM_CHANNELS,
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
+ NL80211_IFACE_COMB_DIFF_BEACON_INTERVAL,
/* keep last */
NUM_NL80211_IFACE_COMB,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7645e97..204f861 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -485,7 +485,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
int i, j;
for (i = 0; i < wiphy->n_iface_combinations; i++) {
- u32 cnt = 0;
+ u32 cnt = 0, ap_cnt;
u16 all_iftypes = 0;
c = &wiphy->iface_combinations[i];
@@ -517,6 +517,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
if (WARN_ON(!c->n_limits))
return -EINVAL;
+ ap_cnt = 0;
for (j = 0; j < c->n_limits; j++) {
u16 types = c->limits[j].types;
@@ -538,6 +539,9 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
return -EINVAL;
cnt += c->limits[j].max;
+ ap_cnt += (types & (BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO))) ?
+ c->limits[j].max : 0;
/*
* Don't advertise an unsupported type
* in a combination.
@@ -546,6 +550,13 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
return -EINVAL;
}
+ /*
+ * Different beacon interval allowed only in AP or P2P_GO
+ * multi-interface combinations.
+ */
+ if (WARN_ON(c->supp_diff_beacon_int && (ap_cnt < 2)))
+ return -EINVAL;
+
/* You can't even choose that many! */
if (WARN_ON(cnt < c->max_interfaces))
return -EINVAL;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 46417f9..0a35d54 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1020,6 +1020,9 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
c->radar_detect_regions)))
goto nla_put_failure;
+ if (c->supp_diff_beacon_int &&
+ nla_put_flag(msg, NL80211_IFACE_COMB_DIFF_BEACON_INTERVAL))
+ goto nla_put_failure;
nla_nest_end(msg, nl_combi);
}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index b7d1592..3ceaa97 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1553,6 +1553,27 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
}
EXPORT_SYMBOL(ieee80211_chandef_to_operating_class);
+static bool diff_beacon_interval_supported(struct wiphy *wiphy)
+{
+ const struct ieee80211_iface_combination *c;
+ int i, j;
+
+ for (i = 0; i < wiphy->n_iface_combinations; i++) {
+ c = &wiphy->iface_combinations[i];
+
+ if (!c->supp_diff_beacon_int)
+ continue;
+
+ for (j = 0; j < c->n_limits; j++)
+ if (c->limits[j].types &
+ (BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO)))
+ return true;
+ }
+
+ return false;
+}
+
int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
u32 beacon_int)
{
@@ -1565,7 +1586,8 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (!wdev->beacon_interval)
continue;
- if (wdev->beacon_interval != beacon_int) {
+ if (wdev->beacon_interval != beacon_int &&
+ !diff_beacon_interval_supported(&rdev->wiphy)) {
res = -EINVAL;
break;
}
--
1.9.1
^ permalink raw reply related
* [PATCH] cfg80211: Add support for user configurable beacon data rate
From: Purushottam Kushwaha @ 2016-08-05 4:35 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, jouni, usdutt, ganeshk, mkalikot, amarnath,
pkushwah
This will allow user to configure beacon tx rate (u8) from userspace.
Signed-off-by: Purushottam Kushwaha <pkushwah@qti.qualcomm.com>
---
include/net/cfg80211.h | 25 +++++++++++---------
net/wireless/nl80211.c | 62 +++++++++++++++++++++++++++++++++-----------------
2 files changed, 55 insertions(+), 32 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9c23f4d3..dd900de 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -676,6 +676,18 @@ struct cfg80211_acl_data {
struct mac_address mac_addrs[];
};
+/*
+ * cfg80211_bitrate_mask - masks for bitrate control
+ */
+struct cfg80211_bitrate_mask {
+ struct {
+ u32 legacy;
+ u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
+ u16 vht_mcs[NL80211_VHT_NSS_MAX];
+ enum nl80211_txrate_gi gi;
+ } control[NUM_NL80211_BANDS];
+};
+
/**
* struct cfg80211_ap_settings - AP configuration
*
@@ -700,6 +712,7 @@ struct cfg80211_acl_data {
* MAC address based access control
* @pbss: If set, start as a PCP instead of AP. Relevant for DMG
* networks.
+ * @beacon_rate: masks for setting user configured beacon tx rate.
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -719,6 +732,7 @@ struct cfg80211_ap_settings {
bool p2p_opp_ps;
const struct cfg80211_acl_data *acl;
bool pbss;
+ struct cfg80211_bitrate_mask beacon_rate;
};
/**
@@ -2001,17 +2015,6 @@ enum wiphy_params_flags {
WIPHY_PARAM_DYN_ACK = 1 << 5,
};
-/*
- * cfg80211_bitrate_mask - masks for bitrate control
- */
-struct cfg80211_bitrate_mask {
- struct {
- u32 legacy;
- u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
- u16 vht_mcs[NL80211_VHT_NSS_MAX];
- enum nl80211_txrate_gi gi;
- } control[NUM_NL80211_BANDS];
-};
/**
* struct cfg80211_pmksa - PMK Security Association
*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 46417f9..53e7bf5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -36,6 +36,8 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
struct genl_info *info);
static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
struct genl_info *info);
+static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
+ struct cfg80211_bitrate_mask *mask);
/* the netlink family */
static struct genl_family nl80211_fam = {
@@ -3457,6 +3459,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
if (err)
return err;
+ if (info->attrs[NL80211_ATTR_TX_RATES]) {
+ err = nl80211_parse_tx_bitrate_mask(info, ¶ms.beacon_rate);
+ if (err)
+ return err;
+ }
/*
* In theory, some of these attributes should be required here
@@ -8696,22 +8703,17 @@ static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
[NL80211_TXRATE_GI] = { .type = NLA_U8 },
};
-static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
- struct genl_info *info)
+static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
+ struct cfg80211_bitrate_mask *mask)
{
struct nlattr *tb[NL80211_TXRATE_MAX + 1];
struct cfg80211_registered_device *rdev = info->user_ptr[0];
- struct cfg80211_bitrate_mask mask;
int rem, i;
- struct net_device *dev = info->user_ptr[1];
struct nlattr *tx_rates;
struct ieee80211_supported_band *sband;
u16 vht_tx_mcs_map;
- if (!rdev->ops->set_bitrate_mask)
- return -EOPNOTSUPP;
-
- memset(&mask, 0, sizeof(mask));
+ memset(mask, 0, sizeof(*mask));
/* Default to all rates enabled */
for (i = 0; i < NUM_NL80211_BANDS; i++) {
sband = rdev->wiphy.bands[i];
@@ -8719,16 +8721,16 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
if (!sband)
continue;
- mask.control[i].legacy = (1 << sband->n_bitrates) - 1;
- memcpy(mask.control[i].ht_mcs,
+ mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
+ memcpy(mask->control[i].ht_mcs,
sband->ht_cap.mcs.rx_mask,
- sizeof(mask.control[i].ht_mcs));
+ sizeof(mask->control[i].ht_mcs));
if (!sband->vht_cap.vht_supported)
continue;
vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
- vht_build_mcs_mask(vht_tx_mcs_map, mask.control[i].vht_mcs);
+ vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
}
/* if no rates are given set it back to the defaults */
@@ -8754,11 +8756,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
if (err)
return err;
if (tb[NL80211_TXRATE_LEGACY]) {
- mask.control[band].legacy = rateset_to_mask(
+ mask->control[band].legacy = rateset_to_mask(
sband,
nla_data(tb[NL80211_TXRATE_LEGACY]),
nla_len(tb[NL80211_TXRATE_LEGACY]));
- if ((mask.control[band].legacy == 0) &&
+ if ((mask->control[band].legacy == 0) &&
nla_len(tb[NL80211_TXRATE_LEGACY]))
return -EINVAL;
}
@@ -8767,24 +8769,24 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
sband,
nla_data(tb[NL80211_TXRATE_HT]),
nla_len(tb[NL80211_TXRATE_HT]),
- mask.control[band].ht_mcs))
+ mask->control[band].ht_mcs))
return -EINVAL;
}
if (tb[NL80211_TXRATE_VHT]) {
if (!vht_set_mcs_mask(
sband,
nla_data(tb[NL80211_TXRATE_VHT]),
- mask.control[band].vht_mcs))
+ mask->control[band].vht_mcs))
return -EINVAL;
}
if (tb[NL80211_TXRATE_GI]) {
- mask.control[band].gi =
+ mask->control[band].gi =
nla_get_u8(tb[NL80211_TXRATE_GI]);
- if (mask.control[band].gi > NL80211_TXRATE_FORCE_LGI)
+ if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
return -EINVAL;
}
- if (mask.control[band].legacy == 0) {
+ if (mask->control[band].legacy == 0) {
/* don't allow empty legacy rates if HT or VHT
* are not even supported.
*/
@@ -8793,11 +8795,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
return -EINVAL;
for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
- if (mask.control[band].ht_mcs[i])
+ if (mask->control[band].ht_mcs[i])
goto out;
for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
- if (mask.control[band].vht_mcs[i])
+ if (mask->control[band].vht_mcs[i])
goto out;
/* legacy and mcs rates may not be both empty */
@@ -8806,6 +8808,24 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
}
out:
+ return 0;
+}
+
+static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_bitrate_mask mask;
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ int err;
+
+ if (!rdev->ops->set_bitrate_mask)
+ return -EOPNOTSUPP;
+
+ err = nl80211_parse_tx_bitrate_mask(info, &mask);
+ if (err)
+ return err;
+
return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
}
--
1.9.1
^ permalink raw reply related
* [PATCH 1/2] ath9k: use ieee80211_tx_status_noskb where possible
From: Felix Fietkau @ 2016-08-04 21:49 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
It removes the need for undoing the padding changes to skb->data and it
improves performance by eliminating one tx status lookup per MPDU in the
status path. It is also useful for preparing a follow-up fix to better
handle powersave filtering.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/ath/ath9k/xmit.c | 94 +++++++++++++++++++++++------------
1 file changed, 62 insertions(+), 32 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 39d9383..5693558 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -50,9 +50,11 @@ static u16 bits_per_symbol[][2] = {
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid, struct sk_buff *skb);
static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
- int tx_flags, struct ath_txq *txq);
+ int tx_flags, struct ath_txq *txq,
+ struct ieee80211_sta *sta);
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
+ struct ieee80211_sta *sta,
struct ath_tx_status *ts, int txok);
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
struct list_head *head, bool internal);
@@ -77,6 +79,22 @@ enum {
/* Aggregation logic */
/*********************/
+static void ath_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = info->status.status_driver_data[0];
+
+ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
+ ieee80211_tx_status(hw, skb);
+ return;
+ }
+
+ if (sta)
+ ieee80211_tx_status_noskb(hw, sta, info);
+
+ dev_kfree_skb(skb);
+}
+
void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
__acquires(&txq->axq_lock)
{
@@ -92,6 +110,7 @@ void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
__releases(&txq->axq_lock)
{
+ struct ieee80211_hw *hw = sc->hw;
struct sk_buff_head q;
struct sk_buff *skb;
@@ -100,7 +119,7 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
spin_unlock_bh(&txq->axq_lock);
while ((skb = __skb_dequeue(&q)))
- ieee80211_tx_status(sc->hw, skb);
+ ath_tx_status(hw, skb);
}
static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
@@ -268,7 +287,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
}
list_add_tail(&bf->list, &bf_head);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
}
if (sendbar) {
@@ -333,12 +352,12 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
bf = fi->bf;
if (!bf) {
- ath_tx_complete(sc, skb, ATH_TX_ERROR, txq);
+ ath_tx_complete(sc, skb, ATH_TX_ERROR, txq, NULL);
continue;
}
list_add_tail(&bf->list, &bf_head);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
}
}
@@ -441,12 +460,11 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct list_head *bf_q,
+ struct ieee80211_sta *sta,
struct ath_tx_status *ts, int txok)
{
struct ath_node *an = NULL;
struct sk_buff *skb;
- struct ieee80211_sta *sta;
- struct ieee80211_hw *hw = sc->hw;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *tx_info;
struct ath_atx_tid *tid = NULL;
@@ -475,12 +493,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
for (i = 0; i < ts->ts_rateindex; i++)
retries += rates[i].count;
- rcu_read_lock();
-
- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
if (!sta) {
- rcu_read_unlock();
-
INIT_LIST_HEAD(&bf_head);
while (bf) {
bf_next = bf->bf_next;
@@ -488,7 +501,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
if (!bf->bf_state.stale || bf_next != NULL)
list_move_tail(&bf->list, &bf_head);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, ts, 0);
bf = bf_next;
}
@@ -598,7 +611,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
ts);
}
- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, sta, ts,
!txfail);
} else {
if (tx_info->flags & IEEE80211_TX_STATUS_EOSP) {
@@ -619,7 +632,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_update_baw(sc, tid, seqno);
ath_tx_complete_buf(sc, bf, txq,
- &bf_head, ts, 0);
+ &bf_head, NULL, ts,
+ 0);
bar_index = max_t(int, bar_index,
ATH_BA_INDEX(seq_first, seqno));
break;
@@ -663,8 +677,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_txq_lock(sc, txq);
}
- rcu_read_unlock();
-
if (needreset)
ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR);
}
@@ -679,7 +691,10 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
struct ath_tx_status *ts, struct ath_buf *bf,
struct list_head *bf_head)
{
+ struct ieee80211_hw *hw = sc->hw;
struct ieee80211_tx_info *info;
+ struct ieee80211_sta *sta;
+ struct ieee80211_hdr *hdr;
bool txok, flush;
txok = !(ts->ts_status & ATH9K_TXERR_MASK);
@@ -692,6 +707,10 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc,
ts->ts_rateindex);
+
+ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
+
if (!bf_isampdu(bf)) {
if (!flush) {
info = IEEE80211_SKB_CB(bf->bf_mpdu);
@@ -700,9 +719,9 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts);
}
- ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
+ ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok);
} else
- ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
+ ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, ts, txok);
if (!flush)
ath_txq_schedule(sc, txq);
@@ -938,7 +957,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
list_add(&bf->list, &bf_head);
__skb_unlink(skb, *q);
ath_tx_update_baw(sc, tid, seqno);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
continue;
}
@@ -1847,6 +1866,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
*/
void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq)
{
+ rcu_read_lock();
ath_txq_lock(sc, txq);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
@@ -1865,6 +1885,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq)
ath_drain_txq_list(sc, txq, &txq->axq_q);
ath_txq_unlock_complete(sc, txq);
+ rcu_read_unlock();
}
bool ath_drain_all_txq(struct ath_softc *sc)
@@ -2487,7 +2508,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
/*****************/
static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
- int tx_flags, struct ath_txq *txq)
+ int tx_flags, struct ath_txq *txq,
+ struct ieee80211_sta *sta)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2507,15 +2529,17 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
tx_info->flags |= IEEE80211_TX_STAT_ACK;
}
- padpos = ieee80211_hdrlen(hdr->frame_control);
- padsize = padpos & 3;
- if (padsize && skb->len>padpos+padsize) {
- /*
- * Remove MAC header padding before giving the frame back to
- * mac80211.
- */
- memmove(skb->data + padsize, skb->data, padpos);
- skb_pull(skb, padsize);
+ if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
+ padpos = ieee80211_hdrlen(hdr->frame_control);
+ padsize = padpos & 3;
+ if (padsize && skb->len>padpos+padsize) {
+ /*
+ * Remove MAC header padding before giving the frame back to
+ * mac80211.
+ */
+ memmove(skb->data + padsize, skb->data, padpos);
+ skb_pull(skb, padsize);
+ }
}
spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -2530,12 +2554,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
}
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
- __skb_queue_tail(&txq->complete_q, skb);
ath_txq_skb_done(sc, txq, skb);
+ tx_info->status.status_driver_data[0] = sta;
+ __skb_queue_tail(&txq->complete_q, skb);
}
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
+ struct ieee80211_sta *sta,
struct ath_tx_status *ts, int txok)
{
struct sk_buff *skb = bf->bf_mpdu;
@@ -2563,7 +2589,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
complete(&sc->paprd_complete);
} else {
ath_debug_stat_tx(sc, bf, ts, txq, tx_flags);
- ath_tx_complete(sc, skb, tx_flags, txq);
+ ath_tx_complete(sc, skb, tx_flags, txq, sta);
}
skip_tx_complete:
/* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
@@ -2715,10 +2741,12 @@ void ath_tx_tasklet(struct ath_softc *sc)
u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs;
int i;
+ rcu_read_lock();
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
ath_tx_processq(sc, &sc->tx.txq[i]);
}
+ rcu_read_unlock();
}
void ath_tx_edma_tasklet(struct ath_softc *sc)
@@ -2732,6 +2760,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
struct list_head *fifo_list;
int status;
+ rcu_read_lock();
for (;;) {
if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
break;
@@ -2802,6 +2831,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
ath_txq_unlock_complete(sc, txq);
}
+ rcu_read_unlock();
}
/*****************/
--
2.8.4
^ permalink raw reply related
* [PATCH 2/2] ath9k: improve powersave filter handling
From: Felix Fietkau @ 2016-08-04 21:49 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
In-Reply-To: <20160804214940.78476-1-nbd@nbd.name>
For non-aggregated frames, ath9k was leaving handling of powersave
filtered packets to mac80211. This can be too slow if the intermediate
queue is already filled with packets and mac80211 does not immediately
send a new packet via drv_tx().
Improve response time with filtered frames by triggering clearing the
powersave filter internally.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/ath/ath9k/xmit.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5693558..a3e292f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -461,13 +461,13 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct list_head *bf_q,
struct ieee80211_sta *sta,
+ struct ath_atx_tid *tid,
struct ath_tx_status *ts, int txok)
{
struct ath_node *an = NULL;
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *tx_info;
- struct ath_atx_tid *tid = NULL;
struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
struct list_head bf_head;
struct sk_buff_head bf_pending;
@@ -509,7 +509,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
}
an = (struct ath_node *)sta->drv_priv;
- tid = ath_get_skb_tid(sc, an, skb);
seq_first = tid->seq_start;
isba = ts->ts_flags & ATH9K_TX_BA;
@@ -695,6 +694,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
struct ieee80211_tx_info *info;
struct ieee80211_sta *sta;
struct ieee80211_hdr *hdr;
+ struct ath_atx_tid *tid = NULL;
bool txok, flush;
txok = !(ts->ts_status & ATH9K_TXERR_MASK);
@@ -710,6 +710,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
+ if (sta) {
+ struct ath_node *an = (struct ath_node *)sta->drv_priv;
+ tid = ath_get_skb_tid(sc, an, bf->bf_mpdu);
+ if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
+ tid->clear_ps_filter = true;
+ }
if (!bf_isampdu(bf)) {
if (!flush) {
@@ -721,7 +727,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
}
ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok);
} else
- ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, ts, txok);
+ ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, tid, ts, txok);
if (!flush)
ath_txq_schedule(sc, txq);
--
2.8.4
^ permalink raw reply related
* Re: [v5.1] ucc_fast: Fix to avoid IS_ERR_VALUE abuses and dead code on 64bit systems.
From: Arnd Bergmann @ 2016-08-04 20:31 UTC (permalink / raw)
To: linuxppc-dev
Cc: Arvind Yadav, zajec5, leoli, qiang.zhao, viresh.kumar,
linux-wireless, netdev, scottwood, akpm, linux
In-Reply-To: <1470329563-5464-1-git-send-email-arvind.yadav.cs@gmail.com>
On Thursday, August 4, 2016 10:22:43 PM CEST Arvind Yadav wrote:
> index df8ea79..ada9070 100644
> --- a/include/soc/fsl/qe/ucc_fast.h
> +++ b/include/soc/fsl/qe/ucc_fast.h
> @@ -165,10 +165,12 @@ struct ucc_fast_private {
> int stopped_tx; /* Whether channel has been stopped for Tx
> (STOP_TX, etc.) */
> int stopped_rx; /* Whether channel has been stopped for Rx */
> - u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
> - virtual fifo */
> - u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
> - virtual fifo */
> + unsigned long ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of
> + * Tx virtual fifo
> + */
> + unsigned long ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of
> + * Rx virtual fifo
> + */
> #ifdef STATISTICS
> u32 tx_frames; /* Transmitted frames counter. */
> u32 rx_frames; /* Received frames counter (only frames
>
This change seems ok, but what about the other u32 variables in ucc_geth.c
that get checked for IS_ERR_VALUE?
Arnd
^ permalink raw reply
* Re: Wireless Workshop accepted into the 2016 Linux Kernel Summit and Linux Plumbers Conference
From: Johannes Berg @ 2016-08-04 17:32 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <20160802084542.75cd47c2@redtail.lan>
> Please join us for a timely and important discussion [4]!
>
> KS [5] will be held October 31-November 1 and LPC [6] will be held
> November 1-4, both in Santa Fe, New Mexico, US.
The workshop is going to be on November 1st, the combined day.
I've put up a new wiki page here:
https://wireless.wiki.kernel.org/en/developers/summits/santa-fe-2016
Please consider adding yourself, I have a number of free/reduced passes
to hand out so I'll assign those maybe next week. You do need to be
registered for LPC, which is currently closed for registrations, but
I'm trying to see if we can get reservations or maybe workshop-only
tickets.
Please add yourself if you are considering attending, so I can get a
better idea of the numbers.
johannes
^ permalink raw reply
* [PATCH] ath10k: hide kernel addresses from logs using %pK format specifier
From: c_mkenna @ 2016-08-04 13:51 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, mkenna, Maharaja Kennadyrajan
From: Maharaja Kennadyrajan <c_mkenna@qti.qualcomm.com>
With the %pK format specifier we hide the kernel addresses
with the help of kptr_restrict sysctl.
In this patch, %p is changed to %pK in the driver code.
The sysctl is documented in Documentation/sysctl/kernel.txt.
Signed-off-by: Maharaja Kennadyrajan <c_mkenna@qti.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/ahb.c | 2 +-
drivers/net/wireless/ath/ath10k/bmi.c | 4 ++--
drivers/net/wireless/ath/ath10k/ce.c | 4 ++--
drivers/net/wireless/ath/ath10k/core.c | 4 ++--
drivers/net/wireless/ath/ath10k/htc.c | 6 +++---
drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +-
drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++----------
drivers/net/wireless/ath/ath10k/pci.c | 2 +-
drivers/net/wireless/ath/ath10k/testmode.c | 4 ++--
drivers/net/wireless/ath/ath10k/txrx.c | 2 +-
drivers/net/wireless/ath/ath10k/wmi.c | 4 ++--
11 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c
index acec16b..dede026 100644
--- a/drivers/net/wireless/ath/ath10k/ahb.c
+++ b/drivers/net/wireless/ath/ath10k/ahb.c
@@ -577,7 +577,7 @@ static int ath10k_ahb_resource_init(struct ath10k *ar)
ath10k_dbg(ar, ATH10K_DBG_BOOT, "irq: %d\n", ar_ahb->irq);
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%p mem_len: %lu gcc mem: 0x%p tcsr_mem: 0x%p\n",
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%pK mem_len: %lu gcc mem: 0x%pK tcsr_mem: 0x%pK\n",
ar_ahb->mem, ar_ahb->mem_len,
ar_ahb->gcc_mem, ar_ahb->tcsr_mem);
return 0;
diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c
index 3d29b08..2872d34 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.c
+++ b/drivers/net/wireless/ath/ath10k/bmi.c
@@ -221,7 +221,7 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
u32 txlen;
int ret;
- ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n",
+ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%pK length %d\n",
buffer, length);
if (ar->bmi.done_sent) {
@@ -287,7 +287,7 @@ int ath10k_bmi_fast_download(struct ath10k *ar,
int ret;
ath10k_dbg(ar, ATH10K_DBG_BMI,
- "bmi fast download address 0x%x buffer 0x%p length %d\n",
+ "bmi fast download address 0x%x buffer 0x%pK length %d\n",
address, buffer, length);
ret = ath10k_bmi_lz_stream_start(ar, address);
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 9fb8d74..65d8d71 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -840,7 +840,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
ath10k_dbg(ar, ATH10K_DBG_BOOT,
- "boot init ce src ring id %d entries %d base_addr %p\n",
+ "boot init ce src ring id %d entries %d base_addr %pK\n",
ce_id, nentries, src_ring->base_addr_owner_space);
return 0;
@@ -874,7 +874,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
ath10k_dbg(ar, ATH10K_DBG_BOOT,
- "boot ce dest ring id %d entries %d base_addr %p\n",
+ "boot ce dest ring id %d entries %d base_addr %pK\n",
ce_id, nentries, dest_ring->base_addr_owner_space);
return 0;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index e889829..ffcf6b8 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -699,7 +699,7 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
if (!ar->running_fw->fw_file.otp_data ||
!ar->running_fw->fw_file.otp_len) {
- ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
+ ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",
ar->running_fw->fw_file.otp_data,
ar->running_fw->fw_file.otp_len);
return 0;
@@ -753,7 +753,7 @@ static int ath10k_download_fw(struct ath10k *ar)
}
ath10k_dbg(ar, ATH10K_DBG_BOOT,
- "boot uploading firmware image %p len %d\n",
+ "boot uploading firmware image %pK len %d\n",
data, data_len);
ret = ath10k_bmi_fast_download(ar, address, data, data_len);
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 5b3c6bc..175aae3 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -44,7 +44,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
skb_cb = ATH10K_SKB_CB(skb);
memset(skb_cb, 0, sizeof(*skb_cb));
- ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb);
+ ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %pK\n", __func__, skb);
return skb;
}
@@ -62,7 +62,7 @@ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
{
struct ath10k *ar = ep->htc->ar;
- ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
+ ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
ep->eid, skb);
ath10k_htc_restore_tx_skb(ep->htc, skb);
@@ -404,7 +404,7 @@ void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
goto out;
}
- ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n",
+ ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %pK\n",
eid, skb);
ep->ep_ops.ep_rx_complete(ar, skb);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 78db5d6..ae6931b 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -931,7 +931,7 @@ static void ath10k_process_rx(struct ath10k *ar,
*status = *rx_status;
ath10k_dbg(ar, ATH10K_DBG_DATA,
- "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
+ "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
skb,
skb->len,
ieee80211_get_SA(hdr),
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index fb8e38d..fe3b1d9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -824,7 +824,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
*/
for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
if (ar->peer_map[i] == peer) {
- ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",
+ ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
peer->addr, peer, i);
ar->peer_map[i] = NULL;
}
@@ -3524,7 +3524,7 @@ static int ath10k_mac_tx(struct ath10k *ar,
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
if (!ath10k_mac_tx_frm_has_freq(ar)) {
- ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
skb);
skb_queue_tail(&ar->offchan_tx_queue, skb);
@@ -3586,7 +3586,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
mutex_lock(&ar->conf_mutex);
- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
skb);
hdr = (struct ieee80211_hdr *)skb->data;
@@ -3643,7 +3643,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
time_left =
wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
if (time_left == 0)
- ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
+ ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
skb);
if (!peer && tmp_peer_created) {
@@ -6001,7 +6001,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
continue;
if (peer->sta == sta) {
- ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n",
+ ath10k_warn(ar, "found sta peer %pM (ptr %pK id %d) entry on vdev %i after it was supposedly removed\n",
sta->addr, peer, i, arvif->vdev_id);
peer->sta = NULL;
@@ -7134,7 +7134,7 @@ ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
struct ath10k *ar = hw->priv;
ath10k_dbg(ar, ATH10K_DBG_MAC,
- "mac chanctx add freq %hu width %d ptr %p\n",
+ "mac chanctx add freq %hu width %d ptr %pK\n",
ctx->def.chan->center_freq, ctx->def.width, ctx);
mutex_lock(&ar->conf_mutex);
@@ -7158,7 +7158,7 @@ ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
struct ath10k *ar = hw->priv;
ath10k_dbg(ar, ATH10K_DBG_MAC,
- "mac chanctx remove freq %hu width %d ptr %p\n",
+ "mac chanctx remove freq %hu width %d ptr %pK\n",
ctx->def.chan->center_freq, ctx->def.width, ctx);
mutex_lock(&ar->conf_mutex);
@@ -7223,7 +7223,7 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
mutex_lock(&ar->conf_mutex);
ath10k_dbg(ar, ATH10K_DBG_MAC,
- "mac chanctx change freq %hu width %d ptr %p changed %x\n",
+ "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
/* This shouldn't really happen because channel switching should use
@@ -7281,7 +7281,7 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
mutex_lock(&ar->conf_mutex);
ath10k_dbg(ar, ATH10K_DBG_MAC,
- "mac chanctx assign ptr %p vdev_id %i\n",
+ "mac chanctx assign ptr %pK vdev_id %i\n",
ctx, arvif->vdev_id);
if (WARN_ON(arvif->is_started)) {
@@ -7342,7 +7342,7 @@ ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
mutex_lock(&ar->conf_mutex);
ath10k_dbg(ar, ATH10K_DBG_MAC,
- "mac chanctx unassign ptr %p vdev_id %i\n",
+ "mac chanctx unassign ptr %pK vdev_id %i\n",
ctx, arvif->vdev_id);
WARN_ON(!arvif->is_started);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 9a22c47..1b841ad 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -3062,7 +3062,7 @@ static int ath10k_pci_claim(struct ath10k *ar)
goto err_master;
}
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem);
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%pK\n", ar_pci->mem);
return 0;
err_master:
diff --git a/drivers/net/wireless/ath/ath10k/testmode.c b/drivers/net/wireless/ath/ath10k/testmode.c
index 120f423..52298c3 100644
--- a/drivers/net/wireless/ath/ath10k/testmode.c
+++ b/drivers/net/wireless/ath/ath10k/testmode.c
@@ -45,7 +45,7 @@ bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
int ret;
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
- "testmode event wmi cmd_id %d skb %p skb->len %d\n",
+ "testmode event wmi cmd_id %d skb %pK skb->len %d\n",
cmd_id, skb, skb->len);
ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", skb->data, skb->len);
@@ -360,7 +360,7 @@ static int ath10k_tm_cmd_wmi(struct ath10k *ar, struct nlattr *tb[])
cmd_id = nla_get_u32(tb[ATH10K_TM_ATTR_WMI_CMDID]);
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
- "testmode cmd wmi cmd_id %d buf %p buf_len %d\n",
+ "testmode cmd wmi cmd_id %d buf %pK buf_len %d\n",
cmd_id, buf, buf_len);
ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len);
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index b29a86a..1e695d1 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -44,7 +44,7 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
complete(&ar->offchan_tx_completed);
ar->offchan_tx_skb = NULL; /* just for sanity */
- ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb);
+ ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %pK\n", skb);
out:
spin_unlock_bh(&ar->data_lock);
}
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 169cd2e7..bb080d4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1874,7 +1874,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
memcpy(cmd->buf, msdu->data, msdu->len);
- ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n",
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %pK len %d ftype %02x stype %02x\n",
msdu, skb->len, fc & IEEE80211_FCTL_FTYPE,
fc & IEEE80211_FCTL_STYPE);
trace_ath10k_tx_hdr(ar, skb->data, skb->len);
@@ -2347,7 +2347,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
ath10k_mac_handle_beacon(ar, skb);
ath10k_dbg(ar, ATH10K_DBG_MGMT,
- "event mgmt rx skb %p len %d ftype %02x stype %02x\n",
+ "event mgmt rx skb %pK len %d ftype %02x stype %02x\n",
skb, skb->len,
fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/2] get_expected_throughput interface update
From: Maxim Altshul @ 2016-08-04 12:48 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, kvalo, Maxim Altshul
These two patches are two important patches (mainly 1/2)
that solve a regression issue that was found in wlcore
(where wl was found to be null in some cases)
Also, they make it easier for driver to get hw->priv when op is invoked.
Maxim Altshul (2):
mac80211/wlcore: Add ieee80211_hw variable to get_expected_throughput
wlcore: Remove wl pointer from wl_sta structure
drivers/net/wireless/ti/wlcore/main.c | 6 +++---
drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 -
include/net/mac80211.h | 3 ++-
net/mac80211/driver-ops.h | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
--
2.9.0
^ permalink raw reply
* Re: [PATCH] ath10k: disable wake_tx_queue for older devices
From: Dave Taht @ 2016-08-04 12:02 UTC (permalink / raw)
To: Roman Yeryomin
Cc: Valo, Kalle, linux-wireless@vger.kernel.org,
michal.kazior@tieto.com, ath10k@lists.infradead.org
In-Reply-To: <CACiydb+PfbS+Hc79My2HFqdacFtik7_H8d3kFsrST6m1GnSAgA@mail.gmail.com>
On Thu, Aug 4, 2016 at 12:07 PM, Roman Yeryomin <leroi.lists@gmail.com> wrote:
> On 1 August 2016 at 12:04, Dave Taht <dave.taht@gmail.com> wrote:
>> On Mon, Aug 1, 2016 at 1:35 AM, Roman Yeryomin <leroi.lists@gmail.com> wrote:
>>> On 7 July 2016 at 19:30, Valo, Kalle <kvalo@qca.qualcomm.com> wrote:
>>>> Michal Kazior <michal.kazior@tieto.com> writes:
>>>>
>>>>> Ideally wake_tx_queue should be used regardless as
>>>>> it is a requirement for reducing bufferbloat and
>>>>> implementing airtime fairness in the future.
>>>>>
>>>>> However some setups (typically low-end platforms
>>>>> hosting QCA988X) suffer performance regressions
>>>>> with the current wake_tx_queue implementation.
>>>>> Therefore disable it unless it is really
>>>>> beneficial with current codebase (which is when
>>>>> firmware supports smart pull-push tx scheduling).
>>>>>
>>>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>>>
>>>> I think it's too late to send this to 4.7 anymore (and this due to my
>>>> vacation). So I'm planning to queue this to 4.8, but if the feedback is
>>>> positive we can always send this to a 4.7 stable release.
>>>>
>>>
>>> Sorry guys, drowned.
>>> So, yes, applying this patch does the job. That is gets me to the
>>> results similar to
>>> https://lists.openwrt.org/pipermail/openwrt-devel/2016-May/041448.html
>>>
>>> Going to try latest code on same system...
>>
>> Can you try increasing the quantum to 1514, and reducing the codel
>> target to 5ms? (without this patch?)
>>
>
> So it was 1514 already...
based on some testing of 20, codel target should be 5ms and isn't.
https://github.com/torvalds/linux/commit/5caa328e3811b7cfa33fd02c93280ffa622deb0e
> Regards,
> Roman
>
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
--
Dave Täht
Let's go make home routers and wifi faster! With better software!
http://blog.cerowrt.org
^ permalink raw reply
* Re: [PATCH] ath10k: disable wake_tx_queue for older devices
From: Roman Yeryomin @ 2016-08-04 10:07 UTC (permalink / raw)
To: Dave Taht
Cc: Valo, Kalle, linux-wireless@vger.kernel.org,
michal.kazior@tieto.com, ath10k@lists.infradead.org
In-Reply-To: <CAA93jw6j0pBKnm3Fs=D7V1CUsBnhZKKymbk4=UQuFWKuEAs-+Q@mail.gmail.com>
On 1 August 2016 at 12:04, Dave Taht <dave.taht@gmail.com> wrote:
> On Mon, Aug 1, 2016 at 1:35 AM, Roman Yeryomin <leroi.lists@gmail.com> wrote:
>> On 7 July 2016 at 19:30, Valo, Kalle <kvalo@qca.qualcomm.com> wrote:
>>> Michal Kazior <michal.kazior@tieto.com> writes:
>>>
>>>> Ideally wake_tx_queue should be used regardless as
>>>> it is a requirement for reducing bufferbloat and
>>>> implementing airtime fairness in the future.
>>>>
>>>> However some setups (typically low-end platforms
>>>> hosting QCA988X) suffer performance regressions
>>>> with the current wake_tx_queue implementation.
>>>> Therefore disable it unless it is really
>>>> beneficial with current codebase (which is when
>>>> firmware supports smart pull-push tx scheduling).
>>>>
>>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>>
>>> I think it's too late to send this to 4.7 anymore (and this due to my
>>> vacation). So I'm planning to queue this to 4.8, but if the feedback is
>>> positive we can always send this to a 4.7 stable release.
>>>
>>
>> Sorry guys, drowned.
>> So, yes, applying this patch does the job. That is gets me to the
>> results similar to
>> https://lists.openwrt.org/pipermail/openwrt-devel/2016-May/041448.html
>>
>> Going to try latest code on same system...
>
> Can you try increasing the quantum to 1514, and reducing the codel
> target to 5ms? (without this patch?)
>
So it was 1514 already...
Regards,
Roman
^ 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