<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.kernel.wireless.general">
    <title>gmane.linux.kernel.wireless.general</title>
    <link>http://blog.gmane.org/gmane.linux.kernel.wireless.general</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108254"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108250"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108248"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108216"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108214"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108213"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108212"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108211"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108206"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108205"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108204"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108198"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108189"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108185"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108183"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108179"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108175"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108168"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108158"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108156"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108254">
    <title>[PATCH 0/3] Work on STBC Rx monitoring</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108254</link>
    <description>&lt;pre&gt;This patch set will pass RxSTBC flags from ath9k to ieee80211
and to radiotap.
This field is now a part of radiotap specification:
http://www.radiotap.org/defined-fields/MCS

Oleksij Rempel (3):
  mac80211: add STBC flag for radiotap
  ath9k: remove useless flag conversation.
  ath9k: check for Rx-STBC flag and pass it to ieee80211

 drivers/net/wireless/ath/ath9k/ar9003_mac.c |  5 +++--
 drivers/net/wireless/ath/ath9k/mac.c        | 16 ++++++++++++----
 drivers/net/wireless/ath/ath9k/mac.h        |  4 +++-
 drivers/net/wireless/ath/ath9k/recv.c       |  5 +----
 include/net/ieee80211_radiotap.h            |  7 +++++++
 include/net/mac80211.h                      |  4 ++++
 net/mac80211/main.c                         |  3 ++-
 net/mac80211/rx.c                           |  4 ++++
 net/mac80211/status.c                       |  3 ++-
 9 files changed, 38 insertions(+), 13 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Oleksij Rempel</dc:creator>
    <dc:date>2013-05-19T07:38:53</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108250">
    <title>[PATCH 3.10] ath9k: prevent aggregation session deadlocks</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108250</link>
    <description>&lt;pre&gt;Waiting for all subframes of an existing aggregation session to drain
before allowing mac80211 to start a new one is fragile and deadlocks
caused by this behavior have been observed.

Since mac80211 has proper synchronization for aggregation session
start/stop handling, a better approach to session handling is to simply
allow mac80211 to start a new session at any time. This requires
changing the code to discard any packets outside of the BlockAck window
in the A-MPDU software retry code.

This patch implements the above and also simplifies the code.

Signed-off-by: Felix Fietkau &amp;lt;nbd-p3rKhJxN3npAfugRpC6u6w&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  14 +---
 drivers/net/wireless/ath/ath9k/main.c  |   3 +-
 drivers/net/wireless/ath/ath9k/rc.c    |   5 +-
 drivers/net/wireless/ath/ath9k/xmit.c  | 138 ++++++++++-----------------------
 4 files changed, 46 insertions(+), 114 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 366002f..42b03dc 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -251,10 +251,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ath_atx_tid {
 int tidno;
 int baw_head;   /* first un-acked tx buffer */
 int baw_tail;   /* next unused tx buffer slot */
-int sched;
-int paused;
-u8 state;
-bool stop_cb;
+bool sched;
+bool paused;
+bool active;
 };
 
 struct ath_node {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -275,10 +274,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ath_node {
 #endif
 };
 
-#define AGGR_CLEANUP         BIT(1)
-#define AGGR_ADDBA_COMPLETE  BIT(2)
-#define AGGR_ADDBA_PROGRESS  BIT(3)
-
 struct ath_tx_control {
 struct ath_txq *txq;
 struct ath_node *an;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -352,8 +347,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_tasklet(struct ath_softc *sc);
 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);
-bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
-      bool flush);
+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);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 2382d12..5092eca 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1709,7 +1709,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 flush = true;
 case IEEE80211_AMPDU_TX_STOP_CONT:
 ath9k_ps_wakeup(sc);
-if (ath_tx_aggr_stop(sc, sta, tid, flush))
+ath_tx_aggr_stop(sc, sta, tid);
+if (!flush)
 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
 ath9k_ps_restore(sc);
 break;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index aa4d368..7eb1f4b 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1227,10 +1227,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
 return false;
 
 txtid = ATH_AN_2_TID(an, tidno);
-
-if (!(txtid-&amp;gt;state &amp;amp; (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
-return true;
-return false;
+return !txtid-&amp;gt;active;
 }
 
 
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 14bb335..1c9b1ba 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -125,24 +125,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
 list_add_tail(&amp;amp;ac-&amp;gt;list, &amp;amp;txq-&amp;gt;axq_acq);
 }
 
-static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-struct ath_txq *txq = tid-&amp;gt;ac-&amp;gt;txq;
-
-WARN_ON(!tid-&amp;gt;paused);
-
-ath_txq_lock(sc, txq);
-tid-&amp;gt;paused = false;
-
-if (skb_queue_empty(&amp;amp;tid-&amp;gt;buf_q))
-goto unlock;
-
-ath_tx_queue_tid(txq, tid);
-ath_txq_schedule(sc, txq);
-unlock:
-ath_txq_unlock_complete(sc, txq);
-}
-
 static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
 {
 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -164,20 +146,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
        ARRAY_SIZE(bf-&amp;gt;rates));
 }
 
-static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
-if (!tid-&amp;gt;stop_cb)
-return;
-
-ieee80211_start_tx_ba_cb_irqsafe(tid-&amp;gt;an-&amp;gt;vif, tid-&amp;gt;an-&amp;gt;sta-&amp;gt;addr,
- tid-&amp;gt;tidno);
-tid-&amp;gt;stop_cb = false;
-}
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
-     bool flush_packets)
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
 struct ath_txq *txq = tid-&amp;gt;ac-&amp;gt;txq;
 struct sk_buff *skb;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -194,15 +163,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
 while ((skb = __skb_dequeue(&amp;amp;tid-&amp;gt;buf_q))) {
 fi = get_frame_info(skb);
 bf = fi-&amp;gt;bf;
-if (!bf &amp;amp;&amp;amp; !flush_packets)
-bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
 if (!bf) {
-ieee80211_free_txskb(sc-&amp;gt;hw, skb);
-continue;
+bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+if (!bf) {
+ieee80211_free_txskb(sc-&amp;gt;hw, skb);
+continue;
+}
 }
 
-if (fi-&amp;gt;retries || flush_packets) {
+if (fi-&amp;gt;retries) {
 list_add_tail(&amp;amp;bf-&amp;gt;list, &amp;amp;bf_head);
 ath_tx_update_baw(sc, tid, bf-&amp;gt;bf_state.seqno);
 ath_tx_complete_buf(sc, bf, txq, &amp;amp;bf_head, &amp;amp;ts, 0);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -213,10 +183,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
 }
 }
 
-if (tid-&amp;gt;baw_head == tid-&amp;gt;baw_tail)
-ath_tx_clear_tid(sc, tid);
-
-if (sendbar &amp;amp;&amp;amp; !flush_packets) {
+if (sendbar) {
 ath_txq_unlock(sc, txq);
 ath_send_bar(tid, tid-&amp;gt;seq_start);
 ath_txq_lock(sc, txq);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -499,19 +466,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 tx_info = IEEE80211_SKB_CB(skb);
 fi = get_frame_info(skb);
 
-if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
+if (!BAW_WITHIN(tid-&amp;gt;seq_start, tid-&amp;gt;baw_size, seqno)) {
+/*
+ * Outside of the current BlockAck window,
+ * maybe part of a previous session
+ */
+txfail = 1;
+} else if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
 /* transmit completion, subframe is
  * acked by block ack */
 acked_cnt++;
 } else if (!isaggr &amp;amp;&amp;amp; txok) {
 /* transmit completion */
 acked_cnt++;
-} else if (tid-&amp;gt;state &amp;amp; AGGR_CLEANUP) {
-/*
- * cleanup in progress, just fail
- * the un-acked sub-frames
- */
-txfail = 1;
 } else if (flush) {
 txpending = 1;
 } else if (fi-&amp;gt;retries &amp;lt; ATH_MAX_SW_RETRIES) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -535,7 +502,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 if (bf_next != NULL || !bf_last-&amp;gt;bf_stale)
 list_move_tail(&amp;amp;bf-&amp;gt;list, &amp;amp;bf_head);
 
-if (!txpending || (tid-&amp;gt;state &amp;amp; AGGR_CLEANUP)) {
+if (!txpending) {
 /*
  * complete the acked-ones/xretried ones; update
  * block-ack window
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -609,9 +576,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 ath_txq_lock(sc, txq);
 }
 
-if (tid-&amp;gt;state &amp;amp; AGGR_CLEANUP)
-ath_tx_flush_tid(sc, tid, false);
-
 rcu_read_unlock();
 
 if (needreset)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1244,9 +1208,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
 an = (struct ath_node *)sta-&amp;gt;drv_priv;
 txtid = ATH_AN_2_TID(an, tid);
 
-if (txtid-&amp;gt;state &amp;amp; (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
-return -EAGAIN;
-
 /* update ampdu factor/density, they may have changed. This may happen
  * in HT IBSS when a beacon with HT-info is received after the station
  * has already been added.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1258,7 +1219,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
 an-&amp;gt;mpdudensity = density;
 }
 
-txtid-&amp;gt;state |= AGGR_ADDBA_PROGRESS;
+txtid-&amp;gt;active = true;
 txtid-&amp;gt;paused = true;
 *ssn = txtid-&amp;gt;seq_start = txtid-&amp;gt;seq_next;
 txtid-&amp;gt;bar_index = -1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1269,45 +1230,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
 return 0;
 }
 
-bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
-      bool flush)
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
 struct ath_node *an = (struct ath_node *)sta-&amp;gt;drv_priv;
 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
 struct ath_txq *txq = txtid-&amp;gt;ac-&amp;gt;txq;
-bool ret = !flush;
-
-if (flush)
-txtid-&amp;gt;stop_cb = false;
-
-if (txtid-&amp;gt;state &amp;amp; AGGR_CLEANUP)
-return false;
-
-if (!(txtid-&amp;gt;state &amp;amp; AGGR_ADDBA_COMPLETE)) {
-txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
-return ret;
-}
 
 ath_txq_lock(sc, txq);
+txtid-&amp;gt;active = false;
 txtid-&amp;gt;paused = true;
-
-/*
- * If frames are still being transmitted for this TID, they will be
- * cleaned up during tx completion. To prevent race conditions, this
- * TID can only be reused after all in-progress subframes have been
- * completed.
- */
-if (txtid-&amp;gt;baw_head != txtid-&amp;gt;baw_tail) {
-txtid-&amp;gt;state |= AGGR_CLEANUP;
-ret = false;
-txtid-&amp;gt;stop_cb = !flush;
-} else {
-txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-}
-
-ath_tx_flush_tid(sc, txtid, flush);
+ath_tx_flush_tid(sc, txtid);
 ath_txq_unlock_complete(sc, txq);
-return ret;
 }
 
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1371,18 +1304,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
 }
 }
 
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
+u16 tidno)
 {
-struct ath_atx_tid *txtid;
+struct ath_atx_tid *tid;
 struct ath_node *an;
+struct ath_txq *txq;
 
 an = (struct ath_node *)sta-&amp;gt;drv_priv;
+tid = ATH_AN_2_TID(an, tidno);
+txq = tid-&amp;gt;ac-&amp;gt;txq;
 
-txtid = ATH_AN_2_TID(an, tid);
-txtid-&amp;gt;baw_size = IEEE80211_MIN_AMPDU_BUF &amp;lt;&amp;lt; sta-&amp;gt;ht_cap.ampdu_factor;
-txtid-&amp;gt;state |= AGGR_ADDBA_COMPLETE;
-txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
-ath_tx_resume_tid(sc, txtid);
+ath_txq_lock(sc, txq);
+
+tid-&amp;gt;baw_size = IEEE80211_MIN_AMPDU_BUF &amp;lt;&amp;lt; sta-&amp;gt;ht_cap.ampdu_factor;
+tid-&amp;gt;paused = false;
+
+if (!skb_queue_empty(&amp;amp;tid-&amp;gt;buf_q)) {
+ath_tx_queue_tid(txq, tid);
+ath_txq_schedule(sc, txq);
+}
+
+ath_txq_unlock_complete(sc, txq);
 }
 
 /********************/
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2431,13 +2374,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 tid-&amp;gt;baw_head  = tid-&amp;gt;baw_tail = 0;
 tid-&amp;gt;sched     = false;
 tid-&amp;gt;paused    = false;
-tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
+tid-&amp;gt;active   = false;
 __skb_queue_head_init(&amp;amp;tid-&amp;gt;buf_q);
 acno = TID_TO_WME_AC(tidno);
 tid-&amp;gt;ac = &amp;amp;an-&amp;gt;ac[acno];
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
-tid-&amp;gt;stop_cb = false;
 }
 
 for (acno = 0, ac = &amp;amp;an-&amp;gt;ac[acno];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2474,7 +2414,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 }
 
 ath_tid_drain(sc, txq, tid);
