Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH] mac80211: use maximum number of a-msdu frames as default in BA RX
From: Luciano Coelho @ 2011-01-12 13:03 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, stable@kernel.org
In-Reply-To: <1294836844.3639.26.camel@jlt3.sipsolutions.net>

On Wed, 2011-01-12 at 13:54 +0100, Johannes Berg wrote:
> On Wed, 2011-01-12 at 14:51 +0200, coelho@ti.com wrote:
> > From: Luciano Coelho <coelho@ti.com>
> > 
> > When the buffer size is set to zero in the block ack parameter set
> > field, we should use the maximum supported number of subframes.  The
> > existing code was bogus and was doing some unnecessary calculations
> > that lead to wrong values.
> > 
> > Thanks Johannes for helping me figure this one out.
> > 
> > Cc: stable@kernel.org
> > Cc: Johannes Berg <johannes@sipsolutions.net>
> 
> Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
> 
> It'd be easier for stable if you reordered with the other patch, I
> think, but I guess it's easy enough to fix up.

Will do.


> Also some older stable versions might have this code in a different
> file, but I'm not sure how to handle that.

Dunno how to handle that either... If I need to do something, someone
please just let me know. ;)

-- 
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH 1/2] mac80211: add hw configuration for max ampdu buffer size
From: Luciano Coelho @ 2011-01-12 13:04 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, juuso.oikarinen@nokia.com
In-Reply-To: <1294836406.3639.25.camel@jlt3.sipsolutions.net>

On Wed, 2011-01-12 at 13:46 +0100, Johannes Berg wrote:
> On Wed, 2011-01-12 at 14:40 +0200, coelho@ti.com wrote:
> > From: Luciano Coelho <coelho@ti.com>
> > 
> > Some devices don't support the maximum AMDPU buffer size of 64, so we
> > need to add an option to configure this in the hardware configuration.
> > This value will be used in the ADDBA response instead of the value
> > suggested in the request, if the latter is greater than the max
> > supported.
> > 
> > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > ---
> >  include/net/mac80211.h |    4 ++++
> >  net/mac80211/agg-rx.c  |    3 +++
> >  net/mac80211/main.c    |    1 +
> >  3 files changed, 8 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> > index 5b3fd5a..1341d82 100644
> > --- a/include/net/mac80211.h
> > +++ b/include/net/mac80211.h
> > @@ -1143,6 +1143,9 @@ enum ieee80211_hw_flags {
> >   * @napi_weight: weight used for NAPI polling.  You must specify an
> >   *	appropriate value here if a napi_poll operation is provided
> >   *	by your driver.
> > + * @max_rx_aggregation_subframes: maximum buffer size (number of
> > + *	sub-frames) to be used for A-MPDU block ack receiver
> > + *	aggregation.
> 
> ... "This is only relevant if the device has restrictions on the number
> of subframes, if it relies on mac80211 to do reordering it shouldn't be
> set." maybe?

Yes, this makes it clearer.  Thanks! I'll add it.

-- 
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH 1/2] mac80211: add hw configuration for max ampdu buffer size
From: Luciano Coelho @ 2011-01-12 13:05 UTC (permalink / raw)
  To: Juuso Oikarinen; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1294837049.18570.63.camel@wimaxnb.nmp.nokia.com>

On Wed, 2011-01-12 at 13:57 +0100, Juuso Oikarinen wrote:
> On Wed, 2011-01-12 at 14:40 +0200, ext coelho@ti.com wrote:
> > From: Luciano Coelho <coelho@ti.com>
> > 
> > Some devices don't support the maximum AMDPU buffer size of 64, so we
> > need to add an option to configure this in the hardware configuration.
> > This value will be used in the ADDBA response instead of the value
> > suggested in the request, if the latter is greater than the max
> > supported.
> > 
> > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > ---
> 
> Tested-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>

Thanks a lot for testing this for me, Juuso! I owe you one beer...
hrmmm... coke!

-- 
Cheers,
Luca.


^ permalink raw reply

* [PATCH v2] mac80211: use maximum number of AMPDU frames as default in BA RX
From: coelho @ 2011-01-12 13:18 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho, stable, Johannes Berg

From: Luciano Coelho <coelho@ti.com>

When the buffer size is set to zero in the block ack parameter set
field, we should use the maximum supported number of subframes.  The
existing code was bogus and was doing some unnecessary calculations
that lead to wrong values.

Thanks Johannes for helping me figure this one out.

Cc: stable@kernel.org
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/agg-rx.c |   11 ++---------
 1 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index f138b19..227ca82 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -185,8 +185,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 				     struct ieee80211_mgmt *mgmt,
 				     size_t len)
 {
-	struct ieee80211_hw *hw = &local->hw;
-	struct ieee80211_conf *conf = &hw->conf;
 	struct tid_ampdu_rx *tid_agg_rx;
 	u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
 	u8 dialog_token;
@@ -231,13 +229,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 		goto end_no_lock;
 	}
 	/* determine default buffer size */
-	if (buf_size == 0) {
-		struct ieee80211_supported_band *sband;
-
-		sband = local->hw.wiphy->bands[conf->channel->band];
-		buf_size = IEEE80211_MIN_AMPDU_BUF;
-		buf_size = buf_size << sband->ht_cap.ampdu_factor;
-	}
+	if (buf_size == 0)
+		buf_size = IEEE80211_MAX_AMPDU_BUF;
 
 
 	/* examine state machine */
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] mac80211: use maximum number of a-msdu frames as default in BA RX
From: Luciano Coelho @ 2011-01-12 13:21 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, stable@kernel.org
In-Reply-To: <1294837426.2097.32.camel@pimenta>

On Wed, 2011-01-12 at 14:03 +0100, Coelho, Luciano wrote:
> On Wed, 2011-01-12 at 13:54 +0100, Johannes Berg wrote:
> > On Wed, 2011-01-12 at 14:51 +0200, coelho@ti.com wrote:
> > > From: Luciano Coelho <coelho@ti.com>
> > > 
> > > When the buffer size is set to zero in the block ack parameter set
> > > field, we should use the maximum supported number of subframes.  The
> > > existing code was bogus and was doing some unnecessary calculations
> > > that lead to wrong values.
> > > 
> > > Thanks Johannes for helping me figure this one out.
> > > 
> > > Cc: stable@kernel.org
> > > Cc: Johannes Berg <johannes@sipsolutions.net>
> > 
> > Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
> > 
> > It'd be easier for stable if you reordered with the other patch, I
> > think, but I guess it's easy enough to fix up.
> 
> Will do.

Sent v2 rebased in a cleaner head and changed "a-msdu" to AMPDU in the
commit subject, as Johannes pointed out.


-- 
Cheers,
Luca.


^ permalink raw reply

* [PATCH v2] mac80211: add hw configuration for max ampdu buffer size
From: coelho @ 2011-01-12 13:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luciano Coelho

From: Luciano Coelho <coelho@ti.com>

Some devices don't support the maximum AMDPU buffer size of 64, so we
need to add an option to configure this in the hardware configuration.
This value will be used in the ADDBA response instead of the value
suggested in the request, if the latter is greater than the max
supported.