-ath_tx_clear_tid(sc, tid);
+tid-&amp;gt;active = false;
 
 ath_txq_unlock(sc, txq);
 }
&lt;/pre&gt;</description>
    <dc:creator>Felix Fietkau</dc:creator>
    <dc:date>2013-05-18T19:28:15</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108248">
    <title>rt3070-based usb device won't accept mac address changes</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108248</link>
    <description>&lt;pre&gt;Hi, after switching to kernel 3.8.8 (ubuntu quantal to raring), I'm
unable to change my alfa AWUS036NH mac address; a simple:

ifconfig &amp;lt;device&amp;gt; down
ifconfig &amp;lt;device&amp;gt; hw ether &amp;lt;random hw&amp;gt;

results in:

SIOCSIFHWADDR: Invalid argument

I tried the drivers shipped with the distribution,
compat-drivers-3.9-rc4-2-su and compat-drivers-2013-03-28-4-u aswell;
all to no avail.

Any help appreciated, I'm able to recompile/test if needed.

Thank you for your time.

Alessandro Lannocca

Attached 'lsusb -v' , kernel 3.8.8 x86_64

&amp;lt;snip&amp;gt;

Bus 003 Device 005: ID 148f:3070 Ralink Technology, Corp.
RT2870/RT3070 Wireless Adapter
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x148f Ralink Technology, Corp.
  idProduct          0x3070 RT2870/RT3070 Wireless Adapter
  bcdDevice            1.01
  iManufacturer           1
  iProduct                2
  iSerial                 3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           67
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              450mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           7
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x06  EP 6 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0

&amp;lt;/snip&amp;gt;
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA&amp;lt; at &amp;gt;public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Alessandro Lannocca</dc:creator>
    <dc:date>2013-05-18T15:10:55</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108216">
    <title>[PATCH 00/32] BBP initialization split</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108216</link>
    <description>&lt;pre&gt;This series spits big and messy rt2800_init_bbp() procedure into small
per chip (or few similar chips) subroutines.

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA&amp;lt; at &amp;gt;public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>stf_xl-5tc4TXWwyLM&lt; at &gt;public.gmane.org</dc:creator>
    <dc:date>2013-05-18T12:03:23</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108214">
    <title>[PATCH v2 17/17] mwifiex: add support for Marvell SD8897 chipset</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108214</link>
    <description>&lt;pre&gt;From: Yogesh Ashok Powar &amp;lt;yogeshp-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

Some of the key differences between SD8897 and older chipsets
are as follows:

a) sdio mpa_rx and mpa_tx ports have been increased from 16 to 32
b) Same is the case with read/write bitmap that one receives from
   mpa_reg read
c) aggregation packet count doubled from 8 to 16
d) Most of key reg addresses are changed
e) There is a separate command or control port
f) Now command rx/tx_done have new interrupts

1. 'supports_sdio_new_mode' flag is added to handle (a) and (b).
2. (c) and (d) are taken care of by filling chip specific
   information in global structurei (mwifiex_sdio_sd8897).
3. For older chipsets, port 0 was cmd port and port 1-&amp;gt;15 were
   data port. Therefore we had CTRL_PORT_MASK to differentiate
   port type. Now these changes are under 'has_control_mask' flag.

Signed-off-by: Yogesh Ashok Powar &amp;lt;yogeshp-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Nishant Sarmukadam &amp;lt;nishants-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Frank Huang &amp;lt;frankh-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
v2: fix cmd53 single port address overwriting

 drivers/net/wireless/mwifiex/Kconfig |   4 +-
 drivers/net/wireless/mwifiex/sdio.c  | 267 ++++++++++++++++++++++++++++-------
 drivers/net/wireless/mwifiex/sdio.h  | 105 +++++++++++++-
 3 files changed, 315 insertions(+), 61 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 4f614aa..f7ff472 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3,13 +3,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config MWIFIEX
 depends on CFG80211
 ---help---
   This adds support for wireless adapters based on Marvell
-  802.11n chipsets.
+  802.11n/ac chipsets.
 
   If you choose to build it as a module, it will be called
   mwifiex.
 
 config MWIFIEX_SDIO
-tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797"
+tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797/SD8897"
 depends on MWIFIEX &amp;amp;&amp;amp; MMC
 select FW_LOADER
 ---help---
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 4b196dc..5ee5ed0 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -84,6 +84,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
 card-&amp;gt;reg = data-&amp;gt;reg;
 card-&amp;gt;max_ports = data-&amp;gt;max_ports;
 card-&amp;gt;mp_agg_pkt_limit = data-&amp;gt;mp_agg_pkt_limit;
+card-&amp;gt;supports_sdio_new_mode = data-&amp;gt;supports_sdio_new_mode;
+card-&amp;gt;has_control_mask = data-&amp;gt;has_control_mask;
 }
 
 sdio_claim_host(func);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -260,6 +262,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_resume(struct device *dev)
 #define SDIO_DEVICE_ID_MARVELL_8787   (0x9119)
 /* Device ID for SD8797 */
 #define SDIO_DEVICE_ID_MARVELL_8797   (0x9129)
+/* Device ID for SD8897 */
+#define SDIO_DEVICE_ID_MARVELL_8897   (0x912d)
 
 /* WLAN IDs */
 static const struct sdio_device_id mwifiex_ids[] = {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -269,6 +273,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const struct sdio_device_id mwifiex_ids[] = {
 .driver_data = (unsigned long) &amp;amp;mwifiex_sdio_sd8787},
 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797),
 .driver_data = (unsigned long) &amp;amp;mwifiex_sdio_sd8797},
+{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897),
+.driver_data = (unsigned long) &amp;amp;mwifiex_sdio_sd8897},
 {},
 };
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -412,7 +418,40 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
 }
 
 /*
- * This function initializes the IO ports.
+ * This function is used to initialize IO ports for the
+ * chipsets supporting SDIO new mode eg SD8897.
+ */
+static int mwifiex_init_sdio_new_mode(struct mwifiex_adapter *adapter)
+{
+u8 reg;
+
+adapter-&amp;gt;ioport = MEM_PORT;
+
+/* enable sdio new mode */
+if (mwifiex_read_reg(adapter, CARD_CONFIG_2_1_REG, &amp;amp;reg))
+return -1;
+if (mwifiex_write_reg(adapter, CARD_CONFIG_2_1_REG,
+      reg | CMD53_NEW_MODE))
+return -1;
+
+/* Configure cmd port and enable reading rx length from the register */
+if (mwifiex_read_reg(adapter, CMD_CONFIG_0, &amp;amp;reg))
+return -1;
+if (mwifiex_write_reg(adapter, CMD_CONFIG_0, reg | CMD_PORT_RD_LEN_EN))
+return -1;
+
+/* Enable Dnld/Upld ready auto reset for cmd port after cmd53 is
+ * completed
+ */
+if (mwifiex_read_reg(adapter, CMD_CONFIG_1, &amp;amp;reg))
+return -1;
+if (mwifiex_write_reg(adapter, CMD_CONFIG_1, reg | CMD_PORT_AUTO_EN))
+return -1;
+
+return 0;
+}
+
+/* This function initializes the IO ports.
  *
  * The following operations are performed -
  *      - Read the IO ports (0, 1 and 2)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -426,6 +465,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
 
 adapter-&amp;gt;ioport = 0;
 
+if (card-&amp;gt;supports_sdio_new_mode) {
+if (mwifiex_init_sdio_new_mode(adapter))
+return -1;
+goto cont;
+}
+
 /* Read the IO port */
 if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &amp;amp;reg))
 adapter-&amp;gt;ioport |= (reg &amp;amp; 0xff);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -441,7 +486,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
 adapter-&amp;gt;ioport |= ((reg &amp;amp; 0xff) &amp;lt;&amp;lt; 16);
 else
 return -1;
-
+cont:
 pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter-&amp;gt;ioport);
 
 /* Set Host interrupt reset to read to clear */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -504,10 +549,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 
 dev_dbg(adapter-&amp;gt;dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap);
 
-if (!(rd_bitmap &amp;amp; (CTRL_PORT_MASK | reg-&amp;gt;data_port_mask)))
-return -1;
+if (card-&amp;gt;supports_sdio_new_mode) {
+if (!(rd_bitmap &amp;amp; reg-&amp;gt;data_port_mask))
+return -1;
+} else {
+if (!(rd_bitmap &amp;amp; (CTRL_PORT_MASK | reg-&amp;gt;data_port_mask)))
+return -1;
+}
 