Signed-off-by: Luciano Coelho <coelho@ti.com>
Tested-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
 include/net/mac80211.h |    8 ++++++++
 net/mac80211/agg-rx.c  |    3 +++
 net/mac80211/main.c    |    1 +
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5b3fd5a..e651988 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1143,6 +1143,13 @@ enum ieee80211_hw_flags {
  * @napi_weight: weight used for NAPI polling.  You must specify an
  *	appropriate value here if a napi_poll operation is provided
  *	by your driver.
+
+ * @max_rx_aggregation_subframes: maximum buffer size (number of
+ *	sub-frames) to be used for A-MPDU block ack receiver
+ *	aggregation.
+ *	This is only relevant if the device has restrictions on the
+ *	number of subframes, if it relies on mac80211 to do reordering
+ *	it shouldn't be set.
  */
 struct ieee80211_hw {
 	struct ieee80211_conf conf;
@@ -1161,6 +1168,7 @@ struct ieee80211_hw {
 	u8 max_rates;
 	u8 max_report_rates;
 	u8 max_rate_tries;
+	u8 max_rx_aggregation_subframes;
 };
 
 /**
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 227ca82..1274440 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -232,6 +232,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 	if (buf_size == 0)
 		buf_size = IEEE80211_MAX_AMPDU_BUF;
 
+	/* make sure the size doesn't exceed the maximum supported by the hw */
+	if (buf_size > local->hw.max_rx_aggregation_subframes)
+		buf_size = local->hw.max_rx_aggregation_subframes;
 
 	/* examine state machine */
 	mutex_lock(&sta->ampdu_mlme.mtx);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 485d36b..1c507c6 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -552,6 +552,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	local->hw.queues = 1;
 	local->hw.max_rates = 1;
 	local->hw.max_report_rates = 0;
+	local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
 	local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
 	local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
 	local->user_power_level = -1;
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2] wl12xx: add hw configuration for max supported AMDPU size
From: coelho @ 2011-01-12 13:27 UTC (permalink / raw)
  To: coelho; +Cc: linux-wireless

From: Luciano Coelho <coelho@ti.com>

The wl12xx chips do the AMDPU aggregation work in the firmware, but it
supports a maximum of 8 frames per block.  Configure the mac80211 hw
structure accordingly.

Signed-off-by: Luciano Coelho <coelho@ti.com>
Tested-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
 drivers/net/wireless/wl12xx/main.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 67732ea..463d6bf 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -3178,6 +3178,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
 
 	wl->hw->sta_data_size = sizeof(struct wl1271_station);
 
+	wl->hw->max_rx_aggregation_subframes = 8;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(wl1271_init_ieee80211);
-- 
1.7.1


^ permalink raw reply related

* Re: [RFC/RFT] mac80211: Fix mixed usage of spin_lock and spin_lock_irqsave on same lock
From: Stanislaw Gruszka @ 2011-01-12 13:26 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Larry Finger, John W Linville, linux-wireless
In-Reply-To: <1294822933.3639.14.camel@jlt3.sipsolutions.net>

On Wed, Jan 12, 2011 at 10:02:13AM +0100, Johannes Berg wrote:
> local->skb_queue[_unreliable]. I think Stanislaw was right on (but why
> didn't he offer a fix? :-) ).
Heh, I did't know such simple fix exist :)

Stanislaw

^ permalink raw reply

* Re: [PATCH] ath9k: set hw opmode while changing interface type
From: Rajkumar Manoharan @ 2011-01-12 14:20 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Rajkumar Manoharan, linville@tuxdriver.com,
	linux-wireless@vger.kernel.org, Jouni Malinen
In-Reply-To: <4D29F995.1000007@openwrt.org>

On Sun, Jan 09, 2011 at 11:38:21PM +0530, Felix Fietkau wrote:
> On 2011-01-09 9:51 AM, Rajkumar Manoharan wrote:
> > The commit "ath9k: Add change_interface callback" is
> > failed to set hw opmode while changing interface type
> > on runtime. Not setting opmode fails to generate
> > beacons on changing to AP mode.
> >
> I think since not only ah->opmode matters, but also various other things 
> that conditionally enable/disable ANI, various flags in ah->imask, etc. 
> it would probably be best to merge most of the code of .add_interface, 
> .remove_interface and .change_interface into one function that iterates 
> over all active interfaces and calculates all the mode dependent 
> parameters. The way things are done right now is just too fragile.

Sorry for delayed response. Will send a RFC patch. Thanks for the review.

--
Rajkumar

^ permalink raw reply

* [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-12 14:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: Rajkumar Manoharan

The commit ""ath9k: Add change_interface callback" was failed
to update of hw opmode, ani and interrupt mask. This leads
to break p2p functionality on ath9k. And the existing add and
remove interface functions are not handling hw opmode and
ANI properly.

This patch combines the common code in interface callbacks
and also takes care of multi-vif cases.

Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    7 +
 drivers/net/wireless/ath/ath9k/main.c  |  195 +++++++++++++------------------
 drivers/net/wireless/ath/ath9k/recv.c  |    2 +-
 3 files changed, 90 insertions(+), 114 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 3681caf5..ef00f93 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -309,6 +309,7 @@ int ath_startrecv(struct ath_softc *sc);
 bool ath_stoprecv(struct ath_softc *sc);
 void ath_flushrecv(struct ath_softc *sc);
 u32 ath_calcrxfilter(struct ath_softc *sc);
+void ath_opmode_init(struct ath_softc *sc);
 int ath_rx_init(struct ath_softc *sc, int nbufs);
 void ath_rx_cleanup(struct ath_softc *sc);
 int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
@@ -337,6 +338,12 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
 /* VIFs */
 /********/
 
+enum ath_iface_optype {
+	ATH9K_ADD_IFACE,
+	ATH9K_MOD_IFACE,
+	ATH9K_DEL_IFACE,
+};
+
 struct ath_vif {
 	int av_bslot;
 	__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index f90a6ca..b6dd7d0 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1341,64 +1341,114 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
 }
 
-static int ath9k_add_interface(struct ieee80211_hw *hw,
-			       struct ieee80211_vif *vif)
+static void ath9k_reclaim_beacon(struct ath_softc *sc,
+				 struct ieee80211_vif *vif)
+{
+	struct ath_vif *avp = (void *)vif->drv_priv;
+
+	/* Disable SWBA interrupt */
+	sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
+	ath9k_ps_wakeup(sc);
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+	ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+	tasklet_kill(&sc->bcon_tasklet);
+	ath9k_ps_restore(sc);
+
+	ath_beacon_return(sc, avp);
+	sc->sc_flags &= ~SC_OP_BEACONS;
+
+	if (sc->nbcnvifs > 0) {
+		/* Re-enable beaconing */
+		sc->sc_ah->imask |= ATH9K_INT_SWBA;
+		ath9k_ps_wakeup(sc);
+		ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+		ath9k_ps_restore(sc);
+	}
+}
+
+static int ath9k_iface_work(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    enum nl80211_iftype new_type,
+			    bool p2p,
+			    u8 optype)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_vif *avp = (void *)vif->drv_priv;
-	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	enum nl80211_iftype iftype;
 	int ret = 0;
 
 	mutex_lock(&sc->mutex);
 
-	switch (vif->type) {
+	/* Stop ANI timer */
+	del_timer_sync(&common->ani.timer);
+
+	iftype = (optype == ATH9K_MOD_IFACE) ? new_type : vif->type;
+
+	/* Remove interface */
+	if (optype == ATH9K_DEL_IFACE) {
+		if ((iftype == NL80211_IFTYPE_AP) ||
+		    (iftype == NL80211_IFTYPE_ADHOC)) {
+			ath9k_reclaim_beacon(sc, vif);
+			if (!sc->nbcnvifs)
+				sc->sc_flags &= ~SC_OP_ANI_RUN;
+		}
+		ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
+		sc->nvifs--;
+		goto out;
+	}
+
+	switch (iftype) {
 	case NL80211_IFTYPE_STATION:
-		ic_opmode = NL80211_IFTYPE_STATION;
+		if ((optype == ATH9K_MOD_IFACE) &&
+		    ((vif->type == NL80211_IFTYPE_AP) ||
+		     (vif->type == NL80211_IFTYPE_ADHOC)))
+			ath9k_reclaim_beacon(sc, vif);
+		if (!sc->nbcnvifs) {
+			sc->sc_flags &= ~SC_OP_ANI_RUN;
+			ah->opmode = iftype;
+		}
 		break;
 	case NL80211_IFTYPE_WDS:
-		ic_opmode = NL80211_IFTYPE_WDS;
+		ah->opmode = iftype;
 		break;
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_MESH_POINT:
+	case NL80211_IFTYPE_AP:
 		if (sc->nbcnvifs >= ATH_BCBUF) {
 			ret = -ENOBUFS;
 			goto out;
 		}
-		ic_opmode = vif->type;
+		sc->sc_flags |= SC_OP_ANI_RUN;
+		ah->opmode = iftype;
 		break;
 	default:
 		ath_err(common, "Interface type %d not yet supported\n",
-			vif->type);
+				iftype);
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
-
-	ath_dbg(common, ATH_DBG_CONFIG,
-		"Attach a VIF of type: %d\n", ic_opmode);
-
-	/* Set the VIF opmode */
-	avp->av_opmode = ic_opmode;
+	avp->av_opmode = iftype;
 	avp->av_bslot = -1;
+	vif->type = iftype;
+	vif->p2p = p2p;
 
-	sc->nvifs++;
-
-	ath9k_set_bssid_mask(hw, vif);
-
-	if (sc->nvifs > 1)
-		goto out; /* skip global settings for secondary vif */
+	if (optype == ATH9K_ADD_IFACE) {
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"Attach Interface of type %d\n", vif->type);
+		sc->nvifs++;
+	} else
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"Change Interface to type %d\n", vif->type);
 
-	if (ic_opmode == NL80211_IFTYPE_AP) {
+	ath_opmode_init(sc);
+	if (vif->type == NL80211_IFTYPE_AP) {
 		ath9k_hw_set_tsfadjust(ah, 1);
 		sc->sc_flags |= SC_OP_TSF_RESET;
 	}
 
-	/* Set the device opmode */
-	ah->opmode = ic_opmode;
-
 	/*
 	 * Enable MIB interrupts when there are hardware phy counters.
 	 * Note we only do this (at the moment) for station mode.
@@ -1410,43 +1460,18 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
 			ah->imask |= ATH9K_INT_MIB;
 		ah->imask |= ATH9K_INT_TSFOOR;
 	}
-
 	ath9k_hw_set_interrupts(ah, ah->imask);
 
-	if (vif->type == NL80211_IFTYPE_AP    ||
-	    vif->type == NL80211_IFTYPE_ADHOC) {
-		sc->sc_flags |= SC_OP_ANI_RUN;
-		ath_start_ani(common);
-	}
-
 out:
+	ath_start_ani(common);
 	mutex_unlock(&sc->mutex);
 	return ret;
 }
 
-static void ath9k_reclaim_beacon(struct ath_softc *sc,
-				 struct ieee80211_vif *vif)
+static int ath9k_add_interface(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif)
 {
-	struct ath_vif *avp = (void *)vif->drv_priv;
-
-	/* Disable SWBA interrupt */
-	sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
-	ath9k_ps_wakeup(sc);
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
-	ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-	tasklet_kill(&sc->bcon_tasklet);
-	ath9k_ps_restore(sc);
-
-	ath_beacon_return(sc, avp);
-	sc->sc_flags &= ~SC_OP_BEACONS;
-
-	if (sc->nbcnvifs > 0) {
-		/* Re-enable beaconing */
-		sc->sc_ah->imask |= ATH9K_INT_SWBA;
-		ath9k_ps_wakeup(sc);
-		ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
-		ath9k_ps_restore(sc);
-	}
+	return ath9k_iface_work(hw, vif, vif->type, vif->p2p, ATH9K_ADD_IFACE);
 }
 
 static int ath9k_change_interface(struct ieee80211_hw *hw,
@@ -1454,69 +1479,13 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
 				  enum nl80211_iftype new_type,
 				  bool p2p)
 {
-	struct ath_wiphy *aphy = hw->priv;
-	struct ath_softc *sc = aphy->sc;
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	int ret = 0;
-
-	ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
-	mutex_lock(&sc->mutex);
-
-	switch (new_type) {
-	case NL80211_IFTYPE_AP:
-	case NL80211_IFTYPE_ADHOC:
-		if (sc->nbcnvifs >= ATH_BCBUF) {
-			ath_err(common, "No beacon slot available\n");
-			ret = -ENOBUFS;
-			goto out;
-		}
-		break;
-	case NL80211_IFTYPE_STATION:
-		/* Stop ANI */
-		sc->sc_flags &= ~SC_OP_ANI_RUN;
-		del_timer_sync(&common->ani.timer);
-		if ((vif->type == NL80211_IFTYPE_AP) ||
-		    (vif->type == NL80211_IFTYPE_ADHOC))
-			ath9k_reclaim_beacon(sc, vif);
-		break;
-	default:
-		ath_err(common, "Interface type %d not yet supported\n",
-				vif->type);
-		ret = -ENOTSUPP;
-		goto out;
-	}
-	vif->type = new_type;
-	vif->p2p = p2p;
-
-out:
-	mutex_unlock(&sc->mutex);
-	return ret;
+	return ath9k_iface_work(hw, vif, new_type, p2p, ATH9K_MOD_IFACE);
 }
 
 static void ath9k_remove_interface(struct ieee80211_hw *hw,
 				   struct ieee80211_vif *vif)
 {
-	struct ath_wiphy *aphy = hw->priv;
-	struct ath_softc *sc = aphy->sc;
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-
-	ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
-
-	mutex_lock(&sc->mutex);
-
-	/* Stop ANI */
-	sc->sc_flags &= ~SC_OP_ANI_RUN;
-	del_timer_sync(&common->ani.timer);
-
-	/* Reclaim beacon resources */
-	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))
-		ath9k_reclaim_beacon(sc, vif);
-
-	sc->nvifs--;
-
-	mutex_unlock(&sc->mutex);
+	ath9k_iface_work(hw, vif, vif->type, vif->p2p, ATH9K_DEL_IFACE);
 }
 
 static void ath9k_enable_ps(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b2497b8..f02a709 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -107,7 +107,7 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
 	sc->rx.rxotherant = 0;
 }
 
-static void ath_opmode_init(struct ath_softc *sc)
+void ath_opmode_init(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-- 
1.7.3.5


^ permalink raw reply related

* Re: [RFC 2/2] iwlwifi: use maximum aggregation size
From: Guy, Wey-Yi @ 2011-01-12 16:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20110112121418.037714947@sipsolutions.net>

Hi Johannes,

On Wed, 2011-01-12 at 04:13 -0800, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> Use the values from the peer to set up the ucode
> for the right maximum number of subframes in an
> aggregate. Since the ucode only tracks this per
> station, use the minimum across all aggregation
> sessions with this peer.
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
>  drivers/net/wireless/iwlwifi/iwl-agn-rs.c |    5 +++-
>  drivers/net/wireless/iwlwifi/iwl-agn.c    |   32 +++++++++++++++++++++++++-----
>  drivers/net/wireless/iwlwifi/iwl-dev.h    |    1 
>  3 files changed, 32 insertions(+), 6 deletions(-)
> 
> --- wireless-testing.orig/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2011-01-12 13:08:22.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2011-01-12 13:10:58.000000000 +0100
> @@ -2889,6 +2889,8 @@ static void rs_fill_link_cmd(struct iwl_
>  	u8 ant_toggle_cnt = 0;
>  	u8 use_ht_possible = 1;
>  	u8 valid_tx_ant = 0;
> +	struct iwl_station_priv *sta_priv =
> +		container_of(lq_sta, struct iwl_station_priv, lq_sta);
>  	struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
>  
>  	/* Override starting rate (index 0) if needed for debug purposes */
> @@ -3007,7 +3009,8 @@ static void rs_fill_link_cmd(struct iwl_
>  		repeat_rate--;
>  	}
>  
> -	lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
> +	lq_cmd->agg_params.agg_frame_cnt_limit =
> +		sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF;

at this point, sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit has
the right value, why not use it?

on the other hand, sta_priv->max_agg_bufsize ==
sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit

why need both?


>  	lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
>  
>  	lq_cmd->agg_params.agg_time_limit =
> --- wireless-testing.orig/drivers/net/wireless/iwlwifi/iwl-agn.c	2011-01-12 13:03:34.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/iwlwifi/iwl-agn.c	2011-01-12 13:11:50.000000000 +0100
> @@ -3421,6 +3421,7 @@ int iwlagn_mac_ampdu_action(struct ieee8
>  {
>  	struct iwl_priv *priv = hw->priv;
>  	int ret = -EINVAL;
> +	struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
>  
>  	IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
>  		     sta->addr, tid);
> @@ -3475,11 +3476,28 @@ int iwlagn_mac_ampdu_action(struct ieee8
>  		}
>  		break;
>  	case IEEE80211_AMPDU_TX_OPERATIONAL:
> +		/*
> +		 * If the limit is 0, then it wasn't initialised yet,
> +		 * use the default. We can do that since we take the
> +		 * minimum below, and we don't want to go above our
> +		 * default due to hardware restrictions.
> +		 */
> +		if (sta_priv->max_agg_bufsize == 0)
> +			sta_priv->max_agg_bufsize =
> +				LINK_QUAL_AGG_FRAME_LIMIT_DEF;
> +
> +		/*
> +		 * Even though in theory the peer could have different
> +		 * aggregation reorder buffer sizes for different sessions,
> +		 * our ucode doesn't allow for that and has a global limit
> +		 * for each station. Therefore, use the minimum of all the
> +		 * aggregation sessions and our default value.
> +		 */
> +		sta_priv->max_agg_bufsize =
> +			min(sta_priv->max_agg_bufsize, buf_size);
> +
not sure where the "bus_size" come from?

>  		if (priv->cfg->ht_params &&
>  		    priv->cfg->ht_params->use_rts_for_aggregation) {
> -			struct iwl_station_priv *sta_priv =
> -				(void *) sta->drv_priv;
> -
>  			/*
>  			 * switch to RTS/CTS if it is the prefer protection
>  			 * method for HT traffic
> @@ -3487,9 +3505,13 @@ int iwlagn_mac_ampdu_action(struct ieee8
>  
>  			sta_priv->lq_sta.lq.general_params.flags |=
>  				LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
> -			iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
> -					&sta_priv->lq_sta.lq, CMD_ASYNC, false);
>  		}
> +
> +		sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit =
> +			sta_priv->max_agg_bufsize;
> +
> +		iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
> +				&sta_priv->lq_sta.lq, CMD_ASYNC, false);
>  		ret = 0;
>  		break;
>  	}
> --- wireless-testing.orig/drivers/net/wireless/iwlwifi/iwl-dev.h	2011-01-12 13:03:12.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/iwlwifi/iwl-dev.h	2011-01-12 13:03:31.000000000 +0100
> @@ -509,6 +509,7 @@ struct iwl_station_priv {
>  	atomic_t pending_frames;
>  	bool client;
>  	bool asleep;
> +	u8 max_agg_bufsize;
>  };
>  
>  /**
> 

Wey



^ permalink raw reply

* Re: [RFC 2/2] iwlwifi: use maximum aggregation size
From: Johannes Berg @ 2011-01-12 16:38 UTC (permalink / raw)
  To: Guy, Wey-Yi; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1294849399.3591.34.camel@wwguy-huron>

On Wed, 2011-01-12 at 08:23 -0800, Guy, Wey-Yi wrote:

> > +	lq_cmd->agg_params.agg_frame_cnt_limit =
> > +		sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF;
> 
> at this point, sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit has
> the right value, why not use it?

I wasn't sure it would _always_ have the right value, and if the ucode
would accept 0 before needed -- the ?: construct will use it if
non-zero, and use the default otherwise.

> on the other hand, sta_priv->max_agg_bufsize ==
> sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit
> 
> why need both?

Yeah I guess that would work if we put the init somewhere else, and
didn't change it above in that function -- we need the minimum
calculation to work. This seemed easier to verify to me :-)

> > +		/*
> > +		 * Even though in theory the peer could have different
> > +		 * aggregation reorder buffer sizes for different sessions,
> > +		 * our ucode doesn't allow for that and has a global limit
> > +		 * for each station. Therefore, use the minimum of all the
> > +		 * aggregation sessions and our default value.
> > +		 */
> > +		sta_priv->max_agg_bufsize =
> > +			min(sta_priv->max_agg_bufsize, buf_size);
> > +
> not sure where the "bus_size" come from?

It's a new argument to the function -- see patch 1/2.

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: fix lockdep warning
From: Larry Finger @ 2011-01-12 16:44 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John Linville, linux-wireless@vger.kernel.org, Miles Lane, Sujith
In-Reply-To: <1294836033.3639.24.camel@jlt3.sipsolutions.net>

On 01/12/2011 06:40 AM, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> Since the introduction of the fixes for the
> reorder timer, mac80211 will cause lockdep
> warnings because lockdep confuses
> local->skb_queue and local->rx_skb_queue
> and treats their lock as the same.
> 
> However, their locks are different, and are
> valid in different contexts (the former is
> used in IRQ context, the latter in BH only)
> and the only thing to be done is mark the
> former as a different lock class so that
> lockdep can tell the difference.
> 
> Reported-by: Larry Finger <Larry.Finger@lwfinger.net>
> Reported-by: Sujith <m.sujith@gmail.com>
> Reported-by: Miles Lane <miles.lane@gmail.com>
> Tested-by: Sujith <m.sujith@gmail.com>
> Tested-by: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
>  net/mac80211/main.c |   12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> --- wireless-testing.orig/net/mac80211/main.c	2011-01-12 09:58:07.000000000 +0100
> +++ wireless-testing/net/mac80211/main.c	2011-01-12 10:02:03.000000000 +0100
> @@ -39,6 +39,8 @@ module_param(ieee80211_disable_40mhz_24g
>  MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
>  		 "Disable 40MHz support in the 2.4GHz band");
>  
> +static struct lock_class_key ieee80211_rx_skb_queue_class;
> +
>  void ieee80211_configure_filter(struct ieee80211_local *local)
>  {
>  	u64 mc;
> @@ -569,7 +571,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(
>  	spin_lock_init(&local->filter_lock);
>  	spin_lock_init(&local->queue_stop_reason_lock);
>  
> -	skb_queue_head_init(&local->rx_skb_queue);
> +	/*
> +	 * The rx_skb_queue is only accessed from tasklets,
> +	 * but other SKB queues are used from within IRQ
> +	 * context. Therefore, this one needs a different
> +	 * locking class so our direct, non-irq-safe use of
> +	 * the queue's lock doesn't throw lockdep warnings.
> +	 */
> +	skb_queue_head_init_class(&local->rx_skb_queue,
> +				  &ieee80211_rx_skb_queue_class);
>  
>  	INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
>  
> 
> 

This one works for me. Thanks for sorting this out.

Larry

^ permalink raw reply

* Re: [RFC 2/2] iwlwifi: use maximum aggregation size
From: Guy, Wey-Yi @ 2011-01-12 16:46 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1294850337.3639.28.camel@jlt3.sipsolutions.net>

Hi Johannes,

On Wed, 2011-01-12 at 08:38 -0800, Johannes Berg wrote:
> On Wed, 2011-01-12 at 08:23 -0800, Guy, Wey-Yi wrote:
> 
> > > +	lq_cmd->agg_params.agg_frame_cnt_limit =
> > > +		sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF;
> > 
> > at this point, sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit has
> > the right value, why not use it?
> 
> I wasn't sure it would _always_ have the right value, and if the ucode
> would accept 0 before needed -- the ?: construct will use it if
> non-zero, and use the default otherwise.
> 
> > on the other hand, sta_priv->max_agg_bufsize ==
> > sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit
> > 
> > why need both?
> 
> Yeah I guess that would work if we put the init somewhere else, and
> didn't change it above in that function -- we need the minimum
> calculation to work. This seemed easier to verify to me :-)
> 
> > > +		/*
> > > +		 * Even though in theory the peer could have different
> > > +		 * aggregation reorder buffer sizes for different sessions,
> > > +		 * our ucode doesn't allow for that and has a global limit
> > > +		 * for each station. Therefore, use the minimum of all the
> > > +		 * aggregation sessions and our default value.
> > > +		 */
> > > +		sta_priv->max_agg_bufsize =
> > > +			min(sta_priv->max_agg_bufsize, buf_size);
> > > +
> > not sure where the "bus_size" come from?
> 
> It's a new argument to the function -- see patch 1/2.
> 
I don't think I have patch 1/2

Here is what I have
[RFC2/2]iwlwifi: use maximum aggregation size
[RFC2/2]iwlwifi: advertise max aggregate size

Wey



^ permalink raw reply

* Re: [RFC 1/2] mac80211: track receivers aggregation reorder buffer size
From: Guy, Wey-Yi @ 2011-01-12 16:51 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20110112121417.852157387@sipsolutions.net>

Johannes,

ok, got it

Wey

On Wed, 2011-01-12 at 04:13 -0800, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> The aggregation code currently doesn't implement the
> buffer size negotiation. It will always request a max
> buffer size (which is fine, if a little pointless, as
> the mac80211 code doesn't know and might just use 0
> instead), but if the peer requests a smaller size it
> isn't possible to honour this request.
> 
> In order to fix this, look at the buffer size in the
> addBA response frame, keep track of it and pass it to
> the driver in the ampdu_action callback when called
> with the IEEE80211_AMPDU_TX_OPERATIONAL action. That
> way the driver can limit the number of subframes in
> aggregates appropriately.
> 
> Note that this doesn't fix any drivers apart from the
> addition of the new argument -- they all need to be
> updated separately to use this variable!
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
>  drivers/net/wireless/ath/ar9170/main.c        |    3 ++-
>  drivers/net/wireless/ath/ath9k/htc_drv_main.c |    2 +-
>  drivers/net/wireless/ath/ath9k/main.c         |    2 +-
>  drivers/net/wireless/ath/carl9170/main.c      |    2 +-
>  drivers/net/wireless/iwlwifi/iwl-agn.c        |    3 ++-
>  drivers/net/wireless/iwlwifi/iwl-agn.h        |    3 ++-
>  drivers/net/wireless/mac80211_hwsim.c         |    3 ++-
>  drivers/net/wireless/mwl8k.c                  |    3 ++-
>  drivers/net/wireless/rt2x00/rt2800lib.c       |    3 ++-
>  drivers/net/wireless/rt2x00/rt2800lib.h       |    3 ++-
>  drivers/net/wireless/rtlwifi/core.c           |    3 ++-
>  include/net/mac80211.h                        |    7 ++++++-
>  net/mac80211/agg-rx.c                         |    4 ++--
>  net/mac80211/agg-tx.c                         |   20 +++++++++++++++++---
>  net/mac80211/driver-ops.h                     |    6 +++---
>  net/mac80211/driver-trace.h                   |   11 +++++++----
>  net/mac80211/sta_info.h                       |    2 ++
>  17 files changed, 56 insertions(+), 24 deletions(-)
> 
> --- wireless-testing.orig/include/net/mac80211.h        2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/include/net/mac80211.h     2011-01-12 13:02:36.000000000 +0100
> @@ -1723,6 +1723,10 @@ enum ieee80211_ampdu_mlme_action {
>   *     ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
>   *     is the first frame we expect to perform the action on. Notice
>   *     that TX/RX_STOP can pass NULL for this parameter.
> + *     The @buf_size parameter is only valid when the action is set to
> + *     %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder
> + *     buffer size (number of subframes) for this session -- aggregates
> + *     containing more subframes than this may not be transmitted to the peer.
>   *     Returns a negative error code on failure.
>   *     The callback can sleep.
>   *
> @@ -1825,7 +1829,8 @@ struct ieee80211_ops {
>         int (*ampdu_action)(struct ieee80211_hw *hw,
>                             struct ieee80211_vif *vif,
>                             enum ieee80211_ampdu_mlme_action action,
> -                           struct ieee80211_sta *sta, u16 tid, u16 *ssn);
> +                           struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                           u8 buf_size);
>         int (*get_survey)(struct ieee80211_hw *hw, int idx,
>                 struct survey_info *survey);
>         void (*rfkill_poll)(struct ieee80211_hw *hw);
> --- wireless-testing.orig/net/mac80211/agg-tx.c 2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/net/mac80211/agg-tx.c      2011-01-12 13:02:36.000000000 +0100
> @@ -190,7 +190,7 @@ int ___ieee80211_stop_tx_ba_session(stru
> 
>         ret = drv_ampdu_action(local, sta->sdata,
>                                IEEE80211_AMPDU_TX_STOP,
> -                              &sta->sta, tid, NULL);
> +                              &sta->sta, tid, NULL, 0);
> 
>         /* HW shall not deny going back to legacy */
>         if (WARN_ON(ret)) {
> @@ -311,7 +311,7 @@ void ieee80211_tx_ba_session_handle_star
>         start_seq_num = sta->tid_seq[tid] >> 4;
> 
>         ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
> -                              &sta->sta, tid, &start_seq_num);
> +                              &sta->sta, tid, &start_seq_num, 0);
>         if (ret) {
>  #ifdef CONFIG_MAC80211_HT_DEBUG
>                 printk(KERN_DEBUG "BA request denied - HW unavailable for"
> @@ -487,7 +487,8 @@ static void ieee80211_agg_tx_operational
> 
>         drv_ampdu_action(local, sta->sdata,
>                          IEEE80211_AMPDU_TX_OPERATIONAL,
> -                        &sta->sta, tid, NULL);
> +                        &sta->sta, tid, NULL,
> +                        sta->ampdu_mlme.tid_tx[tid]->buf_size);
> 
>         /*
>          * synchronize with TX path, while splicing the TX path
> @@ -742,9 +743,11 @@ void ieee80211_process_addba_resp(struct
>  {
>         struct tid_ampdu_tx *tid_tx;
>         u16 capab, tid;
> +       u8 buf_size;
> 
>         capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
>         tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
> +       buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
> 
>         mutex_lock(&sta->ampdu_mlme.mtx);
> 
> @@ -767,12 +770,23 @@ void ieee80211_process_addba_resp(struct
> 
>         if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
>                         == WLAN_STATUS_SUCCESS) {
> +               /*
> +                * IEEE 802.11-2007 7.3.1.14:
> +                * In an ADDBA Response frame, when the Status Code field
> +                * is set to 0, the Buffer Size subfield is set to a value
> +                * of at least 1.
> +                */
> +               if (!buf_size)
> +                       goto out;
> +
>                 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
>                                      &tid_tx->state)) {
>                         /* ignore duplicate response */
>                         goto out;
>                 }
> 
> +               tid_tx->buf_size = buf_size;
> +
>                 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
>                         ieee80211_agg_tx_operational(local, sta, tid);
> 
> --- wireless-testing.orig/net/mac80211/sta_info.h       2011-01-12 13:02:28.000000000 +0100
> +++ wireless-testing/net/mac80211/sta_info.h    2011-01-12 13:02:36.000000000 +0100
> @@ -82,6 +82,7 @@ enum ieee80211_sta_info_flags {
>   * @state: session state (see above)
>   * @stop_initiator: initiator of a session stop
>   * @tx_stop: TX DelBA frame when stopping
> + * @buf_size: reorder buffer size at receiver
>   *
>   * This structure's lifetime is managed by RCU, assignments to
>   * the array holding it must hold the aggregation mutex.
> @@ -101,6 +102,7 @@ struct tid_ampdu_tx {
>         u8 dialog_token;
>         u8 stop_initiator;
>         bool tx_stop;
> +       u8 buf_size;
>  };
> 
>  /**
> --- wireless-testing.orig/net/mac80211/agg-rx.c 2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/net/mac80211/agg-rx.c      2011-01-12 13:02:36.000000000 +0100
> @@ -76,7 +76,7 @@ void ___ieee80211_stop_rx_ba_session(str
>  #endif /* CONFIG_MAC80211_HT_DEBUG */
> 
>         if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
> -                            &sta->sta, tid, NULL))
> +                            &sta->sta, tid, NULL, 0))
>                 printk(KERN_DEBUG "HW problem - can not stop rx "
>                                 "aggregation for tid %d\n", tid);
> 
> @@ -294,7 +294,7 @@ void ieee80211_process_addba_request(str
>         }
> 
>         ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
> -                              &sta->sta, tid, &start_seq_num);
> +                              &sta->sta, tid, &start_seq_num, 0);
>  #ifdef CONFIG_MAC80211_HT_DEBUG
>         printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
>  #endif /* CONFIG_MAC80211_HT_DEBUG */
> --- wireless-testing.orig/net/mac80211/driver-ops.h     2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/net/mac80211/driver-ops.h  2011-01-12 13:02:36.000000000 +0100
> @@ -382,17 +382,17 @@ static inline int drv_ampdu_action(struc
>                                    struct ieee80211_sub_if_data *sdata,
>                                    enum ieee80211_ampdu_mlme_action action,
>                                    struct ieee80211_sta *sta, u16 tid,
> -                                  u16 *ssn)
> +                                  u16 *ssn, u8 buf_size)
>  {
>         int ret = -EOPNOTSUPP;
> 
>         might_sleep();
> 
> -       trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn);
> +       trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
> 
>         if (local->ops->ampdu_action)
>                 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
> -                                              sta, tid, ssn);
> +                                              sta, tid, ssn, buf_size);
> 
>         trace_drv_return_int(local, ret);
> 
> --- wireless-testing.orig/net/mac80211/driver-trace.h   2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/net/mac80211/driver-trace.h        2011-01-12 13:02:36.000000000 +0100
> @@ -784,9 +784,9 @@ TRACE_EVENT(drv_ampdu_action,
>                  struct ieee80211_sub_if_data *sdata,
>                  enum ieee80211_ampdu_mlme_action action,
>                  struct ieee80211_sta *sta, u16 tid,
> -                u16 *ssn),
> +                u16 *ssn, u8 buf_size),
> 
> -       TP_ARGS(local, sdata, action, sta, tid, ssn),
> +       TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size),
> 
>         TP_STRUCT__entry(
>                 LOCAL_ENTRY
> @@ -794,6 +794,7 @@ TRACE_EVENT(drv_ampdu_action,
>                 __field(u32, action)
>                 __field(u16, tid)
>                 __field(u16, ssn)
> +               __field(u8, buf_size)
>                 VIF_ENTRY
>         ),
> 
> @@ -804,11 +805,13 @@ TRACE_EVENT(drv_ampdu_action,
>                 __entry->action = action;
>                 __entry->tid = tid;
>                 __entry->ssn = ssn ? *ssn : 0;
> +               __entry->buf_size = buf_size;
>         ),
> 
>         TP_printk(
> -               LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d",
> -               LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid
> +               LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d",
> +               LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action,
> +               __entry->tid, __entry->buf_size
>         )
>  );
> 
> --- wireless-testing.orig/drivers/net/wireless/ath/ar9170/main.c        2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/ath/ar9170/main.c     2011-01-12 13:02:36.000000000 +0100
> @@ -1945,7 +1945,8 @@ static int ar9170_conf_tx(struct ieee802
>  static int ar9170_ampdu_action(struct ieee80211_hw *hw,
>                                struct ieee80211_vif *vif,
>                                enum ieee80211_ampdu_mlme_action action,
> -                              struct ieee80211_sta *sta, u16 tid, u16 *ssn)
> +                              struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                              u8 buf_size)
>  {
>         switch (action) {
>         case IEEE80211_AMPDU_RX_START:
> --- wireless-testing.orig/drivers/net/wireless/ath/ath9k/htc_drv_main.c 2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/ath/ath9k/htc_drv_main.c      2011-01-12 13:02:36.000000000 +0100
> @@ -1548,7 +1548,7 @@ static int ath9k_htc_ampdu_action(struct
>                                   struct ieee80211_vif *vif,
>                                   enum ieee80211_ampdu_mlme_action action,
>                                   struct ieee80211_sta *sta,
> -                                 u16 tid, u16 *ssn)
> +                                 u16 tid, u16 *ssn, u8 buf_size)
>  {
>         struct ath9k_htc_priv *priv = hw->priv;
>         struct ath9k_htc_sta *ista;
> --- wireless-testing.orig/drivers/net/wireless/ath/ath9k/main.c 2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/ath/ath9k/main.c      2011-01-12 13:02:36.000000000 +0100
> @@ -2018,7 +2018,7 @@ static int ath9k_ampdu_action(struct iee
>                               struct ieee80211_vif *vif,
>                               enum ieee80211_ampdu_mlme_action action,
>                               struct ieee80211_sta *sta,
> -                             u16 tid, u16 *ssn)
> +                             u16 tid, u16 *ssn, u8 buf_size)
>  {
>         struct ath_wiphy *aphy = hw->priv;
>         struct ath_softc *sc = aphy->sc;
> --- wireless-testing.orig/drivers/net/wireless/ath/carl9170/main.c      2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/ath/carl9170/main.c   2011-01-12 13:02:36.000000000 +0100
> @@ -1279,7 +1279,7 @@ static int carl9170_op_ampdu_action(stru
>                                     struct ieee80211_vif *vif,
>                                     enum ieee80211_ampdu_mlme_action action,
>                                     struct ieee80211_sta *sta,
> -                                   u16 tid, u16 *ssn)
> +                                   u16 tid, u16 *ssn, u8 buf_size)
>  {
>         struct ar9170 *ar = hw->priv;
>         struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
> --- wireless-testing.orig/drivers/net/wireless/iwlwifi/iwl-agn.c        2011-01-12 13:02:35.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/iwlwifi/iwl-agn.c     2011-01-12 13:02:36.000000000 +0100
> @@ -3416,7 +3416,8 @@ int iwlagn_mac_set_key(struct ieee80211_
>  int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
>                             struct ieee80211_vif *vif,
>                             enum ieee80211_ampdu_mlme_action action,
> -                           struct ieee80211_sta *sta, u16 tid, u16 *ssn)
> +                           struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                           u8 buf_size)
>  {
>         struct iwl_priv *priv = hw->priv;
>         int ret = -EINVAL;
> --- wireless-testing.orig/drivers/net/wireless/iwlwifi/iwl-agn.h        2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/iwlwifi/iwl-agn.h     2011-01-12 13:02:36.000000000 +0100
> @@ -363,7 +363,8 @@ void iwlagn_mac_update_tkip_key(struct i
>  int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
>                             struct ieee80211_vif *vif,
>                             enum ieee80211_ampdu_mlme_action action,
> -                           struct ieee80211_sta *sta, u16 tid, u16 *ssn);
> +                           struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                           u8 buf_size);
>  int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
>                        struct ieee80211_vif *vif,
>                        struct ieee80211_sta *sta);
> --- wireless-testing.orig/drivers/net/wireless/mac80211_hwsim.c 2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/mac80211_hwsim.c      2011-01-12 13:02:36.000000000 +0100
> @@ -943,7 +943,8 @@ static int mac80211_hwsim_testmode_cmd(s
>  static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
>                                        struct ieee80211_vif *vif,
>                                        enum ieee80211_ampdu_mlme_action action,
> -                                      struct ieee80211_sta *sta, u16 tid, u16 *ssn)
> +                                      struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                                      u8 buf_size)
>  {
>         switch (action) {
>         case IEEE80211_AMPDU_TX_START:
> --- wireless-testing.orig/drivers/net/wireless/mwl8k.c  2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/mwl8k.c       2011-01-12 13:02:36.000000000 +0100
> @@ -3932,7 +3932,8 @@ static int mwl8k_get_survey(struct ieee8
>  static int
>  mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                    enum ieee80211_ampdu_mlme_action action,
> -                  struct ieee80211_sta *sta, u16 tid, u16 *ssn)
> +                  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                  u8 buf_size)
>  {
>         switch (action) {
>         case IEEE80211_AMPDU_RX_START:
> --- wireless-testing.orig/drivers/net/wireless/rt2x00/rt2800lib.c       2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/rt2x00/rt2800lib.c    2011-01-12 13:02:36.000000000 +0100
> @@ -3530,7 +3530,8 @@ EXPORT_SYMBOL_GPL(rt2800_get_tsf);
> 
>  int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                         enum ieee80211_ampdu_mlme_action action,
> -                       struct ieee80211_sta *sta, u16 tid, u16 *ssn)
> +                       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                       u8 buf_size)
>  {
>         int ret = 0;
> 
> --- wireless-testing.orig/drivers/net/wireless/rt2x00/rt2800lib.h       2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/rt2x00/rt2800lib.h    2011-01-12 13:02:36.000000000 +0100
> @@ -198,7 +198,8 @@ int rt2800_conf_tx(struct ieee80211_hw *
>  u64 rt2800_get_tsf(struct ieee80211_hw *hw);
>  int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                         enum ieee80211_ampdu_mlme_action action,
> -                       struct ieee80211_sta *sta, u16 tid, u16 *ssn);
> +                       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                       u8 buf_size);
>  int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
>                       struct survey_info *survey);
> 
> --- wireless-testing.orig/drivers/net/wireless/rtlwifi/core.c   2011-01-12 13:02:27.000000000 +0100
> +++ wireless-testing/drivers/net/wireless/rtlwifi/core.c        2011-01-12 13:02:36.000000000 +0100
> @@ -748,7 +748,8 @@ static void rtl_op_sta_notify(struct iee
>  static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
>                                struct ieee80211_vif *vif,
>                                enum ieee80211_ampdu_mlme_action action,
> -                              struct ieee80211_sta *sta, u16 tid, u16 * ssn)
> +                              struct ieee80211_sta *sta, u16 tid, u16 *ssn,
> +                              u8 buf_size)
>  {
>         struct rtl_priv *rtlpriv = rtl_priv(hw);
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Björn Smedman @ 2011-01-12 17:06 UTC (permalink / raw)
  To: Rajkumar Manoharan; +Cc: linux-wireless
In-Reply-To: <1294842652-7406-1-git-send-email-rmanoharan@atheros.com>

On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
<rmanoharan@atheros.com> wrote:
> The commit ""ath9k: Add change_interface callback" was failed
> to update of hw opmode, ani and interrupt mask. This leads
> to break p2p functionality on ath9k. And the existing add and
> remove interface functions are not handling hw opmode and
> ANI properly.
>
> This patch combines the common code in interface callbacks
> and also takes care of multi-vif cases.

How does your patch handle the race condition between the interface
change done in process context and the beacon tasklet triggered by
SWBA?

Also, perhaps more applicable to the commit log than the patch, how
can opmode be properly handled in multi-vif cases? I mean let's say I
have two AP vifs and then change one into STA, is the opmode then STA?
Compare that to the case where I have two STA vifs and change one into
AP; so again I have one AP and one STA vif but this time opmode is AP,
right? I can see how I can be wrong about these examples but I can't
really see how the opmode concept can be properly handled in multi-vif
cases.

/Björn

^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Sujith @ 2011-01-12 17:22 UTC (permalink / raw)
  To: Björn Smedman; +Cc: Rajkumar Manoharan, linux-wireless
In-Reply-To: <AANLkTi=S6TFk88cY27KFZ2q5mCykMMSn17LnH=V95MST@mail.gmail.com>

Björn Smedman wrote:
> On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
> <rmanoharan@atheros.com> wrote:
> > The commit ""ath9k: Add change_interface callback" was failed
> > to update of hw opmode, ani and interrupt mask. This leads
> > to break p2p functionality on ath9k. And the existing add and
> > remove interface functions are not handling hw opmode and
> > ANI properly.
> >
> > This patch combines the common code in interface callbacks
> > and also takes care of multi-vif cases.
> 
> How does your patch handle the race condition between the interface
> change done in process context and the beacon tasklet triggered by
> SWBA?
> 
> Also, perhaps more applicable to the commit log than the patch, how
> can opmode be properly handled in multi-vif cases? I mean let's say I
> have two AP vifs and then change one into STA, is the opmode then STA?
> Compare that to the case where I have two STA vifs and change one into
> AP; so again I have one AP and one STA vif but this time opmode is AP,
> right? I can see how I can be wrong about these examples but I can't
> really see how the opmode concept can be properly handled in multi-vif
> cases.

The opmode should be calculated every time an interface is created/destroyed.

If an AP vif is already present when a STA is added, the opmode remains as AP.
if a STA vif is changed into AP mode, then the opmode should be changed to AP,
along with disabling PS for other STA interfaces.
If an AP is present and a STA is added, the beacon interval can't be different.
And there are a few other conditions as well...

And you are right, interface management is not protected with the beacon tasklet...

Sujith

^ permalink raw reply

* [PATCH] staging: brcm80211: fix suspend/resume issue in brcmsmac
From: Arend van Spriel @ 2011-01-12 17:59 UTC (permalink / raw)
  To: gregkh; +Cc: devel, linux-wireless

PCI PM suspend callback took down the interface and resume brought
it back up. In the mac80211 context this is done in subsequent calls.
Rework implementation so that suspend only stores config, and sets
PCI power state. The resume return to full power state (D0), restores
the config, and brings hardware back up. Full bringup is done by
subsequent mac80211 calls.

Reviewed-by: Brett Rudley <brudley@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/staging/brcm80211/brcmsmac/wl_mac80211.c |   28 ++++++++++++---------
 drivers/staging/brcm80211/brcmsmac/wl_mac80211.h |    4 +--
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
index c2663bd..8f11409 100644
--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
+++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
@@ -179,7 +179,6 @@ static void wl_ops_stop(struct ieee80211_hw *hw)
 	struct wl_info *wl = hw->priv;
 	ASSERT(wl);
 	WL_LOCK(wl);
-	wl_down(wl);
 	ieee80211_stop_queues(hw);
 	WL_UNLOCK(wl);
 
@@ -216,6 +215,14 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 static void
 wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
+	struct wl_info *wl;
+
+	wl = HW_TO_WL(hw);
+
+	/* put driver in down state */
+	WL_LOCK(wl);
+	wl_down(wl);
+	WL_UNLOCK(wl);
 	return;
 }
 