-if (card-&amp;gt;mp_rd_bitmap &amp;amp; CTRL_PORT_MASK) {
+if ((card-&amp;gt;has_control_mask) &amp;amp;&amp;amp;
+    (card-&amp;gt;mp_rd_bitmap &amp;amp; CTRL_PORT_MASK)) {
 card-&amp;gt;mp_rd_bitmap &amp;amp;= (u32) (~CTRL_PORT_MASK);
 *port = CTRL_PORT;
 dev_dbg(adapter-&amp;gt;dev, "data: port=%d mp_rd_bitmap=0x%08x\n",
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -542,24 +593,34 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
+const struct mwifiex_sdio_card_reg *reg = card-&amp;gt;reg;
 u32 wr_bitmap = card-&amp;gt;mp_wr_bitmap;
 
 dev_dbg(adapter-&amp;gt;dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);
 
-if (!(wr_bitmap &amp;amp; card-&amp;gt;mp_data_port_mask))
+if (card-&amp;gt;supports_sdio_new_mode &amp;amp;&amp;amp;
+    !(wr_bitmap &amp;amp; reg-&amp;gt;data_port_mask)) {
+adapter-&amp;gt;data_sent = true;
+return -EBUSY;
+} else if (!card-&amp;gt;supports_sdio_new_mode &amp;amp;&amp;amp;
+   !(wr_bitmap &amp;amp; card-&amp;gt;mp_data_port_mask)) {
 return -1;
+}
 
 if (card-&amp;gt;mp_wr_bitmap &amp;amp; (1 &amp;lt;&amp;lt; card-&amp;gt;curr_wr_port)) {
 card-&amp;gt;mp_wr_bitmap &amp;amp;= (u32) (~(1 &amp;lt;&amp;lt; card-&amp;gt;curr_wr_port));
 *port = card-&amp;gt;curr_wr_port;
-if (++card-&amp;gt;curr_wr_port == card-&amp;gt;mp_end_port)
-card-&amp;gt;curr_wr_port = card-&amp;gt;reg-&amp;gt;start_wr_port;
+if (((card-&amp;gt;supports_sdio_new_mode) &amp;amp;&amp;amp;
+     (++card-&amp;gt;curr_wr_port == card-&amp;gt;max_ports)) ||
+    ((!card-&amp;gt;supports_sdio_new_mode) &amp;amp;&amp;amp;
+     (++card-&amp;gt;curr_wr_port == card-&amp;gt;mp_end_port)))
+card-&amp;gt;curr_wr_port = reg-&amp;gt;start_wr_port;
 } else {
 adapter-&amp;gt;data_sent = true;
 return -EBUSY;
 }
 
-if (*port == CTRL_PORT) {
+if ((card-&amp;gt;has_control_mask) &amp;amp;&amp;amp; (*port == CTRL_PORT)) {
 dev_err(adapter-&amp;gt;dev,
 "invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -&amp;gt; 0x%08x\n",
 *port, card-&amp;gt;curr_wr_port, wr_bitmap,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -904,6 +965,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
 if (sdio_ireg) {
 /*
  * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+ * For SDIO new mode CMD port interrupts
+ *DN_LD_CMD_PORT_HOST_INT_STATUS and/or
+ *UP_LD_CMD_PORT_HOST_INT_STATUS
  * Clear the interrupt status register
  */
 dev_dbg(adapter-&amp;gt;dev, "int: sdio_ireg = %#x\n", sdio_ireg);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1031,7 +1095,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 u8 *curr_ptr;
 u32 rx_len = skb-&amp;gt;len;
 
-if (port == CTRL_PORT) {
+if ((card-&amp;gt;has_control_mask) &amp;amp;&amp;amp; (port == CTRL_PORT)) {
 /* Read the command Resp without aggr */
 dev_dbg(adapter-&amp;gt;dev, "info: %s: no aggregation for cmd "
 "response\n", __func__);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1048,7 +1112,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 goto rx_curr_single;
 }
 
-if (card-&amp;gt;mp_rd_bitmap &amp;amp; (~((u32) CTRL_PORT_MASK))) {
+if ((!card-&amp;gt;has_control_mask &amp;amp;&amp;amp; (card-&amp;gt;mp_rd_bitmap &amp;amp;
+ card-&amp;gt;reg-&amp;gt;data_port_mask)) ||
+    (card-&amp;gt;has_control_mask &amp;amp;&amp;amp; (card-&amp;gt;mp_rd_bitmap &amp;amp;
+(~((u32) CTRL_PORT_MASK))))) {
 /* Some more data RX pending */
 dev_dbg(adapter-&amp;gt;dev, "info: %s: not last packet\n", __func__);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1100,8 +1167,25 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 dev_dbg(adapter-&amp;gt;dev, "info: do_rx_aggr: num of packets: %d\n",
 card-&amp;gt;mpa_rx.pkt_cnt);
 
-mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
- (card-&amp;gt;mpa_rx.ports &amp;lt;&amp;lt; 4)) + card-&amp;gt;mpa_rx.start_port;
+if (card-&amp;gt;supports_sdio_new_mode) {
+int i;
+u32 port_count;
+
+for (i = 0, port_count = 0; i &amp;lt; card-&amp;gt;max_ports; i++)
+if (card-&amp;gt;mpa_rx.ports &amp;amp; BIT(i))
+port_count++;
+
+/* Reading data from "start_port + 0" to "start_port +
+ * port_count -1", so decrease the count by 1
+ */
+port_count--;
+mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
+ (port_count &amp;lt;&amp;lt; 8)) + card-&amp;gt;mpa_rx.start_port;
+} else {
+mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
+ (card-&amp;gt;mpa_rx.ports &amp;lt;&amp;lt; 4)) +
+ card-&amp;gt;mpa_rx.start_port;
+}
 
 if (mwifiex_read_data_sync(adapter, card-&amp;gt;mpa_rx.buf,
    card-&amp;gt;mpa_rx.buf_len, mport, 1))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1200,6 +1284,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 u32 rx_blocks;
 u16 rx_len;
 unsigned long flags;
+u32 bitmap;
+u8 cr;
 
 spin_lock_irqsave(&amp;amp;adapter-&amp;gt;int_lock, flags);
 sdio_ireg = adapter-&amp;gt;int_status;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1209,12 +1295,60 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 if (!sdio_ireg)
 return ret;
 
+/* Following interrupt is only for SDIO new mode */
+if (sdio_ireg &amp;amp; DN_LD_CMD_PORT_HOST_INT_STATUS &amp;amp;&amp;amp; adapter-&amp;gt;cmd_sent)
+adapter-&amp;gt;cmd_sent = false;
+
+/* Following interrupt is only for SDIO new mode */
+if (sdio_ireg &amp;amp; UP_LD_CMD_PORT_HOST_INT_STATUS) {
+u32 pkt_type;
+
+/* read the len of control packet */
+rx_len = card-&amp;gt;mp_regs[CMD_RD_LEN_1] &amp;lt;&amp;lt; 8;
+rx_len |= (u16) card-&amp;gt;mp_regs[CMD_RD_LEN_0];
+rx_blocks = DIV_ROUND_UP(rx_len, MWIFIEX_SDIO_BLOCK_SIZE);
+if (rx_len &amp;lt;= INTF_HEADER_LEN ||
+    (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) &amp;gt;
+     MWIFIEX_RX_DATA_BUF_SIZE)
+return -1;
+rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
+
+skb = dev_alloc_skb(rx_len);
+if (!skb)
+return -1;
+
+skb_put(skb, rx_len);
+
+if (mwifiex_sdio_card_to_host(adapter, &amp;amp;pkt_type, skb-&amp;gt;data,
+      skb-&amp;gt;len, adapter-&amp;gt;ioport |
+CMD_PORT_SLCT)) {
+dev_err(adapter-&amp;gt;dev,
+"%s: failed to card_to_host", __func__);
+dev_kfree_skb_any(skb);
+goto term_cmd;
+}
+
+if ((pkt_type != MWIFIEX_TYPE_CMD) &amp;amp;&amp;amp;
+    (pkt_type != MWIFIEX_TYPE_EVENT))
+dev_err(adapter-&amp;gt;dev,
+"%s:Received wrong packet on cmd port",
+__func__);
+
+mwifiex_decode_rx_packet(adapter, skb, pkt_type);
+}
+
 if (sdio_ireg &amp;amp; DN_LD_HOST_INT_STATUS) {
-card-&amp;gt;mp_wr_bitmap =
-((u32) card-&amp;gt;mp_regs[reg-&amp;gt;wr_bitmap_u]) &amp;lt;&amp;lt; 8;
-card-&amp;gt;mp_wr_bitmap |=
-(u32) card-&amp;gt;mp_regs[reg-&amp;gt;wr_bitmap_l];
-dev_dbg(adapter-&amp;gt;dev, "int: DNLD: wr_bitmap=0x%08x\n",
+bitmap = (u32) card-&amp;gt;mp_regs[reg-&amp;gt;wr_bitmap_l];
+bitmap |= ((u32) card-&amp;gt;mp_regs[reg-&amp;gt;wr_bitmap_u]) &amp;lt;&amp;lt; 8;
+if (card-&amp;gt;supports_sdio_new_mode) {
+bitmap |=
+((u32) card-&amp;gt;mp_regs[reg-&amp;gt;wr_bitmap_1l]) &amp;lt;&amp;lt; 16;
+bitmap |=
+((u32) card-&amp;gt;mp_regs[reg-&amp;gt;wr_bitmap_1u]) &amp;lt;&amp;lt; 24;
+}
+card-&amp;gt;mp_wr_bitmap = bitmap;
+
+dev_dbg(adapter-&amp;gt;dev, "int: DNLD: wr_bitmap=0x%x\n",
 card-&amp;gt;mp_wr_bitmap);
 if (adapter-&amp;gt;data_sent &amp;amp;&amp;amp;
     (card-&amp;gt;mp_wr_bitmap &amp;amp; card-&amp;gt;mp_data_port_mask)) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1227,7 +1361,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 /* As firmware will not generate download ready interrupt if the port
    updated is command port only, cmd_sent should be done for any SDIO
    interrupt. */
-if (adapter-&amp;gt;cmd_sent) {
+if (card-&amp;gt;has_control_mask &amp;amp;&amp;amp; adapter-&amp;gt;cmd_sent) {
 /* Check if firmware has attach buffer at command port and
    update just that in wr_bit_map. */
 card-&amp;gt;mp_wr_bitmap |=
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1239,10 +1373,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 dev_dbg(adapter-&amp;gt;dev, "info: cmd_sent=%d data_sent=%d\n",
 adapter-&amp;gt;cmd_sent, adapter-&amp;gt;data_sent);
 if (sdio_ireg &amp;amp; UP_LD_HOST_INT_STATUS) {
-card-&amp;gt;mp_rd_bitmap =
-((u32) card-&amp;gt;mp_regs[reg-&amp;gt;rd_bitmap_u]) &amp;lt;&amp;lt; 8;
-card-&amp;gt;mp_rd_bitmap |= (u32) card-&amp;gt;mp_regs[reg-&amp;gt;rd_bitmap_l];
-dev_dbg(adapter-&amp;gt;dev, "int: UPLD: rd_bitmap=0x%08x\n",
+bitmap = (u32) card-&amp;gt;mp_regs[reg-&amp;gt;rd_bitmap_l];
+bitmap |= ((u32) card-&amp;gt;mp_regs[reg-&amp;gt;rd_bitmap_u]) &amp;lt;&amp;lt; 8;
+if (card-&amp;gt;supports_sdio_new_mode) {
+bitmap |=
+((u32) card-&amp;gt;mp_regs[reg-&amp;gt;rd_bitmap_1l]) &amp;lt;&amp;lt; 16;
+bitmap |=
+((u32) card-&amp;gt;mp_regs[reg-&amp;gt;rd_bitmap_1u]) &amp;lt;&amp;lt; 24;
+}
+card-&amp;gt;mp_rd_bitmap = bitmap;
+dev_dbg(adapter-&amp;gt;dev, "int: UPLD: rd_bitmap=0x%x\n",
 card-&amp;gt;mp_rd_bitmap);
 
 while (true) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1285,37 +1425,33 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 
 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
       port)) {
-u8 cr = 0;
-
 dev_err(adapter-&amp;gt;dev, "card_to_host_mpa failed:"
 " int status=%#x\n", sdio_ireg);
-if (mwifiex_read_reg(adapter,
-     CONFIGURATION_REG, &amp;amp;cr))
-dev_err(adapter-&amp;gt;dev,
-"read CFG reg failed\n");
-
-dev_dbg(adapter-&amp;gt;dev,
-"info: CFG reg val = %d\n", cr);
-if (mwifiex_write_reg(adapter,
-      CONFIGURATION_REG,
-      (cr | 0x04)))
-dev_err(adapter-&amp;gt;dev,
-"write CFG reg failed\n");
-
-dev_dbg(adapter-&amp;gt;dev, "info: write success\n");
-if (mwifiex_read_reg(adapter,
-     CONFIGURATION_REG, &amp;amp;cr))
-dev_err(adapter-&amp;gt;dev,
-"read CFG reg failed\n");
-
-dev_dbg(adapter-&amp;gt;dev,
-"info: CFG reg val =%x\n", cr);
-return -1;
+goto term_cmd;
 }
 }
 }
 
 return 0;
+
+term_cmd:
+/* terminate cmd */
+if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &amp;amp;cr))
+dev_err(adapter-&amp;gt;dev, "read CFG reg failed\n");
+else
+dev_dbg(adapter-&amp;gt;dev, "info: CFG reg val = %d\n", cr);
+
+if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04)))
+dev_err(adapter-&amp;gt;dev, "write CFG reg failed\n");
+else
+dev_dbg(adapter-&amp;gt;dev, "info: write success\n");
+
+if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &amp;amp;cr))
+dev_err(adapter-&amp;gt;dev, "read CFG reg failed\n");
+else
+dev_dbg(adapter-&amp;gt;dev, "info: CFG reg val =%x\n", cr);
+
+return -1;
 }
 
 /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1344,7 +1480,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 s32 f_postcopy_cur_buf = 0;
 u32 mport;
 
-if ((!card-&amp;gt;mpa_tx.enabled) || (port == CTRL_PORT)) {
+if (!card-&amp;gt;mpa_tx.enabled ||
+    (card-&amp;gt;has_control_mask &amp;amp;&amp;amp; (port == CTRL_PORT)) ||
+    (card-&amp;gt;supports_sdio_new_mode &amp;amp;&amp;amp; (port == CMD_PORT_SLCT))) {
 dev_dbg(adapter-&amp;gt;dev, "info: %s: tx aggregation disabled\n",
 __func__);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1419,8 +1557,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 dev_dbg(adapter-&amp;gt;dev, "data: %s: send aggr buffer: %d %d\n",
 __func__,
 card-&amp;gt;mpa_tx.start_port, card-&amp;gt;mpa_tx.ports);
-mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
- (card-&amp;gt;mpa_tx.ports &amp;lt;&amp;lt; 4)) + card-&amp;gt;mpa_tx.start_port;
+if (card-&amp;gt;supports_sdio_new_mode) {
+u32 port_count;
+int i;
+
+for (i = 0, port_count = 0; i &amp;lt; card-&amp;gt;max_ports; i++)
+if (card-&amp;gt;mpa_tx.ports &amp;amp; BIT(i))
+port_count++;
+
+/* Writing data from "start_port + 0" to "start_port +
+ * port_count -1", so decrease the count by 1
+ */
+port_count--;
+mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
+ (port_count &amp;lt;&amp;lt; 8)) + card-&amp;gt;mpa_tx.start_port;
+} else {
+mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
+ (card-&amp;gt;mpa_tx.ports &amp;lt;&amp;lt; 4)) +
+ card-&amp;gt;mpa_tx.start_port;
+}
+
 ret = mwifiex_write_data_to_card(adapter, card-&amp;gt;mpa_tx.buf,
  card-&amp;gt;mpa_tx.buf_len, mport);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1493,6 +1649,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
     pkt_len &amp;gt; MWIFIEX_UPLD_SIZE)
 dev_err(adapter-&amp;gt;dev, "%s: payload=%p, nb=%d\n",
 __func__, payload, pkt_len);
+
+if (card-&amp;gt;supports_sdio_new_mode)
+port = CMD_PORT_SLCT;
 }
 
 /* Transfer data to card */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1748,8 +1907,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
 
 card-&amp;gt;mp_data_port_mask = reg-&amp;gt;data_port_mask;
 
-for (i = 1; i &amp;lt;= card-&amp;gt;max_ports - card-&amp;gt;mp_end_port; i++)
-card-&amp;gt;mp_data_port_mask &amp;amp;= ~(1 &amp;lt;&amp;lt; (card-&amp;gt;max_ports - i));
+if (reg-&amp;gt;start_wr_port) {
+for (i = 1; i &amp;lt;= card-&amp;gt;max_ports - card-&amp;gt;mp_end_port; i++)
+card-&amp;gt;mp_data_port_mask &amp;amp;=
+~(1 &amp;lt;&amp;lt; (card-&amp;gt;max_ports - i));
+}
 
 card-&amp;gt;curr_wr_port = reg-&amp;gt;start_wr_port;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1857,3 +2019,4 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; MODULE_LICENSE("GPL v2");
 MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME);
 MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME);
 MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME);
+MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 597db37..6d51dfd 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -32,6 +32,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define SD8786_DEFAULT_FW_NAME "mrvl/sd8786_uapsta.bin"
 #define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
 #define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin"
+#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
 
 #define BLOCK_MODE1
 #define BYTE_MODE0
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -46,6 +47,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define CTRL_PORT0
 #define CTRL_PORT_MASK0x0001
 
+#define CMD_PORT_UPLD_INT_MASK(0x1U&amp;lt;&amp;lt;6)
+#define CMD_PORT_DNLD_INT_MASK(0x1U&amp;lt;&amp;lt;7)
+#define HOST_TERM_CMD53(0x1U &amp;lt;&amp;lt; 2)
+#define REG_PORT0
+#define MEM_PORT0x10000
+#define CMD_RD_LEN_00xB4
+#define CMD_RD_LEN_10xB5
+#define CARD_CONFIG_2_1_REG             0xCD
+#define CMD53_NEW_MODE(0x1U &amp;lt;&amp;lt; 0)
+#define CMD_CONFIG_00xB8
+#define CMD_PORT_RD_LEN_EN(0x1U &amp;lt;&amp;lt; 2)
+#define CMD_CONFIG_10xB9
+#define CMD_PORT_AUTO_EN(0x1U &amp;lt;&amp;lt; 0)
+#define CMD_PORT_SLCT0x8000
+#define UP_LD_CMD_PORT_HOST_INT_STATUS(0x40U)
+#define DN_LD_CMD_PORT_HOST_INT_STATUS(0x80U)
+
 #define SDIO_MP_TX_AGGR_DEF_BUF_SIZE        (8192)/* 8K */
 
 /* Multi port RX aggregation buffer size */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -73,6 +91,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define UP_LD_HOST_INT_MASK(0x1U)
 /* Host Control Registers : Download host interrupt mask */
 #define DN_LD_HOST_INT_MASK(0x2U)
+
 /* Disable Host interrupt mask */
 #defineHOST_INT_DISABLE0xff
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -196,8 +215,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct mwifiex_sdio_card_reg {
 u8 max_mp_regs;
 u8 rd_bitmap_l;
 u8 rd_bitmap_u;
+u8 rd_bitmap_1l;
+u8 rd_bitmap_1u;
 u8 wr_bitmap_l;
 u8 wr_bitmap_u;
+u8 wr_bitmap_1l;
+u8 wr_bitmap_1u;
 u8 rd_len_p0_l;
 u8 rd_len_p0_u;
 u8 card_misc_cfg_reg;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -211,6 +234,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct sdio_mmc_card {
 const struct mwifiex_sdio_card_reg *reg;
 u8 max_ports;
 u8 mp_agg_pkt_limit;
+bool supports_sdio_new_mode;
+bool has_control_mask;
 
 u32 mp_rd_bitmap;
 u32 mp_wr_bitmap;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -232,6 +257,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct mwifiex_sdio_device {
 const struct mwifiex_sdio_card_reg *reg;
 u8 max_ports;
 u8 mp_agg_pkt_limit;
+bool supports_sdio_new_mode;
+bool has_control_mask;
 };
 
 static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -255,11 +282,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
 .card_misc_cfg_reg = 0x6c,
 };
 
+static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
+.start_rd_port = 0,
+.start_wr_port = 0,
+.base_0_reg = 0x60,
+.base_1_reg = 0x61,
+.poll_reg = 0x50,
+.host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |
+CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,
+.status_reg_0 = 0xc0,
+.status_reg_1 = 0xc1,
+.sdio_int_mask = 0xff,
+.data_port_mask = 0xffffffff,
+.max_mp_regs = 184,
+.rd_bitmap_l = 0x04,
+.rd_bitmap_u = 0x05,
+.rd_bitmap_1l = 0x06,
+.rd_bitmap_1u = 0x07,
+.wr_bitmap_l = 0x08,
+.wr_bitmap_u = 0x09,
+.wr_bitmap_1l = 0x0a,
+.wr_bitmap_1u = 0x0b,
+.rd_len_p0_l = 0x0c,
+.rd_len_p0_u = 0x0d,
+.card_misc_cfg_reg = 0xcc,
+};
+
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
 .firmware = SD8786_DEFAULT_FW_NAME,
 .reg = &amp;amp;mwifiex_reg_sd87xx,
 .max_ports = 16,
 .mp_agg_pkt_limit = 8,
+.supports_sdio_new_mode = false,
+.has_control_mask = true,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -267,6 +322,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
 .reg = &amp;amp;mwifiex_reg_sd87xx,
 .max_ports = 16,
 .mp_agg_pkt_limit = 8,
+.supports_sdio_new_mode = false,
+.has_control_mask = true,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -274,6 +331,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
 .reg = &amp;amp;mwifiex_reg_sd87xx,
 .max_ports = 16,
 .mp_agg_pkt_limit = 8,
+.supports_sdio_new_mode = false,
+.has_control_mask = true,
+};
+
+static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
+.firmware = SD8897_DEFAULT_FW_NAME,
+.reg = &amp;amp;mwifiex_reg_sd8897,
+.max_ports = 32,
+.mp_agg_pkt_limit = 16,
+.supports_sdio_new_mode = true,
+.has_control_mask = false,
 };
 
 /*
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -302,13 +370,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mp_rx_aggr_port_limit_reached(struct sdio_mmc_card *card)
 u8 tmp;
 
 if (card-&amp;gt;curr_rd_port &amp;lt; card-&amp;gt;mpa_rx.start_port) {
-tmp = card-&amp;gt;mp_agg_pkt_limit;
+if (card-&amp;gt;supports_sdio_new_mode)
+tmp = card-&amp;gt;mp_end_port &amp;gt;&amp;gt; 1;
+else
+tmp = card-&amp;gt;mp_agg_pkt_limit;
 
 if (((card-&amp;gt;max_ports - card-&amp;gt;mpa_rx.start_port) +
     card-&amp;gt;curr_rd_port) &amp;gt;= tmp)
 return true;
 }
 
+if (!card-&amp;gt;supports_sdio_new_mode)
+return false;
+
+if ((card-&amp;gt;curr_rd_port - card-&amp;gt;mpa_rx.start_port) &amp;gt;=
+    (card-&amp;gt;mp_end_port &amp;gt;&amp;gt; 1))
+return true;
+
 return false;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -318,13 +396,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
 u16 tmp;
 
 if (card-&amp;gt;curr_wr_port &amp;lt; card-&amp;gt;mpa_tx.start_port) {
-tmp = card-&amp;gt;mp_agg_pkt_limit;
+if (card-&amp;gt;supports_sdio_new_mode)
+tmp = card-&amp;gt;mp_end_port &amp;gt;&amp;gt; 1;
+else
+tmp = card-&amp;gt;mp_agg_pkt_limit;
 
 if (((card-&amp;gt;max_ports - card-&amp;gt;mpa_tx.start_port) +
     card-&amp;gt;curr_wr_port) &amp;gt;= tmp)
 return true;
 }
 
+if (!card-&amp;gt;supports_sdio_new_mode)
+return false;
+
+if ((card-&amp;gt;curr_wr_port - card-&amp;gt;mpa_tx.start_port) &amp;gt;=
+    (card-&amp;gt;mp_end_port &amp;gt;&amp;gt; 1))
+return true;
+
 return false;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -337,11 +425,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
 if (!card-&amp;gt;mpa_rx.pkt_cnt)
 card-&amp;gt;mpa_rx.start_port = port;
 
-if (card-&amp;gt;mpa_rx.start_port &amp;lt;= port)
-card-&amp;gt;mpa_rx.ports |= 1 &amp;lt;&amp;lt; (card-&amp;gt;mpa_rx.pkt_cnt);
-else
-card-&amp;gt;mpa_rx.ports |= 1 &amp;lt;&amp;lt; (card-&amp;gt;mpa_rx.pkt_cnt + 1);
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:54:58</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108213">
    <title>[PATCH v2 16/17] mwifiex: code rearrangement in multiport aggregation path</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108213</link>
    <description>&lt;pre&gt;From: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

There are some macros defined for multiport aggregation
calculations. As we may need to add some more code to
accomodate new chipsets, we will change them to inline
functions. Also, use dynamic allocation for Rx buffer array.

Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/mwifiex/sdio.c | 17 +++++---
 drivers/net/wireless/mwifiex/sdio.h | 83 +++++++++++++++++++++++--------------
 2 files changed, 64 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 1892e88..4b196dc 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1084,10 +1084,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 if (f_aggr_cur) {
 dev_dbg(adapter-&amp;gt;dev, "info: current packet aggregation\n");
 /* Curr pkt can be aggregated */
-MP_RX_AGGR_SETUP(card, skb, port);
+mp_rx_aggr_setup(card, skb, port);
 
 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
-    MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
+    mp_rx_aggr_port_limit_reached(card)) {
 dev_dbg(adapter-&amp;gt;dev, "info: %s: aggregated packet "
 "limit reached\n", __func__);
 /* No more pkts allowed in Aggr buf, rx it */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1358,7 +1358,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 __func__);
 
 if (MP_TX_AGGR_IN_PROGRESS(card)) {
-if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &amp;amp;&amp;amp;
+if (!mp_tx_aggr_port_limit_reached(card) &amp;amp;&amp;amp;
     MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
 f_precopy_cur_buf = 1;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1371,7 +1371,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 /* No room in Aggr buf, send it */
 f_send_aggr_buf = 1;
 
-if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) ||
+if (mp_tx_aggr_port_limit_reached(card) ||
     !(card-&amp;gt;mp_wr_bitmap &amp;amp;
       (1 &amp;lt;&amp;lt; card-&amp;gt;curr_wr_port)))
 f_send_cur_buf = 1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1410,7 +1410,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
 
 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
-    MP_TX_AGGR_PORT_LIMIT_REACHED(card))
+    mp_tx_aggr_port_limit_reached(card))
 /* No more pkts allowed in Aggr buf, send it */
 f_send_aggr_buf = 1;
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1687,6 +1687,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
 if (!card-&amp;gt;mp_regs)
 return -ENOMEM;
 
+/* Allocate skb pointer buffers */
+card-&amp;gt;mpa_rx.skb_arr = kzalloc((sizeof(void *)) *
+       card-&amp;gt;mp_agg_pkt_limit, GFP_KERNEL);
+card-&amp;gt;mpa_rx.len_arr = kzalloc(sizeof(*card-&amp;gt;mpa_rx.len_arr) *
+       card-&amp;gt;mp_agg_pkt_limit, GFP_KERNEL);
 ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
      SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
      SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1723,6 +1728,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 
 kfree(card-&amp;gt;mp_regs);
+kfree(card-&amp;gt;mpa_rx.skb_arr);
+kfree(card-&amp;gt;mpa_rx.len_arr);
 kfree(card-&amp;gt;mpa_tx.buf);
 kfree(card-&amp;gt;mpa_rx.buf);
 }
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 339608b..597db37 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -46,8 +46,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define CTRL_PORT0
 #define CTRL_PORT_MASK0x0001
 
-#define SDIO_MP_AGGR_DEF_PKT_LIMIT8
-
 #define SDIO_MP_TX_AGGR_DEF_BUF_SIZE        (8192)/* 8K */
 
 /* Multi port RX aggregation buffer size */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -126,12 +124,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define MP_TX_AGGR_PKT_LIMIT_REACHED(a)\
 (a-&amp;gt;mpa_tx.pkt_cnt == a-&amp;gt;mpa_tx.pkt_aggr_limit)
 
-/* SDIO Tx aggregation port limit ? */
-#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a-&amp;gt;curr_wr_port &amp;lt;\
-a-&amp;gt;mpa_tx.start_port) &amp;amp;&amp;amp; (((a-&amp;gt;max_ports -\
-a-&amp;gt;mpa_tx.start_port) + a-&amp;gt;curr_wr_port) &amp;gt;=\
-a-&amp;gt;mp_agg_pkt_limit))
-
 /* Reset SDIO Tx aggregation buffer parameters */
 #define MP_TX_AGGR_BUF_RESET(a) do {\
 a-&amp;gt;mpa_tx.pkt_cnt = 0;\
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -144,12 +136,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define MP_RX_AGGR_PKT_LIMIT_REACHED(a)\
 (a-&amp;gt;mpa_rx.pkt_cnt == a-&amp;gt;mpa_rx.pkt_aggr_limit)
 