@@ -1059,7 +1066,6 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return 0;
 }
 
-#ifdef LINUXSTA_PS
 static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct wl_info *wl;
@@ -1074,11 +1080,12 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
 		return -ENODEV;
 	}
 
+	/* only need to flag hw is down for proper resume */
 	WL_LOCK(wl);
-	wl_down(wl);
 	wl->pub->hw_up = false;
 	WL_UNLOCK(wl);
-	pci_save_state(pdev, wl->pci_psstate);
+
+	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	return pci_set_power_state(pdev, PCI_D3hot);
 }
@@ -1102,7 +1109,7 @@ static int wl_resume(struct pci_dev *pdev)
 	if (err)
 		return err;
 
-	pci_restore_state(pdev, wl->pci_psstate);
+	pci_restore_state(pdev);
 
 	err = pci_enable_device(pdev);
 	if (err)
@@ -1114,13 +1121,12 @@ static int wl_resume(struct pci_dev *pdev)
 	if ((val & 0x0000ff00) != 0)
 		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
 
-	WL_LOCK(wl);
-	err = wl_up(wl);
-	WL_UNLOCK(wl);
-
+	/*
+	*  done. driver will be put in up state
+	*  in wl_ops_add_interface() call.
+	*/
 	return err;
 }
-#endif				/* LINUXSTA_PS */
 
 static void wl_remove(struct pci_dev *pdev)
 {
@@ -1155,10 +1161,8 @@ static void wl_remove(struct pci_dev *pdev)
 static struct pci_driver wl_pci_driver = {
 	.name  = KBUILD_MODNAME,
 	.probe = wl_pci_probe,
-#ifdef LINUXSTA_PS
 	.suspend = wl_suspend,
 	.resume  = wl_resume,
-#endif				/* LINUXSTA_PS */
 	.remove   = __devexit_p(wl_remove),
 	.id_table = wl_id_table,
 };
diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
index 070fa94..f6b7354 100644
--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
+++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
@@ -67,9 +67,7 @@ struct wl_info {
 	struct wl_timer *timers;	/* timer cleanup queue */
 	struct tasklet_struct tasklet;	/* dpc tasklet */
 	bool resched;		/* dpc needs to be and is rescheduled */
-#ifdef LINUXSTA_PS
-	u32 pci_psstate[16];	/* pci ps-state save/restore */
-#endif
+
 	/* RPC, handle, lock, txq, workitem */
 	uint stats_id;		/* the current set of stats */
 	/* ping-pong stats counters updated by Linux watchdog */
-- 
1.7.1



^ permalink raw reply related

* Re: [PATCH] staging: brcm80211: fix suspend/resume issue in brcmsmac
From: Greg KH @ 2011-01-12 18:08 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: devel, linux-wireless
In-Reply-To: <1294855167-3718-1-git-send-email-arend@broadcom.com>

On Wed, Jan 12, 2011 at 06:59:27PM +0100, Arend van Spriel wrote:
> PCI PM suspend callback took down the interface and resume brought
> it back up. In the mac80211 context this is done in subsequent calls.
> Rework implementation so that suspend only stores config, and sets
> PCI power state. The resume return to full power state (D0), restores
> the config, and brings hardware back up. Full bringup is done by
> subsequent mac80211 calls.

Ah, does this solve the suspend/resume bug that a number of people have
reported for the driver since the .36 release?  If so, should it go into
the kernel now and be backported to older releases?

thanks,

greg k-h

^ permalink raw reply

* experimental iwlwifi 5000 uCode available
From: Guy, Wey-Yi @ 2011-01-12 18:15 UTC (permalink / raw)
  To: linux-wireless

Hi 

Experimental version 8.83.5.1 of uCode for Intel@ 5000 Series WiFi
Adapters is now available for download from 
http://www.intellinuxwireless.org/?n=experimental

Experimental uCode is the WiFi uCode released by the Intel uCode team
with the latest bug fixes to address issues being reported by external
parties. The Experimental uCode has not gone through the full regression
test procedures, and the goal is to address the issue(s) that can’t be
easily reproduced within the internal testing environment.
 
Wey


^ permalink raw reply

* pull request: wireless-2.6 2011-01-12
From: John W. Linville @ 2011-01-12 18:37 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

Dave,

This is an initial batch of wireless fixes intended for 2.6.38-rc1.
Highlights include a number of small ath9k fixes, some documentation
fixes from Johannes, and an ssb fix that stops loading b44 inadvertently
when certain b43 devices are present.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit 5b919f833d9d60588d026ad82d17f17e8872c7a9:

  net: ax25: fix information leak to userland harder (2011-01-12 00:34:49 -0800)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master

Christian Lamparter (1):
      p54: fix sequence no. accounting off-by-one error

Indan Zupancic (1):
      ipw2200: Check for -1 INTA in tasklet too.

Johannes Berg (5):
      mac80211: add remain-on-channel docs
      mac80211: add missing docs for off-chan TX flag
      cfg80211: add mesh join/leave callback docs
      nl80211: add/fix mesh docs
      mac80211: add doc short section on LED triggers

Michael Buesch (1):
      ssb: Ignore dangling ethernet cores on wireless devices

Stanislaw Gruszka (1):
      hostap_cs: fix sleeping function called from invalid context

Sujith Manoharan (5):
      ath9k_hw: Fix chip test
      ath9k_hw: Fix calibration for AR9287 devices
      ath9k_hw: Fix thermal issue with UB94
      ath9k_hw: Fix RX handling for USB devices
      ath9k_htc: Really fix packet injection

 Documentation/DocBook/80211.tmpl              |   21 +++++++++++---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c |    3 ++
 drivers/net/wireless/ath/ath9k/eeprom_def.c   |    4 +++
 drivers/net/wireless/ath/ath9k/htc.h          |    1 +
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |   37 +++++++++++++++++-------
 drivers/net/wireless/ath/ath9k/hw.c           |    5 ++-
 drivers/net/wireless/hostap/hostap_cs.c       |   15 ++++------
 drivers/net/wireless/ipw2x00/ipw2200.c        |    7 +++++
 drivers/net/wireless/p54/txrx.c               |    2 +-
 drivers/ssb/scan.c                            |   10 +++++++
 include/linux/nl80211.h                       |   20 ++++++++++---
 include/net/cfg80211.h                        |    2 +
 include/net/mac80211.h                        |   14 +++++++++
 13 files changed, 109 insertions(+), 32 deletions(-)

diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 03641a0..8906648 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -268,10 +268,6 @@
 !Finclude/net/mac80211.h ieee80211_ops
 !Finclude/net/mac80211.h ieee80211_alloc_hw
 !Finclude/net/mac80211.h ieee80211_register_hw
-!Finclude/net/mac80211.h ieee80211_get_tx_led_name
-!Finclude/net/mac80211.h ieee80211_get_rx_led_name
-!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
-!Finclude/net/mac80211.h ieee80211_get_radio_led_name
 !Finclude/net/mac80211.h ieee80211_unregister_hw
 !Finclude/net/mac80211.h ieee80211_free_hw
       </chapter>
@@ -382,6 +378,23 @@
         </para>
       </partintro>
 
+      <chapter id="led-support">
+        <title>LED support</title>
+        <para>
+         Mac80211 supports various ways of blinking LEDs. Wherever possible,
+         device LEDs should be exposed as LED class devices and hooked up to
+         the appropriate trigger, which will then be triggered appropriately
+         by mac80211.
+        </para>
+!Finclude/net/mac80211.h ieee80211_get_tx_led_name
+!Finclude/net/mac80211.h ieee80211_get_rx_led_name
+!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
+!Finclude/net/mac80211.h ieee80211_get_radio_led_name
+!Finclude/net/mac80211.h ieee80211_tpt_blink
+!Finclude/net/mac80211.h ieee80211_tpt_led_trigger_flags
+!Finclude/net/mac80211.h ieee80211_create_tpt_led_trigger
+      </chapter>
+
       <chapter id="hardware-crypto-offload">
         <title>Hardware crypto acceleration</title>
 !Pinclude/net/mac80211.h Hardware crypto acceleration
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 01880aa..ea2e7d7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -954,6 +954,9 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
 				&adc_dc_cal_multi_sample;
 		}
 		ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+
+		if (AR_SREV_9287(ah))
+			ah->supp_cals &= ~ADC_GAIN_CAL;
 	}
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 088f141..749a936 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -226,6 +226,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
 	    eep->baseEepHeader.pwdclkind == 0)
 		ah->need_an_top2_fixup = 1;
 