-/* SDIO Tx aggregation port limit ? */
-#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a-&amp;gt;curr_rd_port &amp;lt;\
-a-&amp;gt;mpa_rx.start_port) &amp;amp;&amp;amp; (((a-&amp;gt;max_ports -\
-a-&amp;gt;mpa_rx.start_port) + a-&amp;gt;curr_rd_port) &amp;gt;=\
-a-&amp;gt;mp_agg_pkt_limit))
-
 /* SDIO Rx aggregation in progress ? */
 #define MP_RX_AGGR_IN_PROGRESS(a) (a-&amp;gt;mpa_rx.pkt_cnt &amp;gt; 0)
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -157,20 +143,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len)\
 ((a-&amp;gt;mpa_rx.buf_len+rx_len) &amp;lt;= a-&amp;gt;mpa_rx.buf_size)
 
-/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
-#define MP_RX_AGGR_SETUP(a, skb, port) do {\
-a-&amp;gt;mpa_rx.buf_len += skb-&amp;gt;len;\
-if (!a-&amp;gt;mpa_rx.pkt_cnt)\
-a-&amp;gt;mpa_rx.start_port = port;\
-if (a-&amp;gt;mpa_rx.start_port &amp;lt;= port)\
-a-&amp;gt;mpa_rx.ports |= (1&amp;lt;&amp;lt;(a-&amp;gt;mpa_rx.pkt_cnt));\
-else\
-a-&amp;gt;mpa_rx.ports |= (1&amp;lt;&amp;lt;(a-&amp;gt;mpa_rx.pkt_cnt+1));\
-a-&amp;gt;mpa_rx.skb_arr[a-&amp;gt;mpa_rx.pkt_cnt] = skb;\
-a-&amp;gt;mpa_rx.len_arr[a-&amp;gt;mpa_rx.pkt_cnt] = skb-&amp;gt;len;\
-a-&amp;gt;mpa_rx.pkt_cnt++;\
-} while (0)
-
 /* Reset SDIO Rx aggregation buffer parameters */
 #define MP_RX_AGGR_BUF_RESET(a) do {\
 a-&amp;gt;mpa_rx.pkt_cnt = 0;\
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -179,7 +151,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 a-&amp;gt;mpa_rx.start_port = 0;\
 } while (0)
 
-
 /* data structure for SDIO MPA TX */
 struct mwifiex_sdio_mpa_tx {
 /* multiport tx aggregation buffer pointer */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -200,8 +171,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct mwifiex_sdio_mpa_rx {
 u32 ports;
 u16 start_port;
 
-struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
-u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+struct sk_buff **skb_arr;
+u32 *len_arr;
 
 u8 enabled;
 u32 buf_size;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -325,4 +296,54 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int mwifiex_sdio_event_complete(struct mwifiex_adapter *adapter,
 return 0;
 }
 
+static inline bool
+mp_rx_aggr_port_limit_reached(struct sdio_mmc_card *card)
+{
+u8 tmp;
+
+if (card-&amp;gt;curr_rd_port &amp;lt; card-&amp;gt;mpa_rx.start_port) {
+tmp = card-&amp;gt;mp_agg_pkt_limit;
+
+if (((card-&amp;gt;max_ports - card-&amp;gt;mpa_rx.start_port) +
+    card-&amp;gt;curr_rd_port) &amp;gt;= tmp)
+return true;
+}
+
+return false;
+}
+
+static inline bool
+mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
+{
+u16 tmp;
+
+if (card-&amp;gt;curr_wr_port &amp;lt; card-&amp;gt;mpa_tx.start_port) {
+tmp = card-&amp;gt;mp_agg_pkt_limit;
+
+if (((card-&amp;gt;max_ports - card-&amp;gt;mpa_tx.start_port) +
+    card-&amp;gt;curr_wr_port) &amp;gt;= tmp)
+return true;
+}
+
+return false;
+}
+
+/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
+static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
+    struct sk_buff *skb, u8 port)
+{
+card-&amp;gt;mpa_rx.buf_len += skb-&amp;gt;len;
+
+if (!card-&amp;gt;mpa_rx.pkt_cnt)
+card-&amp;gt;mpa_rx.start_port = port;
+
+if (card-&amp;gt;mpa_rx.start_port &amp;lt;= port)
+card-&amp;gt;mpa_rx.ports |= 1 &amp;lt;&amp;lt; (card-&amp;gt;mpa_rx.pkt_cnt);
+else
+card-&amp;gt;mpa_rx.ports |= 1 &amp;lt;&amp;lt; (card-&amp;gt;mpa_rx.pkt_cnt + 1);
+
+card-&amp;gt;mpa_rx.skb_arr[card-&amp;gt;mpa_rx.pkt_cnt] = skb;
+card-&amp;gt;mpa_rx.len_arr[card-&amp;gt;mpa_rx.pkt_cnt] = skb-&amp;gt;len;
+card-&amp;gt;mpa_rx.pkt_cnt++;
+}
 #endif /* _MWIFIEX_SDIO_H */
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:54:51</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108212">
    <title>[PATCH v2 15/17] mwifiex: remove unnecessary macros in sdio.h</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108212</link>
    <description>&lt;pre&gt;From: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

They are not used in the code.

Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/mwifiex/sdio.h | 51 -------------------------------------
 1 file changed, 51 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index e4016d2..339608b 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -66,14 +66,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 /* Host Control Registers : Configuration */
 #define CONFIGURATION_REG0x00
-/* Host Control Registers : Host without Command 53 finish host*/
-#define HOST_TO_CARD_EVENT       (0x1U &amp;lt;&amp;lt; 3)
-/* Host Control Registers : Host without Command 53 finish host */
-#define HOST_WO_CMD53_FINISH_HOST(0x1U &amp;lt;&amp;lt; 2)
 /* Host Control Registers : Host power up */
 #define HOST_POWER_UP(0x1U &amp;lt;&amp;lt; 1)
-/* Host Control Registers : Host power down */
-#define HOST_POWER_DOWN(0x1U &amp;lt;&amp;lt; 0)
 
 /* Host Control Registers : Host interrupt mask */
 #define HOST_INT_MASK_REG0x02
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -93,60 +87,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 /* Host Control Registers : Host interrupt RSR */
 #define HOST_INT_RSR_REG0x01
-/* Host Control Registers : Upload host interrupt RSR */
-#define UP_LD_HOST_INT_RSR(0x1U)
 
 /* Host Control Registers : Host interrupt status */
 #define HOST_INT_STATUS_REG0x28
-/* Host Control Registers : Upload CRC error */
-#define UP_LD_CRC_ERR(0x1U &amp;lt;&amp;lt; 2)
-/* Host Control Registers : Upload restart */
-#define UP_LD_RESTART                   (0x1U &amp;lt;&amp;lt; 1)
-/* Host Control Registers : Download restart */
-#define DN_LD_RESTART                   (0x1U &amp;lt;&amp;lt; 0)
 
 /* Card Control Registers : Card I/O ready */
 #define CARD_IO_READY                   (0x1U &amp;lt;&amp;lt; 3)
-/* Card Control Registers : CIS card ready */
-#define CIS_CARD_RDY                    (0x1U &amp;lt;&amp;lt; 2)
-/* Card Control Registers : Upload card ready */
-#define UP_LD_CARD_RDY                  (0x1U &amp;lt;&amp;lt; 1)
 /* Card Control Registers : Download card ready */
 #define DN_LD_CARD_RDY                  (0x1U &amp;lt;&amp;lt; 0)
 
-/* Card Control Registers : Host interrupt mask register */
-#define HOST_INTERRUPT_MASK_REG         0x34
-/* Card Control Registers : Host power interrupt mask */
-#define HOST_POWER_INT_MASK             (0x1U &amp;lt;&amp;lt; 3)
-/* Card Control Registers : Abort card interrupt mask */
-#define ABORT_CARD_INT_MASK             (0x1U &amp;lt;&amp;lt; 2)
-/* Card Control Registers : Upload card interrupt mask */
-#define UP_LD_CARD_INT_MASK             (0x1U &amp;lt;&amp;lt; 1)
-/* Card Control Registers : Download card interrupt mask */
-#define DN_LD_CARD_INT_MASK             (0x1U &amp;lt;&amp;lt; 0)
-
-/* Card Control Registers : Card interrupt status register */
-#define CARD_INTERRUPT_STATUS_REG       0x38
-/* Card Control Registers : Power up interrupt */
-#define POWER_UP_INT                    (0x1U &amp;lt;&amp;lt; 4)
-/* Card Control Registers : Power down interrupt */
-#define POWER_DOWN_INT                  (0x1U &amp;lt;&amp;lt; 3)
-
-/* Card Control Registers : Card interrupt RSR register */
-#define CARD_INTERRUPT_RSR_REG          0x3c
-/* Card Control Registers : Power up RSR */
-#define POWER_UP_RSR                    (0x1U &amp;lt;&amp;lt; 4)
-/* Card Control Registers : Power down RSR */
-#define POWER_DOWN_RSR                  (0x1U &amp;lt;&amp;lt; 3)
-
-/* Host F1 card ready */
-#define HOST_F1_CARD_RDY0x0020
-
-/* Rx length register */
-#define CARD_RX_LEN_REG0x62
-/* Rx unit register */
-#define CARD_RX_UNIT_REG0x63
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:54:42</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108211">
    <title>[PATCH v2 14/17] mwifiex: define a macro for MPA base address</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108211</link>
    <description>&lt;pre&gt;From: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

As Multiple-Port Aggregation base address value is fixed, we can
have a macro for it.

Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/mwifiex/sdio.c | 4 ++--
 drivers/net/wireless/mwifiex/sdio.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 99a508b..1892e88 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1100,7 +1100,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 dev_dbg(adapter-&amp;gt;dev, "info: do_rx_aggr: num of packets: %d\n",
 card-&amp;gt;mpa_rx.pkt_cnt);
 
-mport = (adapter-&amp;gt;ioport | 0x1000 |
+mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
  (card-&amp;gt;mpa_rx.ports &amp;lt;&amp;lt; 4)) + card-&amp;gt;mpa_rx.start_port;
 
 if (mwifiex_read_data_sync(adapter, card-&amp;gt;mpa_rx.buf,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1419,7 +1419,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 dev_dbg(adapter-&amp;gt;dev, "data: %s: send aggr buffer: %d %d\n",
 __func__,
 card-&amp;gt;mpa_tx.start_port, card-&amp;gt;mpa_tx.ports);
-mport = (adapter-&amp;gt;ioport | 0x1000 |
+mport = (adapter-&amp;gt;ioport | SDIO_MPA_ADDR_BASE |
  (card-&amp;gt;mpa_tx.ports &amp;lt;&amp;lt; 4)) + card-&amp;gt;mpa_tx.start_port;
 ret = mwifiex_write_data_to_card(adapter, card-&amp;gt;mpa_tx.buf,
  card-&amp;gt;mpa_tx.buf_len, mport);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 0d931f7..e4016d2 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -42,6 +42,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #define MWIFIEX_SDIO_BYTE_MODE_MASK0x80000000
 
+#define SDIO_MPA_ADDR_BASE0x1000
 #define CTRL_PORT0
 #define CTRL_PORT_MASK0x0001
 
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:54:34</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108206">
    <title>[PATCH v2 13/17] mwifiex: do port calculations separately</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108206</link>
    <description>&lt;pre&gt;From: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

This patch rearranges the code for better readability

Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Yogesh Ashok Powar &amp;lt;yogeshp-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
v2: fix cmd53 single port address overwriting

 drivers/net/wireless/mwifiex/sdio.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index a18a5b4..99a508b 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -539,7 +539,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
  * increased (provided it does not reach the maximum limit, in which
  * case it is reset to 1)
  */
-static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
+static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 u32 wr_bitmap = card-&amp;gt;mp_wr_bitmap;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1027,7 +1027,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 s32 f_aggr_cur = 0;
 struct sk_buff *skb_deaggr;
 u32 pind;
-u32 pkt_len, pkt_type = 0;
+u32 pkt_len, pkt_type, mport;
 u8 *curr_ptr;
 u32 rx_len = skb-&amp;gt;len;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1100,11 +1100,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 dev_dbg(adapter-&amp;gt;dev, "info: do_rx_aggr: num of packets: %d\n",
 card-&amp;gt;mpa_rx.pkt_cnt);
 
+mport = (adapter-&amp;gt;ioport | 0x1000 |
+ (card-&amp;gt;mpa_rx.ports &amp;lt;&amp;lt; 4)) + card-&amp;gt;mpa_rx.start_port;
+
 if (mwifiex_read_data_sync(adapter, card-&amp;gt;mpa_rx.buf,
-   card-&amp;gt;mpa_rx.buf_len,
-   (adapter-&amp;gt;ioport | 0x1000 |
-    (card-&amp;gt;mpa_rx.ports &amp;lt;&amp;lt; 4)) +
-   card-&amp;gt;mpa_rx.start_port, 1))
+   card-&amp;gt;mpa_rx.buf_len, mport, 1))
 goto error;
 
 curr_ptr = card-&amp;gt;mpa_rx.buf;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1333,7 +1333,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
  * and return.
  */
 static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
-u8 *payload, u32 pkt_len, u8 port,
+u8 *payload, u32 pkt_len, u32 port,
 u32 next_pkt_len)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1342,6 +1342,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 s32 f_send_cur_buf = 0;
 s32 f_precopy_cur_buf = 0;
 s32 f_postcopy_cur_buf = 0;
+u32 mport;
 
 if ((!card-&amp;gt;mpa_tx.enabled) || (port == CTRL_PORT)) {
 dev_dbg(adapter-&amp;gt;dev, "info: %s: tx aggregation disabled\n",
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1418,11 +1419,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 dev_dbg(adapter-&amp;gt;dev, "data: %s: send aggr buffer: %d %d\n",
 __func__,
 card-&amp;gt;mpa_tx.start_port, card-&amp;gt;mpa_tx.ports);
+mport = (adapter-&amp;gt;ioport | 0x1000 |
+ (card-&amp;gt;mpa_tx.ports &amp;lt;&amp;lt; 4)) + card-&amp;gt;mpa_tx.start_port;
 ret = mwifiex_write_data_to_card(adapter, card-&amp;gt;mpa_tx.buf,
- card-&amp;gt;mpa_tx.buf_len,
- (adapter-&amp;gt;ioport | 0x1000 |
- (card-&amp;gt;mpa_tx.ports &amp;lt;&amp;lt; 4)) +
-  card-&amp;gt;mpa_tx.start_port);
+ card-&amp;gt;mpa_tx.buf_len, mport);
 
 MP_TX_AGGR_BUF_RESET(card);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1462,7 +1462,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
 int ret;
 u32 buf_block_len;
 u32 blk_size;
-u8 port = CTRL_PORT;
+u32 port = CTRL_PORT;
 u8 *payload = (u8 *)skb-&amp;gt;data;
 u32 pkt_len = skb-&amp;gt;len;
 
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:54:23</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108205">
    <title>[PATCH v2 11/17] mwifiex: replace unnecessary u32 variables with u8 in sdio.c</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108205</link>
    <description>&lt;pre&gt;From: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

Some u32 variables in sdio.c are used to store/pass u8 values.
Replace them with u8 variables.

Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/mwifiex/sdio.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 022e9fd..e4357a6 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -294,13 +294,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct sdio_driver mwifiex_sdio = {
  * This function writes data into SDIO card register.
  */
 static int
-mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
+mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 int ret = -1;
 
 sdio_claim_host(card-&amp;gt;func);
-sdio_writeb(card-&amp;gt;func, (u8) data, reg, &amp;amp;ret);
+sdio_writeb(card-&amp;gt;func, data, reg, &amp;amp;ret);
 sdio_release_host(card-&amp;gt;func);
 
 return ret;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -310,7 +310,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
  * This function reads data from SDIO card register.
  */
 static int
-mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
+mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 int ret = -1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -421,7 +421,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
  */
 static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
 {
-u32 reg;
+u8 reg;
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 
 adapter-&amp;gt;ioport = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -580,7 +580,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 u32 tries;
-u32 cs;
+u8 cs;
 
 for (tries = 0; tries &amp;lt; MAX_POLL_TRIES; tries++) {
 if (mwifiex_read_reg(adapter, card-&amp;gt;reg-&amp;gt;poll_reg, &amp;amp;cs))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -604,7 +604,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 const struct mwifiex_sdio_card_reg *reg = card-&amp;gt;reg;
-u32 fws0, fws1;
+u8 fws0, fws1;
 
 if (mwifiex_read_reg(adapter, reg-&amp;gt;status_reg_0, &amp;amp;fws0))
 return -1;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -625,14 +625,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
  */
 static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
 {
-u32 host_int_mask;
+u8 host_int_mask, host_int_disable = HOST_INT_DISABLE;
 
 /* Read back the host_int_mask register */
 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &amp;amp;host_int_mask))
 return -1;
 
 /* Update with the mask and write back to the register */
-host_int_mask &amp;amp;= ~HOST_INT_DISABLE;
+host_int_mask &amp;amp;= ~host_int_disable;
 
 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
 dev_err(adapter-&amp;gt;dev, "disable host interrupt failed\n");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -712,7 +712,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 u8 *firmware = fw-&amp;gt;fw_buf;
 u32 firmware_len = fw-&amp;gt;fw_len;
 u32 offset = 0;
-u32 base0, base1;
+u8 base0, base1;
 u8 *fwbuf;
 u16 len = 0;
 u32 txlen, tx_blocks = 0, tries;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -854,7 +854,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 int ret = 0;
 u16 firmware_stat;
 u32 tries;
-u32 winner_status;
+u8 winner_status;
 
 /* Wait for firmware initialization event */
 for (tries = 0; tries &amp;lt; poll_num; tries++) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -889,7 +889,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
 {
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
-u32 sdio_ireg;
+u8 sdio_ireg;
 unsigned long flags;
 
 if (mwifiex_read_data_sync(adapter, card-&amp;gt;mp_regs,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1284,7 +1284,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 
 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
       port)) {
-u32 cr = 0;
+u8 cr = 0;
 
 dev_err(adapter-&amp;gt;dev, "card_to_host_mpa failed:"
 " int status=%#x\n", sdio_ireg);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1644,7 +1644,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
 struct sdio_mmc_card *card = adapter-&amp;gt;card;
 const struct mwifiex_sdio_card_reg *reg = card-&amp;gt;reg;
 int ret;
-u32 sdio_ireg;
+u8 sdio_ireg;
 
 /*
  * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:53:42</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108204">
    <title>[PATCH v2 12/17] mwifiex: code rearrangement in mwifiex_get_rd_port()</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108204</link>
    <description>&lt;pre&gt;From: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

Get rid of 'if else' usage by returning in 'if' block.
This improves readability by removing indentations.

Signed-off-by: Amitkumar Karwar &amp;lt;akarwar-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
Signed-off-by: Bing Zhao &amp;lt;bzhao-eYqpPyKDWXRBDgjK7y7TUQ&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/mwifiex/sdio.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index e4357a6..a18a5b4 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -512,22 +512,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 *port = CTRL_PORT;
 dev_dbg(adapter-&amp;gt;dev, "data: port=%d mp_rd_bitmap=0x%08x\n",
 *port, card-&amp;gt;mp_rd_bitmap);
-} else {
-if (card-&amp;gt;mp_rd_bitmap &amp;amp; (1 &amp;lt;&amp;lt; card-&amp;gt;curr_rd_port)) {
-card-&amp;gt;mp_rd_bitmap &amp;amp;= (u32)
-(~(1 &amp;lt;&amp;lt; card-&amp;gt;curr_rd_port));
-*port = card-&amp;gt;curr_rd_port;
+return 0;
+}
 
-if (++card-&amp;gt;curr_rd_port == card-&amp;gt;max_ports)
-card-&amp;gt;curr_rd_port = reg-&amp;gt;start_rd_port;
-} else {
-return -1;
-}
+if (!(card-&amp;gt;mp_rd_bitmap &amp;amp; (1 &amp;lt;&amp;lt; card-&amp;gt;curr_rd_port)))
+return -1;
+
+/* We are now handling the SDIO data ports */
+card-&amp;gt;mp_rd_bitmap &amp;amp;= (u32)(~(1 &amp;lt;&amp;lt; card-&amp;gt;curr_rd_port));
+*port = card-&amp;gt;curr_rd_port;
+
+if (++card-&amp;gt;curr_rd_port == card-&amp;gt;max_ports)
+card-&amp;gt;curr_rd_port = reg-&amp;gt;start_rd_port;
+
+dev_dbg(adapter-&amp;gt;dev,
+"data: port=%d mp_rd_bitmap=0x%08x -&amp;gt; 0x%08x\n",
+*port, rd_bitmap, card-&amp;gt;mp_rd_bitmap);
 
-dev_dbg(adapter-&amp;gt;dev,
-"data: port=%d mp_rd_bitmap=0x%08x -&amp;gt; 0x%08x\n",
-*port, rd_bitmap, card-&amp;gt;mp_rd_bitmap);
-}
 return 0;
 }
 
&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:53:56</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108198">
    <title>[PATCH v2 00/17] mwifiex updates for 3.11</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108198</link>
    <description>&lt;pre&gt;This series adds support for new chipset SD8897, calibration data
downloading, del_station handler, as well as some random cleanups
and updates.

v2: fix cmd53 single port address overwriting
    (13/17 and 17/17 only, no change for other pathes)


Amitkumar Karwar (12):
  mwifiex: rename mwifiex_free_adapter() routine in init.c
  mwifiex: scan delay timer cleanup in unload path
  mwifiex: remove global user_scan_cfg variable
  mwifiex: add calibration data download feature
  mwifiex: use u32 variables for SDIO read/write port bitmap
  mwifiex: store SDIO chip specific information in separate structure
  mwifiex: replace unnecessary u32 variables with u8 in sdio.c
  mwifiex: code rearrangement in mwifiex_get_rd_port()
  mwifiex: do port calculations separately
  mwifiex: define a macro for MPA base address
  mwifiex: remove unnecessary macros in sdio.h
  mwifiex: code rearrangement in multiport aggregation path

Avinash Patil (3):
  mwifiex: avoid deleting all stations during mwifiex_del_sta_entry()
  mwifiex: add del_station handler
  mwifiex: replace spin_lock_irqsave with spin_lock and fix warn_on

Bing Zhao (1):
  mwifiex: abort remaining scan commands when association started

Yogesh Ashok Powar (1):
  mwifiex: add support for Marvell SD8897 chipset

 drivers/net/wireless/mwifiex/Kconfig       |   4 +-
 drivers/net/wireless/mwifiex/cfg80211.c    |  77 ++++-
 drivers/net/wireless/mwifiex/cmdevt.c      |   1 +
 drivers/net/wireless/mwifiex/fw.h          |  17 ++
 drivers/net/wireless/mwifiex/init.c        |  53 ++--
 drivers/net/wireless/mwifiex/main.c        |  14 +
 drivers/net/wireless/mwifiex/main.h        |   5 +-
 drivers/net/wireless/mwifiex/scan.c        |  23 +-
 drivers/net/wireless/mwifiex/sdio.c        | 463 ++++++++++++++++++++---------
 drivers/net/wireless/mwifiex/sdio.h        | 340 ++++++++++++++-------
 drivers/net/wireless/mwifiex/sta_cmd.c     |  62 ++++
 drivers/net/wireless/mwifiex/sta_cmdresp.c |  17 ++
 drivers/net/wireless/mwifiex/uap_cmd.c     |  21 ++
 drivers/net/wireless/mwifiex/uap_event.c   |  25 +-
 14 files changed, 808 insertions(+), 314 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Bing Zhao</dc:creator>
    <dc:date>2013-05-18T00:50:17</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108189">
    <title>[RFC 0/2] cfg80211: SME refactoring</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108189</link>
    <description>&lt;pre&gt;After the cleanups, this is really what I was after, separating
the cfg80211 internal software SME from the SME event processing
that is needed for all three SMEs (userspace, cfg80211, driver.)

I have only lightly tested it so far, any help would be welcome :-)

johannes
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA&amp;lt; at &amp;gt;public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Johannes Berg</dc:creator>
    <dc:date>2013-05-17T14:25:41</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108185">
    <title>[PATCH 3.10] mac80211: fix direct probe auth</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108185</link>
    <description>&lt;pre&gt;We send direct probe to broadcast address, as some APs do not respond to
unicast PROBE frames when unassociated. Broadcast frames are not acked,
so we can not use that for trigger MLME state machine, but we need to
use old timeout mechanism.

This fixes authentication timed out like below:

[ 1024.671974] wlan6: authenticate with 54:e6:fc:98:63:fe
[ 1024.694125] wlan6: direct probe to 54:e6:fc:98:63:fe (try 1/3)
[ 1024.695450] wlan6: direct probe to 54:e6:fc:98:63:fe (try 2/3)
[ 1024.700586] wlan6: send auth to 54:e6:fc:98:63:fe (try 3/3)
[ 1024.701441] wlan6: authentication with 54:e6:fc:98:63:fe timed out

With fix, we have:

[ 4524.198978] wlan6: authenticate with 54:e6:fc:98:63:fe
[ 4524.220692] wlan6: direct probe to 54:e6:fc:98:63:fe (try 1/3)
[ 4524.421784] wlan6: send auth to 54:e6:fc:98:63:fe (try 2/3)
[ 4524.423272] wlan6: authenticated
[ 4524.423811] wlan6: associate with 54:e6:fc:98:63:fe (try 1/3)
[ 4524.427492] wlan6: RX AssocResp from 54:e6:fc:98:63:fe (capab=0x431 status=0 aid=1)

Cc: stable-u79uwXL29TY76Z2rM5mHXA&amp;lt; at &amp;gt;public.gmane.org # 3.9
Signed-off-by: Stanislaw Gruszka &amp;lt;sgruszka-H+wXaHxf7aLQT0dZR+AlfA&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 net/mac80211/mlme.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 346ad4c..0a60f40 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3182,10 +3182,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
 if (WARN_ON_ONCE(!auth_data))
 return -EINVAL;
 
-if (local-&amp;gt;hw.flags &amp;amp; IEEE80211_HW_REPORTS_TX_ACK_STATUS)
-tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
-   IEEE80211_TX_INTFL_MLME_CONN_TX;
-
 auth_data-&amp;gt;tries++;
 
 if (auth_data-&amp;gt;tries &amp;gt; IEEE80211_AUTH_MAX_TRIES) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3219,6 +3215,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
 auth_data-&amp;gt;expected_transaction = trans;
 }
 
+if (local-&amp;gt;hw.flags &amp;amp; IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
+   IEEE80211_TX_INTFL_MLME_CONN_TX;
+
 ieee80211_send_auth(sdata, trans, auth_data-&amp;gt;algorithm, status,
     auth_data-&amp;gt;data, auth_data-&amp;gt;data_len,
     auth_data-&amp;gt;bss-&amp;gt;bssid,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -3242,12 +3242,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
  * will not answer to direct packet in unassociated state.
  */
 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
- NULL, 0, (u32) -1, true, tx_flags,
+ NULL, 0, (u32) -1, true, 0,
  auth_data-&amp;gt;bss-&amp;gt;channel, false);
 rcu_read_unlock();
 }
 
-if (!(local-&amp;gt;hw.flags &amp;amp; IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
+if (tx_flags == 0) {
 auth_data-&amp;gt;timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
 ifmgd-&amp;gt;auth_data-&amp;gt;timeout_started = true;
 run_again(ifmgd, auth_data-&amp;gt;timeout);
&lt;/pre&gt;</description>
    <dc:creator>Stanislaw Gruszka</dc:creator>
    <dc:date>2013-05-17T11:43:04</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108183">
    <title>[PATCH v2 3.10 1/3] ath9k: fix aggregation stop/flush handling</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108183</link>
    <description>&lt;pre&gt;When aggregation stop is requested, don't run the mac80211 aggregation
stop callback yet, while the session is still blocked.
Also, when aggregation flush is requested, don't run the callback at all.

Signed-off-by: Felix Fietkau &amp;lt;nbd-p3rKhJxN3npAfugRpC6u6w&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  4 ++-
 drivers/net/wireless/ath/ath9k/main.c  |  8 +++--
 drivers/net/wireless/ath/ath9k/xmit.c  | 61 ++++++++++++++++++++++------------
 3 files changed, 48 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8a1888d..366002f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -254,6 +254,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ath_atx_tid {
 int sched;
 int paused;
 u8 state;
+bool stop_cb;
 };
 
 struct ath_node {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -351,7 +352,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_tasklet(struct ath_softc *sc);
 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);
+bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
+      bool flush);
 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);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a18414b..2382d12 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1687,6 +1687,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ath9k_ampdu_action(struct ieee80211_hw *hw,
       u16 tid, u16 *ssn, u8 buf_size)
 {
 struct ath_softc *sc = hw-&amp;gt;priv;
+bool flush = false;
 int ret = 0;
 
 local_bh_disable();
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1703,12 +1704,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 ieee80211_start_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
 ath9k_ps_restore(sc);
 break;
-case IEEE80211_AMPDU_TX_STOP_CONT:
 case IEEE80211_AMPDU_TX_STOP_FLUSH:
 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+flush = true;
+case IEEE80211_AMPDU_TX_STOP_CONT:
 ath9k_ps_wakeup(sc);
-ath_tx_aggr_stop(sc, sta, tid);
-ieee80211_stop_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
+if (ath_tx_aggr_stop(sc, sta, tid, flush))
+ieee80211_stop_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
 ath9k_ps_restore(sc);
 break;
 case IEEE80211_AMPDU_TX_OPERATIONAL:
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index eab0fcb..a47bf69 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -164,7 +164,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
        ARRAY_SIZE(bf-&amp;gt;rates));
 }
 
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
+tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
+if (!tid-&amp;gt;stop_cb)
+return;
+
+ieee80211_start_tx_ba_cb_irqsafe(tid-&amp;gt;an-&amp;gt;vif, tid-&amp;gt;an-&amp;gt;sta-&amp;gt;addr,
+ tid-&amp;gt;tidno);
+tid-&amp;gt;stop_cb = false;
+}
+
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
+     bool flush_packets)
 {
 struct ath_txq *txq = tid-&amp;gt;ac-&amp;gt;txq;
 struct sk_buff *skb;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -181,16 +194,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 while ((skb = __skb_dequeue(&amp;amp;tid-&amp;gt;buf_q))) {
 fi = get_frame_info(skb);
 bf = fi-&amp;gt;bf;
+if (!bf &amp;amp;&amp;amp; !flush_packets)
+bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
 if (!bf) {
-bf = ath_tx_setup_buffer(sc, txq, tid, skb);
-if (!bf) {
-ieee80211_free_txskb(sc-&amp;gt;hw, skb);
-continue;
-}
+ieee80211_free_txskb(sc-&amp;gt;hw, skb);
+continue;
 }
 
-if (fi-&amp;gt;retries) {
+if (fi-&amp;gt;retries || flush_packets) {
 list_add_tail(&amp;amp;bf-&amp;gt;list, &amp;amp;bf_head);
 ath_tx_update_baw(sc, tid, bf-&amp;gt;bf_state.seqno);
 ath_tx_complete_buf(sc, bf, txq, &amp;amp;bf_head, &amp;amp;ts, 0);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -201,12 +213,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 }
 }
 
-if (tid-&amp;gt;baw_head == tid-&amp;gt;baw_tail) {
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
-}
+if (tid-&amp;gt;baw_head == tid-&amp;gt;baw_tail)
+ath_tx_clear_tid(sc, tid);
 
-if (sendbar) {
+if (sendbar &amp;amp;&amp;amp; !flush_packets) {
 ath_txq_unlock(sc, txq);
 ath_send_bar(tid, tid-&amp;gt;seq_start);
 ath_txq_lock(sc, txq);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -602,7 +612,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 }
 
 if (tid-&amp;gt;state &amp;amp; AGGR_CLEANUP)
-ath_tx_flush_tid(sc, tid);
+ath_tx_flush_tid(sc, tid, false);
 
 rcu_read_unlock();
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1256,18 +1266,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
 return 0;
 }
 
-void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
+      bool flush)
 {
 struct ath_node *an = (struct ath_node *)sta-&amp;gt;drv_priv;
 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
 struct ath_txq *txq = txtid-&amp;gt;ac-&amp;gt;txq;
+bool ret = !flush;
+
+if (flush)
+txtid-&amp;gt;stop_cb = false;
 
 if (txtid-&amp;gt;state &amp;amp; AGGR_CLEANUP)
-return;
+return false;
 
 if (!(txtid-&amp;gt;state &amp;amp; AGGR_ADDBA_COMPLETE)) {
 txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
-return;
+return ret;
 }
 
 ath_txq_lock(sc, txq);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1279,13 +1294,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
  * TID can only be reused after all in-progress subframes have been
  * completed.
  */
-if (txtid-&amp;gt;baw_head != txtid-&amp;gt;baw_tail)
+if (txtid-&amp;gt;baw_head != txtid-&amp;gt;baw_tail) {
 txtid-&amp;gt;state |= AGGR_CLEANUP;
-else
+ret = false;
+txtid-&amp;gt;stop_cb = !flush;
+} else {
 txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
+}
 
-ath_tx_flush_tid(sc, txtid);
+ath_tx_flush_tid(sc, txtid, flush);
 ath_txq_unlock_complete(sc, txq);
+return ret;
 }
 
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2415,6 +2434,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 tid-&amp;gt;ac = &amp;amp;an-&amp;gt;ac[acno];
 tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
 tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
+tid-&amp;gt;stop_cb = false;
 }
 
 for (acno = 0, ac = &amp;amp;an-&amp;gt;ac[acno];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2451,8 +2471,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 }
 
 ath_tid_drain(sc, txq, tid);
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
+ath_tx_clear_tid(sc, tid);
 
 ath_txq_unlock(sc, txq);
 }
&lt;/pre&gt;</description>
    <dc:creator>Felix Fietkau</dc:creator>
    <dc:date>2013-05-17T10:58:24</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108179">
    <title>[PATCH 3.10 1/3] ath9k: fix aggregation stop/flush handling</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108179</link>
    <description>&lt;pre&gt;When aggregation stop is requested, don't run the mac80211 aggregation
stop callback yet, while the session is still blocked.
Also, when aggregation flush is requested, don't run the callback at all.

Signed-off-by: Felix Fietkau &amp;lt;nbd-p3rKhJxN3npAfugRpC6u6w&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  4 ++-
 drivers/net/wireless/ath/ath9k/main.c  |  9 +++--
 drivers/net/wireless/ath/ath9k/xmit.c  | 61 ++++++++++++++++++++++------------
 3 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8a1888d..366002f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -254,6 +254,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct ath_atx_tid {
 int sched;
 int paused;
 u8 state;
+bool stop_cb;
 };
 
 struct ath_node {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -351,7 +352,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_tasklet(struct ath_softc *sc);
 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);
+bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
+      bool flush);
 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);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a18414b..690a5d6 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1687,6 +1687,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ath9k_ampdu_action(struct ieee80211_hw *hw,
       u16 tid, u16 *ssn, u8 buf_size)
 {
 struct ath_softc *sc = hw-&amp;gt;priv;
+bool flush = false, cb;
 int ret = 0;
 
 local_bh_disable();
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1703,12 +1704,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 ieee80211_start_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
 ath9k_ps_restore(sc);
 break;
-case IEEE80211_AMPDU_TX_STOP_CONT:
 case IEEE80211_AMPDU_TX_STOP_FLUSH:
 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+flush = true;
+case IEEE80211_AMPDU_TX_STOP_CONT:
 ath9k_ps_wakeup(sc);
-ath_tx_aggr_stop(sc, sta, tid);
-ieee80211_stop_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
+cb = ath_tx_aggr_stop(sc, sta, tid, flush);
+if (cb)
+ieee80211_stop_tx_ba_cb_irqsafe(vif, sta-&amp;gt;addr, tid);
 ath9k_ps_restore(sc);
 break;
 case IEEE80211_AMPDU_TX_OPERATIONAL:
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index eab0fcb..a47bf69 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -164,7 +164,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
        ARRAY_SIZE(bf-&amp;gt;rates));
 }
 
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
+tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
+if (!tid-&amp;gt;stop_cb)
+return;
+
+ieee80211_start_tx_ba_cb_irqsafe(tid-&amp;gt;an-&amp;gt;vif, tid-&amp;gt;an-&amp;gt;sta-&amp;gt;addr,
+ tid-&amp;gt;tidno);
+tid-&amp;gt;stop_cb = false;
+}
+
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
+     bool flush_packets)
 {
 struct ath_txq *txq = tid-&amp;gt;ac-&amp;gt;txq;
 struct sk_buff *skb;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -181,16 +194,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 while ((skb = __skb_dequeue(&amp;amp;tid-&amp;gt;buf_q))) {
 fi = get_frame_info(skb);
 bf = fi-&amp;gt;bf;
+if (!bf &amp;amp;&amp;amp; !flush_packets)
+bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
 if (!bf) {
-bf = ath_tx_setup_buffer(sc, txq, tid, skb);
-if (!bf) {
-ieee80211_free_txskb(sc-&amp;gt;hw, skb);
-continue;
-}
+ieee80211_free_txskb(sc-&amp;gt;hw, skb);
+continue;
 }
 
-if (fi-&amp;gt;retries) {
+if (fi-&amp;gt;retries || flush_packets) {
 list_add_tail(&amp;amp;bf-&amp;gt;list, &amp;amp;bf_head);
 ath_tx_update_baw(sc, tid, bf-&amp;gt;bf_state.seqno);
 ath_tx_complete_buf(sc, bf, txq, &amp;amp;bf_head, &amp;amp;ts, 0);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -201,12 +213,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 }
 }
 
-if (tid-&amp;gt;baw_head == tid-&amp;gt;baw_tail) {
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
-}
+if (tid-&amp;gt;baw_head == tid-&amp;gt;baw_tail)
+ath_tx_clear_tid(sc, tid);
 
-if (sendbar) {
+if (sendbar &amp;amp;&amp;amp; !flush_packets) {
 ath_txq_unlock(sc, txq);
 ath_send_bar(tid, tid-&amp;gt;seq_start);
 ath_txq_lock(sc, txq);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -602,7 +612,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 }
 
 if (tid-&amp;gt;state &amp;amp; AGGR_CLEANUP)
-ath_tx_flush_tid(sc, tid);
+ath_tx_flush_tid(sc, tid, false);
 
 rcu_read_unlock();
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1256,18 +1266,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
 return 0;
 }
 
-void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
+      bool flush)
 {
 struct ath_node *an = (struct ath_node *)sta-&amp;gt;drv_priv;
 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
 struct ath_txq *txq = txtid-&amp;gt;ac-&amp;gt;txq;
+bool ret = !flush;
+
+if (flush)
+txtid-&amp;gt;stop_cb = false;
 
 if (txtid-&amp;gt;state &amp;amp; AGGR_CLEANUP)
-return;
+return false;
 
 if (!(txtid-&amp;gt;state &amp;amp; AGGR_ADDBA_COMPLETE)) {
 txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
-return;
+return ret;
 }
 
 ath_txq_lock(sc, txq);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1279,13 +1294,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
  * TID can only be reused after all in-progress subframes have been
  * completed.
  */
-if (txtid-&amp;gt;baw_head != txtid-&amp;gt;baw_tail)
+if (txtid-&amp;gt;baw_head != txtid-&amp;gt;baw_tail) {
 txtid-&amp;gt;state |= AGGR_CLEANUP;
-else
+ret = false;
+txtid-&amp;gt;stop_cb = !flush;
+} else {
 txtid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
+}
 
-ath_tx_flush_tid(sc, txtid);
+ath_tx_flush_tid(sc, txtid, flush);
 ath_txq_unlock_complete(sc, txq);
+return ret;
 }
 
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2415,6 +2434,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 tid-&amp;gt;ac = &amp;amp;an-&amp;gt;ac[acno];
 tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
 tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_PROGRESS;
+tid-&amp;gt;stop_cb = false;
 }
 
 for (acno = 0, ac = &amp;amp;an-&amp;gt;ac[acno];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2451,8 +2471,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 }
 
 ath_tid_drain(sc, txq, tid);
-tid-&amp;gt;state &amp;amp;= ~AGGR_ADDBA_COMPLETE;
-tid-&amp;gt;state &amp;amp;= ~AGGR_CLEANUP;
+ath_tx_clear_tid(sc, tid);
 
 ath_txq_unlock(sc, txq);
 }
&lt;/pre&gt;</description>
    <dc:creator>Felix Fietkau</dc:creator>
    <dc:date>2013-05-17T09:36:21</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108175">
    <title>AR9227: Can't set master mode</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108175</link>
    <description>&lt;pre&gt;Hi,

first: Please CC me as I'm not subscribed to the list.

I have the following wireless card: 04:02.0 Network controller:
Atheros Communications Inc. AR9227 Wireless Network Adapter (rev 01)

I can't set it to master mode, but this card should support it:

server ~ # iwconfig wlp4s2
wlp4s2    IEEE 802.11bgn  ESSID:off/any
          Mode:Managed  Access Point: Not-Associated   Tx-Power=19 dBm
          Retry  long limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off

server ~ # iwconfig wlp4s2 mode Master
Error for wireless request "Set Mode" (8B06) :
    SET failed on device wlp4s2 ; Invalid argument.


My kernel config should be correct:

server linux # cat .config | grep ATH9K
CONFIG_ATH9K_HW=y
CONFIG_ATH9K_COMMON=y
# CONFIG_ATH9K_BTCOEX_SUPPORT is not set
CONFIG_ATH9K=y
CONFIG_ATH9K_PCI=y
# CONFIG_ATH9K_AHB is not set
# CONFIG_ATH9K_DEBUGFS is not set
CONFIG_ATH9K_RATE_CONTROL=y
# CONFIG_ATH9K_HTC is not set

server linux # cat .config | grep MAC80211
CONFIG_MAC80211=y
CONFIG_MAC80211_HAS_RC=y
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MAC80211_RC_MINSTREL_HT=y
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
# CONFIG_MAC80211_MESH is not set
CONFIG_MAC80211_LEDS=y
# CONFIG_MAC80211_DEBUGFS is not set
# CONFIG_MAC80211_MESSAGE_TRACING is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
# CONFIG_MAC80211_HWSIM is not set


I can scan for wireless networks and probably also connect to them
(never tested because this is not an use case for me).

Any ideas? Thanks in advance!

Kind regards,
Felix
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA&amp;lt; at &amp;gt;public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Felix Blanke</dc:creator>
    <dc:date>2013-05-17T08:54:50</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108168">
    <title>[PATCH] regulatory: enable channels 52-64 and 100-144 for world roaming</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108168</link>
    <description>&lt;pre&gt;From: Johannes Berg &amp;lt;johannes.berg-ral2JQCrhuEAvxtiuMwx3w&amp;lt; at &amp;gt;public.gmane.org&amp;gt;

If allowed in a country, these channels typically require DFS
so mark them as such. Channel 144 is a bit special, it's coming
into use now to allow more VHT 80 channels, but world roaming
with passive scanning is acceptable anyway. It seems fairly
unlikely that it'll be used as the control channel for a VHT
AP, but it needs to be present to allow a full VHT connection
to an AP that uses it as one of the secondary channels.

Also enable VHT 160 on these channels, and also for channels
36-48 to be able to use VHT 160 there.

Signed-off-by: Johannes Berg &amp;lt;johannes.berg-ral2JQCrhuEAvxtiuMwx3w&amp;lt; at &amp;gt;public.gmane.org&amp;gt;
---
 net/wireless/reg.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cc35fba..e713051 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -184,11 +184,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const struct ieee80211_regdomain world_regdom = {
 NL80211_RRF_NO_IBSS |
 NL80211_RRF_NO_OFDM),
 /* IEEE 802.11a, channel 36..48 */
-REG_RULE(5180-10, 5240+10, 80, 6, 20,
+REG_RULE(5180-10, 5240+10, 160, 6, 20,
                         NL80211_RRF_PASSIVE_SCAN |
                         NL80211_RRF_NO_IBSS),
 
-/* NB: 5260 MHz - 5700 MHz requires DFS */
+/* IEEE 802.11a, channel 52..64 - DFS required */
+REG_RULE(5260-10, 5320+10, 160, 6, 20,
+NL80211_RRF_PASSIVE_SCAN |
+NL80211_RRF_NO_IBSS |
+NL80211_RRF_DFS),
+
+/* IEEE 802.11a, channel 100..144 - DFS required */
+REG_RULE(5500-10, 5720+10, 160, 6, 20,
+NL80211_RRF_PASSIVE_SCAN |
+NL80211_RRF_NO_IBSS |
+NL80211_RRF_DFS),
 
 /* IEEE 802.11a, channel 149..165 */
 REG_RULE(5745-10, 5825+10, 80, 6, 20,
&lt;/pre&gt;</description>
    <dc:creator>Johannes Berg</dc:creator>
    <dc:date>2013-05-16T21:06:52</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108158">
    <title>[PATCH 0/9] cfg80211 spring cleaning</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108158</link>
    <description>&lt;pre&gt;Motivated by the bugs Ben Greear keeps reporting, I decided to do
some locking and general cleanup in cfg80211.

This is the first series. I'm working on more changes to actually
separate the SME and MLME code much better to avoid such strange
issues as we had before with their state (sme_state and current_bss)
getting confused, but that'll take a bit longer.

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA&amp;lt; at &amp;gt;public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Johannes Berg</dc:creator>
    <dc:date>2013-05-16T21:03:29</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108156">
    <title>pull-request: iwlwifi-fixes 2013-05-16</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108156</link>
    <description>&lt;pre&gt;John,

And another one for iwlwifi, much fewer commits though.

I have fixes for a firmware crash during resume, multicast RX,
aggregation and a workaround for a firmware scanning bug.

Please pull. Thanks,
johannes



The following changes since commit 61f1598278876527314f5fc1d00cf0a4d525c1f7:

  Merge branch 'wireless' (2013-05-10 09:44:05 -0700)

are available in the git repository at:


  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git for-john

for you to fetch changes up to e3d4bc8cc0230e8dc8033484666f03f87392a8c4:

  iwlwifi: mvm: fix aggregation drain flow (2013-05-16 22:39:07 +0200)

----------------------------------------------------------------
Alexander Bondar (1):
      iwlwifi: mvm: Prevent setting assoc flag in MAC_CONTEXT_CMD

Emmanuel Grumbach (2):
      iwlwifi: mvm: tell firmware to let multicast frames in
      iwlwifi: mvm: fix aggregation drain flow

Ilan Peer (1):
      iwlwifi: mvm: Always use SCAN_TYPE_FORCED

 drivers/net/wireless/iwlwifi/mvm/fw-api.h   | 27 ++++++++++++++++
 drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 12 +++++---
 drivers/net/wireless/iwlwifi/mvm/mac80211.c | 17 +++++++++-
 drivers/net/wireless/iwlwifi/mvm/mvm.h      |  1 +
 drivers/net/wireless/iwlwifi/mvm/ops.c      |  1 +
 drivers/net/wireless/iwlwifi/mvm/scan.c     |  6 ++++
 drivers/net/wireless/iwlwifi/mvm/sta.c      | 13 ++++++--
 drivers/net/wireless/iwlwifi/mvm/sta.h      |  2 --
 drivers/net/wireless/iwlwifi/mvm/tx.c       | 48 +++++++++++++++++++++--------
 9 files changed, 105 insertions(+), 22 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Johannes Berg</dc:creator>
    <dc:date>2013-05-16T20:59:25</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.wireless.general/108155">
    <title>pull-request: mac80211 2013-05-16</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.wireless.general/108155</link>
    <description>&lt;pre&gt;John,

Here's my first pull request for the 3.10 fixes stream. Unfortunately, a
fairly large number of these also had to be tagged for stable.

This is what I have:
 * a patch from Felix to fix RCU usage in his rate table code
 * a patch from Ilan to add the wdev id to some notifications so they
can
   actually be used by userspace
 * Sasha Levin found an issue in how hwsim handles devices
 * a fix for a bug in the wiphy_register() error path that's been there
forever
 * three fixes for WoWLAN
 * AP mode frame matching was erroneously giving frames to all virtual
AP
   interfaces (reported by Jouni)
 * a fix for HT handling in my CSA changes, found by Sujith
 * a fix for some locking simplifications gone wrong
 * Ben Greear found more cfg80211/mac80211 state confusion
 * and a fix for another bug found by Jouni: local state changes need to
be
   reported by mac80211 to cfg80211 so it disconnects properly.

Please pull. Thanks,
johannes



The following changes since commit 61f1598278876527314f5fc1d00cf0a4d525c1f7:

  Merge branch 'wireless' (2013-05-10 09:44:05 -0700)

are available in the git repository at:


  git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git for-john

for you to fetch changes up to e248ad30204eff6559b4d2d94d49d9d46c08185a:

  cfg80211: fix sending WoWLAN TCP wakeup settings (2013-05-16 22:38:09 +0200)

----------------------------------------------------------------
Felix Fietkau (1):
      mac80211: fix spurious RCU warning and update documentation

Ilan Peer (1):
      nl80211: Add wdev identifier to some nl80211 notifications

Johannes Berg (9):
      cfg80211: fix wiphy_register error path
      cfg80211: fix WoWLAN wakeup tracing
      mac80211: fix IEEE80211_SDATA_DISCONNECT_RESUME
      mac80211: fix HT beacon-based channel switch handling
      mac80211: use just spin_lock() in ieee80211_get_tkip_p2k()
      mac80211: fix AP-mode frame matching
      cfg80211: fix interface down/disconnect state handling
      mac80211: report deauth to cfg80211 for local state change
      cfg80211: fix sending WoWLAN TCP wakeup settings

Sasha Levin (1):
      mac80211_hwsim: correctly register the platform driver

 drivers/net/wireless/mac80211_hwsim.c | 18 +++++------
 include/net/mac80211.h                | 12 ++++---
 net/mac80211/ieee80211_i.h            |  1 +
 net/mac80211/mlme.c                   | 61 +++++++++++++++++++++++++++++------
 net/mac80211/rate.c                   |  9 +++++-
 net/mac80211/rx.c                     |  3 ++
 net/mac80211/tkip.c                   |  4 +--
 net/mac80211/util.c                   |  7 ++++
 net/wireless/core.c                   | 17 ++++++----
 net/wireless/nl80211.c                |  4 +++
 net/wireless/sme.c                    |  3 +-
 net/wireless/trace.h                  | 23 +++++++------
 12 files changed, 118 insertions(+), 44 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Johannes Berg</dc:creator>
    <dc:date>2013-05-16T20:52:48</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.kernel.wireless.general">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.kernel.wireless.general</link>
  </textinput>
</rdf:RDF>