+	if ((common->bus_ops->ath_bus_type == ATH_USB) &&
+	    (AR_SREV_9280(ah)))
+		eep->modalHeader[0].xpaBiasLvl = 0;
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index a099b3e..1ce506f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -433,6 +433,7 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
 void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
 			enum htc_endpoint_id ep_id, bool txok);
 
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
 void ath9k_htc_station_work(struct work_struct *work);
 void ath9k_htc_aggr_work(struct work_struct *work);
 void ath9k_ani_work(struct work_struct *work);;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 845b4c9..f4d576b 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -301,6 +301,16 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
 
 	priv->nstations++;
 
+	/*
+	 * Set chainmask etc. on the target.
+	 */
+	ret = ath9k_htc_update_cap_target(priv);
+	if (ret)
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"Failed to update capability in target\n");
+
+	priv->ah->is_monitoring = true;
+
 	return 0;
 
 err_vif:
@@ -328,6 +338,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
 	}
 
 	priv->nstations--;
+	priv->ah->is_monitoring = false;
 
 	return 0;
 }
@@ -419,7 +430,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
 	return 0;
 }
 
-static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
 {
 	struct ath9k_htc_cap_target tcap;
 	int ret;
@@ -1186,6 +1197,20 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
 		}
 	}
 
+	/*
+	 * Monitor interface should be added before
+	 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
+	 */
+	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+		if (conf->flags & IEEE80211_CONF_MONITOR) {
+			if (ath9k_htc_add_monitor_interface(priv))
+				ath_err(common, "Failed to set monitor mode\n");
+			else
+				ath_dbg(common, ATH_DBG_CONFIG,
+					"HW opmode set to Monitor mode\n");
+		}
+	}
+
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		struct ieee80211_channel *curchan = hw->conf.channel;
 		int pos = curchan->hw_value;
@@ -1221,16 +1246,6 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
 		ath_update_txpow(priv);
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
-		if (conf->flags & IEEE80211_CONF_MONITOR) {
-			if (ath9k_htc_add_monitor_interface(priv))
-				ath_err(common, "Failed to set monitor mode\n");
-			else
-				ath_dbg(common, ATH_DBG_CONFIG,
-					"HW opmode set to Monitor mode\n");
-		}
-	}
-
 	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
 		mutex_lock(&priv->htc_pm_lock);
 		if (!priv->ps_idle) {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index fde9786..1afb8bb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -436,9 +436,10 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 
 static int ath9k_hw_post_init(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	int ecode;
 
-	if (!AR_SREV_9271(ah)) {
+	if (common->bus_ops->ath_bus_type != ATH_USB) {
 		if (!ath9k_hw_chip_test(ah))
 			return -ENODEV;
 	}
@@ -1213,7 +1214,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	ah->txchainmask = common->tx_chainmask;
 	ah->rxchainmask = common->rx_chainmask;
 
-	if (!ah->chip_fullsleep) {
+	if ((common->bus_ops->ath_bus_type != ATH_USB) && !ah->chip_fullsleep) {
 		ath9k_hw_abortpcurecv(ah);
 		if (!ath9k_hw_stopdmarecv(ah)) {
 			ath_dbg(common, ATH_DBG_XMIT,
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index bd8a413..2176ede 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -518,22 +518,21 @@ static int prism2_config(struct pcmcia_device *link)
 	hw_priv->link = link;
 
 	/*
-	 * Make sure the IRQ handler cannot proceed until at least
-	 * dev->base_addr is initialized.
+	 * We enable IRQ here, but IRQ handler will not proceed
+	 * until dev->base_addr is set below. This protect us from
+	 * receive interrupts when driver is not initialized.
 	 */
-	spin_lock_irqsave(&local->irq_init_lock, flags);
-
 	ret = pcmcia_request_irq(link, prism2_interrupt);
 	if (ret)
-		goto failed_unlock;
+		goto failed;
 
 	ret = pcmcia_enable_device(link);
 	if (ret)
-		goto failed_unlock;
+		goto failed;
 
+	spin_lock_irqsave(&local->irq_init_lock, flags);
 	dev->irq = link->irq;
 	dev->base_addr = link->resource[0]->start;
-
 	spin_unlock_irqrestore(&local->irq_init_lock, flags);
 
 	local->shutdown = 0;
@@ -546,8 +545,6 @@ static int prism2_config(struct pcmcia_device *link)
 
 	return ret;
 
- failed_unlock:
-	spin_unlock_irqrestore(&local->irq_init_lock, flags);
  failed:
 	kfree(hw_priv);
 	prism2_release((u_long)link);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 8d6ed5f..ae438ed 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -1973,6 +1973,13 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
 
 	inta = ipw_read32(priv, IPW_INTA_RW);
 	inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
+
+	if (inta == 0xFFFFFFFF) {
+		/* Hardware disappeared */
+		IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n");
+		/* Only handle the cached INTA values */
+		inta = 0;
+	}
 	inta &= (IPW_INTA_MASK_ALL & inta_mask);
 
 	/* Add any cached INTA values that need to be handled */
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 76b2318..f618b96 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -618,7 +618,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
 	else
 		*burst_possible = false;
 
-	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+	if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
 		*flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
 
 	if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 5a0985d..29884c0 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -420,6 +420,16 @@ int ssb_bus_scan(struct ssb_bus *bus,
 			bus->pcicore.dev = dev;
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 			break;
+		case SSB_DEV_ETHERNET:
+			if (bus->bustype == SSB_BUSTYPE_PCI) {
+				if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
+				    (bus->host_pci->device & 0xFF00) == 0x4300) {
+					/* This is a dangling ethernet core on a
+					 * wireless device. Ignore it. */
+					continue;
+				}
+			}
+			break;
 		default:
 			break;
 		}
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 2b89b71..821ffb9 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -148,6 +148,10 @@
  * @NL80211_CMD_SET_MPATH:  Set mesh path attributes for mesh path to
  * 	destination %NL80211_ATTR_MAC on the interface identified by
  * 	%NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by
+ *	%NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP.
+ * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by
+ *	%NL80211_ATTR_MAC.
  * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
  *	the interface identified by %NL80211_ATTR_IFINDEX.
  * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
@@ -612,7 +616,7 @@ enum nl80211_commands {
  *	consisting of a nested array.
  *
  * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes).
- * @NL80211_ATTR_PLINK_ACTION: action to perform on the mesh peer link.
+ * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link.
  * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
  * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
  * 	info given for %NL80211_CMD_GET_MPATH, nested attribute described at
@@ -879,7 +883,9 @@ enum nl80211_commands {
  *	See &enum nl80211_key_default_types.
  *
  * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters.  These cannot be
- * changed once the mesh is active.
+ *	changed once the mesh is active.
+ * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
+ *	containing attributes from &enum nl80211_meshconf_params.
  *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1225,8 +1231,6 @@ enum nl80211_rate_info {
  * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs)
  * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station)
  * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station)
- * @__NL80211_STA_INFO_AFTER_LAST: internal
- * @NL80211_STA_INFO_MAX: highest possible station info attribute
  * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
  * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
  * 	containing info as possible, see &enum nl80211_sta_info_txrate.
@@ -1236,6 +1240,11 @@ enum nl80211_rate_info {
  * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
  * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
  * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm)
+ * @NL80211_STA_INFO_LLID: the station's mesh LLID
+ * @NL80211_STA_INFO_PLID: the station's mesh PLID
+ * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
+ * @__NL80211_STA_INFO_AFTER_LAST: internal
+ * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
 enum nl80211_sta_info {
 	__NL80211_STA_INFO_INVALID,
@@ -1626,7 +1635,7 @@ enum nl80211_mntr_flags {
  * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
  * that it takes for an HWMP information element to propagate across the mesh
  *
- * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
+ * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not
  *
  * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
  * source mesh point for path selection elements.
@@ -1678,6 +1687,7 @@ enum nl80211_meshconf_params {
  * element that vendors will use to identify the path selection methods and
  * metrics in use.
  *
+ * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
  * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
  */
 enum nl80211_mesh_setup_params {
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bcc9f44..1322695 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1103,6 +1103,8 @@ struct cfg80211_pmksa {
  * @change_mpath: change a given mesh path
  * @get_mpath: get a mesh path for the given parameters
  * @dump_mpath: dump mesh path callback -- resume dump at index @idx
+ * @join_mesh: join the mesh network with the specified parameters
+ * @leave_mesh: leave the current mesh network
  *
  * @get_mesh_config: Get the current mesh configuration
  *
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5b3fd5a..62c0ce2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -337,6 +337,10 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
  * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this
  *	frame and selects the maximum number of streams that it can use.
+ * @IEEE80211_TX_CTL_TX_OFFCHAN: Marks this packet to be transmitted on
+ *	the off-channel channel when a remain-on-channel offload is done
+ *	in hardware -- normal packets still flow and are expected to be
+ *	handled properly by the device.
  *
  * Note: If you have to add new flags to the enumeration, then don't
  *	 forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
@@ -1753,6 +1757,16 @@ enum ieee80211_ampdu_mlme_action {
  *	(also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX).
  *
  * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
+ *
+ * @remain_on_channel: Starts an off-channel period on the given channel, must
+ *	call back to ieee80211_ready_on_channel() when on that channel. Note
+ *	that normal channel traffic is not stopped as this is intended for hw
+ *	offload. Frames to transmit on the off-channel channel are transmitted
+ *	normally except for the %IEEE80211_TX_CTL_TX_OFFCHAN flag. When the
+ *	duration (which will always be non-zero) expires, the driver must call
+ *	ieee80211_remain_on_channel_expired(). This callback may sleep.
+ * @cancel_remain_on_channel: Requests that an ongoing off-channel period is
+ *	aborted before it expires. This callback may sleep.
  */
 struct ieee80211_ops {
 	int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply related

* Re: [RFC] ath9k: Handle interface changes properly
From: Björn Smedman @ 2011-01-12 19:00 UTC (permalink / raw)
  To: Sujith; +Cc: Rajkumar Manoharan, linux-wireless
In-Reply-To: <19757.58191.865301.805439@gargle.gargle.HOWL>

2011/1/12 Sujith <m.sujith@gmail.com>:
> Björn Smedman wrote:
>> Also, perhaps more applicable to the commit log than the patch, how
>> can opmode be properly handled in multi-vif cases? I mean let's say I
>> have two AP vifs and then change one into STA, is the opmode then STA?
>> Compare that to the case where I have two STA vifs and change one into
>> AP; so again I have one AP and one STA vif but this time opmode is AP,
>> right? I can see how I can be wrong about these examples but I can't
>> really see how the opmode concept can be properly handled in multi-vif
>> cases.
>
> The opmode should be calculated every time an interface is created/destroyed.
>
> If an AP vif is already present when a STA is added, the opmode remains as AP.
> if a STA vif is changed into AP mode, then the opmode should be changed to AP,
> along with disabling PS for other STA interfaces.
> If an AP is present and a STA is added, the beacon interval can't be different.
> And there are a few other conditions as well...

Thank you Sujith for the clarification. When you lay out the cases it
makes more sense. But there are still border cases, like e.g. adding
first a STA and then an AP interface. If I read main.c correctly the
opmode will then be STA and the AP vif will be broken, right?

Wouldn't it be better to keep counts of number of vifs by type and
e.g. activate SWBA if (adhocvifs > 0 || apvifs > 0) and similar? Then
it wouldn't mater in which order vifs are added, removed and changed.

/Björn

^ permalink raw reply

* Re: [PATCH] staging: brcm80211: fix suspend/resume issue in brcmsmac
From: Henry Ptasinski @ 2011-01-12 19:44 UTC (permalink / raw)
  To: Greg KH
  Cc: Arend Van Spriel, devel@linuxdriverproject.org,
	linux-wireless@vger.kernel.org, Henry Ptasinski
In-Reply-To: <20110112180829.GB10224@suse.de>

On Wed, Jan 12, 2011 at 10:08:29AM -0800, Greg KH wrote:
> On Wed, Jan 12, 2011 at 06:59:27PM +0100, Arend van Spriel wrote:
> > PCI PM suspend callback took down the interface and resume brought
> > it back up. In the mac80211 context this is done in subsequent calls.
> > Rework implementation so that suspend only stores config, and sets
> > PCI power state. The resume return to full power state (D0), restores
> > the config, and brings hardware back up. Full bringup is done by
> > subsequent mac80211 calls.
> 
> Ah, does this solve the suspend/resume bug that a number of people have
> reported for the driver since the .36 release?  If so, should it go into
> the kernel now and be backported to older releases?


Yes, this should solve the suspend/resume bug that people have reported. 
(It doesn't solve the rfkill issues; Arend is working on a separate fix for
that.)

It should get backported, but it would be nice to get some confirmation from
people that it fixes the issues they're seeing first.

- Henry



^ permalink raw reply

* Re: [RFC] ath9k: Handle interface changes properly
From: Felix Fietkau @ 2011-01-12 19:51 UTC (permalink / raw)
  To: Björn Smedman; +Cc: Rajkumar Manoharan, linux-wireless
In-Reply-To: <AANLkTi=S6TFk88cY27KFZ2q5mCykMMSn17LnH=V95MST@mail.gmail.com>

On 2011-01-12 10:06 AM, Björn Smedman wrote:
> On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
> <rmanoharan@atheros.com>  wrote:
>>  The commit ""ath9k: Add change_interface callback" was failed
>>  to update of hw opmode, ani and interrupt mask. This leads
>>  to break p2p functionality on ath9k. And the existing add and
>>  remove interface functions are not handling hw opmode and
>>  ANI properly.
>>
>>  This patch combines the common code in interface callbacks
>>  and also takes care of multi-vif cases.
>
> How does your patch handle the race condition between the interface
> change done in process context and the beacon tasklet triggered by
> SWBA?
>
> Also, perhaps more applicable to the commit log than the patch, how
> can opmode be properly handled in multi-vif cases? I mean let's say I
> have two AP vifs and then change one into STA, is the opmode then STA?
> Compare that to the case where I have two STA vifs and change one into
> AP; so again I have one AP and one STA vif but this time opmode is AP,
> right? I can see how I can be wrong about these examples but I can't
> really see how the opmode concept can be properly handled in multi-vif
> cases.
I think opmode should be handled as follows:
If there is at least one AP interface, opmode should be AP, regardless 
of what the other interfaces are set to.
If there is no AP vif, opmode can be set to the primary vif type.

- Felix

^ permalink raw reply

* Compat-wireless release for 2011-01-12 is baked
From: Compat-wireless cronjob account @ 2011-01-12 20:04 UTC (permalink / raw)
  To: linux-wireless

>From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
   5ef1982..4e7a997  history    -> origin/history
 + 2cc48ac...4df1d0b master     -> origin/master  (forced update)
   e0e736f..7bc4a4c  stable     -> origin/stable
 * [new tag]         next-20110112 -> next-20110112

compat-wireless code metrics

    782547 - Total upstream lines of code being pulled
      2103 - backport code changes
      1843 - backport code additions
       260 - backport code deletions
      7279 - backport from compat module
      9382 - total backport code
    1.1989 - % of code consists of backport work
      1531 - Crap changes not yet posted
      1488 - Crap additions not yet posted
        43 - Crap deletions not yet posted
    0.1956 - % of crap code

Base tree: linux-next.git
Base tree version: next-20110112
compat-wireless release: compat-wireless-2011-01-06-pc

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox