Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v5] cfg80211: Add nl80211 antenna configuration
From: Johannes Berg @ 2010-08-02 11:01 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: Luis R. Rodriguez, Bruno Randolf, linville, linux-wireless
In-Reply-To: <4C56A251.7080903@openwrt.org>

On Mon, 2010-08-02 at 12:47 +0200, Felix Fietkau wrote:

> Legacy hardware  => run time changes possible (actually optional)
> 802.11n hardware => need to bring down the interface before changing
>                     the antenna settings

I think I'd prefer if all hw just required the device to be stopped.
Otherwise things either become awkward when you have, say. software
diversity control, or they become unpredictable quite, no?

johannes


^ permalink raw reply

* Re: [PATCH v5] cfg80211: Add nl80211 antenna configuration
From: Felix Fietkau @ 2010-08-02 11:18 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Bruno Randolf, johannes, linville, linux-wireless
In-Reply-To: <AANLkTimWpvOQrdgP=1+4zm2=feN51G_+_LAnPgaQqUuF@mail.gmail.com>

On 2010-08-02 12:51 PM, Luis R. Rodriguez wrote:
> On Mon, Aug 2, 2010 at 3:47 AM, Felix Fietkau <nbd@openwrt.org> wrote:
>> 802.11n hardware => need to bring down the interface before changing
>>                    the antenna settings
> 
> The current patch does not deal with the 802.11n case you mentioned.
And why should it? The series does not add antenna control support to
any specific 802.11n driver.

- Felix

^ permalink raw reply

* Re: [PATCH v5] cfg80211: Add nl80211 antenna configuration
From: Felix Fietkau @ 2010-08-02 11:19 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Luis R. Rodriguez, Bruno Randolf, linville, linux-wireless
In-Reply-To: <1280746893.3923.12.camel@jlt3.sipsolutions.net>

On 2010-08-02 1:01 PM, Johannes Berg wrote:
> On Mon, 2010-08-02 at 12:47 +0200, Felix Fietkau wrote:
> 
>> Legacy hardware  => run time changes possible (actually optional)
>> 802.11n hardware => need to bring down the interface before changing
>>                     the antenna settings
> 
> I think I'd prefer if all hw just required the device to be stopped.
> Otherwise things either become awkward when you have, say. software
> diversity control, or they become unpredictable quite, no?
If the driver does something like that, then the antenna control
callback should reset that state as well. But then again, I don't mind
if legacy hw requires the interface to be down as well.

- Felix

^ permalink raw reply

* Re: [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Tony Lindgren @ 2010-08-02 11:42 UTC (permalink / raw)
  To: Luciano Coelho
  Cc: ext John W. Linville, Ohad Ben-Cohen,
	linux-wireless@vger.kernel.org, linux-mmc@vger.kernel.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux@arm.linux.org.uk, Chikkature Rajashekar Madhusudhan,
	akpm@linux-foundation.org, San Mehat,
	Quadros Roger (Nokia-MS/Helsinki), Nicolas Pitre, Pandita Vikram,
	Kalle Valo
In-Reply-To: <1280736987.17809.18.camel@chilepepper>

* Luciano Coelho <luciano.coelho@nokia.com> [100802 11:10]:
> On Mon, 2010-07-26 at 21:30 +0200, ext John W. Linville wrote:
> > On Wed, Jul 21, 2010 at 08:33:34PM +0300, Ohad Ben-Cohen wrote:
> > > This patch series adds native support for wl1271 on ZOOM.
> > 
> > Just for the record, I'm fine with the wl1271 bits here going through
> > the omap tree with the rest of the series.
> 
> Yeah, I agree.  This is probably the best way to keep things in sync.

OK, let's do that then. 

Nicolas Pitre made a comment saying he wants to look at these patches
more, are there other pending comments?

Regards,

Tony

^ permalink raw reply

* wireless-regdb: Why crda db.txt disallows 40Mhz BW on Channel 12-13 for JP?
From: yogeshp @ 2010-08-02 11:55 UTC (permalink / raw)
  To: linville@tuxdriver.com; +Cc: linux-wireless@vger.kernel.org

Hello All,

Crda db.txt has following entries for JP:
        (2402 - 2472 @ 40), (N/A, 20)
        (2457 - 2482 @ 20), (N/A, 20)

Why are channel 12 and 13 for JP disallowed to operate in 40Mhz by this file? 

As per Annex 11J of latest 802.11n spec, for Japan, channel 1-7 are allowed in HT40+ and channel 5-13 are allowed in HT40- mode.

Thanks,
Yogesh


^ permalink raw reply

* Re: [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Ohad Ben-Cohen @ 2010-08-02 12:08 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Luciano Coelho, ext John W. Linville,
	linux-wireless@vger.kernel.org, linux-mmc@vger.kernel.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux@arm.linux.org.uk, Chikkature Rajashekar Madhusudhan,
	akpm@linux-foundation.org, San Mehat,
	Quadros Roger (Nokia-MS/Helsinki), Nicolas Pitre, Pandita Vikram,
	Kalle Valo
In-Reply-To: <20100802114256.GE12293@atomide.com>

On Mon, Aug 2, 2010 at 2:42 PM, Tony Lindgren <tony@atomide.com> wrote:
> Nicolas Pitre made a comment saying he wants to look at these patches
> more, are there other pending comments?

I plan to post a v3 series this week with some of the comments that
were already discussed after v2.

Thanks everyone for the attention,
Ohad.

>
> Regards,
>
> Tony
>

^ permalink raw reply

* Re: [PATCH 01/11] pcmcia: use pcmica_{read,write}_config_byte
From: Komuro @ 2010-08-02 11:59 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: linux-pcmcia, netdev, linux-wireless, linux-serial,
	Dominik Brodowski, Michael Buesch
In-Reply-To: <1280667550-3040-1-git-send-email-linux@dominikbrodowski.net>

Hi,

>--- a/drivers/net/pcmcia/xirc2ps_cs.c
>+++ b/drivers/net/pcmcia/xirc2ps_cs.c


>+	if (err)
> 	    goto config_error;
>-	reg.Action = CS_WRITE;
>-	reg.Offset = CISREG_IOBASE_1;
>-	reg.Value = (link->io.BasePort2 >> 8) & 0xff;
>-	if ((err = pcmcia_access_configuration_register(link, &reg)))
>+
>+	err = pcmcia_write_config_byte(link, CISREG_IOBASE_1,
>+				link->io.BasePort2 & 0xff);

It should be

	err = pcmcia_write_config_byte(link, CISREG_IOBASE_1,
				(link->io.BasePort2 >> 8) & 0xff);




^ permalink raw reply

* [PATCH 1/3] mac80211: put rx handlers into seperate functions
From: Christian Lamparter @ 2010-08-02 13:15 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville

Note: In order to keep diff from removing and re-adding code,
I used forward declarations. So it should be easier to verify
that I didn't change anything related to the reordering logic.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
WIP -> PATCH:
	- no changes
---
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fa0f37e..8179e62 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -574,6 +574,11 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
 	}
 }
 
+static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+					  struct tid_ampdu_rx *tid_agg_rx,
+					  struct sk_buff_head *frames);
+
+
 /*
  * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
  * the skb was added to the buffer longer than this time ago, the earlier
@@ -643,6 +648,17 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 	tid_agg_rx->reorder_buf[index] = skb;
 	tid_agg_rx->reorder_time[index] = jiffies;
 	tid_agg_rx->stored_mpdu_num++;
+	ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);
+
+	return true;
+}
+
+static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+					  struct tid_ampdu_rx *tid_agg_rx,
+					  struct sk_buff_head *frames)
+{
+	int index;
+
 	/* release the buffer until next missing frame */
 	index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
 						tid_agg_rx->buf_size;
@@ -686,8 +702,6 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 		index =	seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
 							tid_agg_rx->buf_size;
 	}
-
-	return true;
 }
 
 /*
@@ -2267,6 +2281,11 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
 	dev_kfree_skb(skb);
 }
 
+static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+					 ieee80211_rx_result res);
+
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+				  struct sk_buff_head *frames);
 
 static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
 					 struct ieee80211_rx_data *rx,
@@ -2288,17 +2307,34 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
 			goto rxh_next;  \
 	} while (0);
 
-	/*
-	 * NB: the rxh_next label works even if we jump
-	 *     to it from here because then the list will
-	 *     be empty, which is a trivial check
-	 */
 	CALL_RXH(ieee80211_rx_h_passive_scan)
 	CALL_RXH(ieee80211_rx_h_check)
 
 	ieee80211_rx_reorder_ampdu(rx, &reorder_release);
 
-	while ((skb = __skb_dequeue(&reorder_release))) {
+	ieee80211_rx_handlers(rx, &reorder_release);
+	return;
+
+ rxh_next:
+	ieee80211_rx_handlers_result(rx, res);
+
+#undef CALL_RXH
+}
+
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+				  struct sk_buff_head *frames)
+{
+	ieee80211_rx_result res = RX_DROP_MONITOR;
+	struct sk_buff *skb;
+
+#define CALL_RXH(rxh)			\
+	do {				\
+		res = rxh(rx);		\
+		if (res != RX_CONTINUE)	\
+			goto rxh_next;  \
+	} while (0);
+
+	while ((skb = __skb_dequeue(frames))) {
 		/*
 		 * all the other fields are valid across frames
 		 * that belong to an aMPDU since they are on the
@@ -2316,41 +2352,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
 		CALL_RXH(ieee80211_rx_h_remove_qos_control)
 		CALL_RXH(ieee80211_rx_h_amsdu)
 #ifdef CONFIG_MAC80211_MESH
-		if (ieee80211_vif_is_mesh(&sdata->vif))
+		if (ieee80211_vif_is_mesh(&rx->sdata->vif))
 			CALL_RXH(ieee80211_rx_h_mesh_fwding);
 #endif
 		CALL_RXH(ieee80211_rx_h_data)
 
 		/* special treatment -- needs the queue */
-		res = ieee80211_rx_h_ctrl(rx, &reorder_release);
+		res = ieee80211_rx_h_ctrl(rx, frames);
 		if (res != RX_CONTINUE)
 			goto rxh_next;
 
 		CALL_RXH(ieee80211_rx_h_action)
 		CALL_RXH(ieee80211_rx_h_mgmt)
 
+ rxh_next:
+		ieee80211_rx_handlers_result(rx, res);
+
 #undef CALL_RXH
+	}
+}
 
- rxh_next:
-		switch (res) {
-		case RX_DROP_MONITOR:
-			I802_DEBUG_INC(sdata->local->rx_handlers_drop);
-			if (rx->sta)
-				rx->sta->rx_dropped++;
-			/* fall through */
-		case RX_CONTINUE:
-			ieee80211_rx_cooked_monitor(rx, rate);
-			break;
-		case RX_DROP_UNUSABLE:
-			I802_DEBUG_INC(sdata->local->rx_handlers_drop);
-			if (rx->sta)
-				rx->sta->rx_dropped++;
-			dev_kfree_skb(rx->skb);
-			break;
-		case RX_QUEUED:
-			I802_DEBUG_INC(sdata->local->rx_handlers_queued);
-			break;
+static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+					 ieee80211_rx_result res)
+{
+	switch (res) {
+	case RX_DROP_MONITOR:
+		I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+		if (rx->sta)
+			rx->sta->rx_dropped++;
+		/* fall through */
+	case RX_CONTINUE: {
+		struct ieee80211_rate *rate = NULL;
+		struct ieee80211_supported_band *sband;
+		struct ieee80211_rx_status *status;
+
+		status = IEEE80211_SKB_RXCB((rx->skb));
+
+		sband = rx->local->hw.wiphy->bands[status->band];
+		if (!(status->flag & RX_FLAG_HT))
+			rate = &sband->bitrates[status->rate_idx];
+
+		ieee80211_rx_cooked_monitor(rx, rate);
+		break;
 		}
+	case RX_DROP_UNUSABLE:
+		I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+		if (rx->sta)
+			rx->sta->rx_dropped++;
+		dev_kfree_skb(rx->skb);
+		break;
+	case RX_QUEUED:
+		I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
+		break;
 	}
 }
 

^ permalink raw reply related

* [PATCH 2/3] mac80211: remove unused rate function parameters
From: Christian Lamparter @ 2010-08-02 13:15 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg j, John W. Linville

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
WIP -> PATCH:
	- no changes
---
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8179e62..6cb5541 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -538,20 +538,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
 					    int index,
 					    struct sk_buff_head *frames)
 {
-	struct ieee80211_supported_band *sband;
-	struct ieee80211_rate *rate = NULL;
 	struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
-	struct ieee80211_rx_status *status;
 
 	if (!skb)
 		goto no_frame;
 
-	status = IEEE80211_SKB_RXCB(skb);
-
-	/* release the reordered frames to stack */
-	sband = hw->wiphy->bands[status->band];
-	if (!(status->flag & RX_FLAG_HT))
-		rate = &sband->bitrates[status->rate_idx];
+	/* release the frame from the reorder ring buffer */
 	tid_agg_rx->stored_mpdu_num--;
 	tid_agg_rx->reorder_buf[index] = NULL;
 	__skb_queue_tail(frames, skb);
@@ -2289,8 +2281,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
 
 static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
 					 struct ieee80211_rx_data *rx,
-					 struct sk_buff *skb,
-					 struct ieee80211_rate *rate)
+					 struct sk_buff *skb)
 {
 	struct sk_buff_head reorder_release;
 	ieee80211_rx_result res = RX_DROP_MONITOR;
@@ -2500,8 +2491,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
  * be called with rcu_read_lock protection.
  */
 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
-					 struct sk_buff *skb,
-					 struct ieee80211_rate *rate)
+					 struct sk_buff *skb)
 {
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_local *local = hw_to_local(hw);
@@ -2609,7 +2599,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 					       prev->name);
 				goto next;
 			}
-			ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
+			ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
 next:
 			prev = sdata;
 		}
@@ -2625,7 +2615,7 @@ next:
 		}
 	}
 	if (prev)
-		ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
+		ieee80211_invoke_rx_handlers(prev, &rx, skb);
 	else
 		dev_kfree_skb(skb);
 }
@@ -2711,7 +2701,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
 		return;
 	}
 
-	__ieee80211_rx_handle_packet(hw, skb, rate);
+	__ieee80211_rx_handle_packet(hw, skb);
 
 	rcu_read_unlock();
 

^ permalink raw reply related

* [PATCH 3/3] mac80211: AMPDU rx reorder timeout timer
From: Christian Lamparter @ 2010-08-02 13:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville
In-Reply-To: <201007281721.51568.chunkeey@googlemail.com>

Everytime a hole is discovered in the reorder ring-buffer,
the release timer (for this tid_ampdu_rx) is set to fire
after HT_RX_REORDER_BUF_TIMEOUT jiffies.
 
If the missing frame(s) is/are arriving in time, the
timer gets deactivated/postponed(another hole has opened up).

Else, timer releases all expired frames after the timeout
period has elapsed.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
WIP -> PATCH:
	- thread-safe ampdu reordering
	- do the reorder release in the timer
---
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 965b272..080d792 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -86,6 +86,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
 				     tid, 0, reason);
 
 	del_timer_sync(&tid_rx->session_timer);
+	del_timer_sync(&tid_rx->reorder_timer);
 
 	call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
 }
@@ -120,6 +121,16 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
 	ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
 }
 
+static void sta_rx_agg_reorder_timer_expired(unsigned long data)
+{
+	u8 *ptid = (u8 *)data;
+	u8 *timer_to_id = ptid - *ptid;
+	struct sta_info *sta = container_of(timer_to_id, struct sta_info,
+			timer_to_tid[0]);
+
+	ieee80211_release_reorder_timeout(sta, *ptid);
+}
+
 static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
 				      u8 dialog_token, u16 status, u16 policy,
 				      u16 buf_size, u16 timeout)
@@ -251,11 +262,18 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 		goto end;
 	}
 
+	spin_lock_init(&tid_agg_rx->lock);
+
 	/* rx timer */
 	tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired;
 	tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
 	init_timer(&tid_agg_rx->session_timer);
 
+	/* rx reorder timer */
+	tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;
+	tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];
+	init_timer(&tid_agg_rx->reorder_timer);
+
 	/* prepare reordering buffer */
 	tid_agg_rx->reorder_buf =
 		kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ef47006..9d1ce88 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1130,6 +1130,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
 void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
 void ieee80211_ba_session_work(struct work_struct *work);
 void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid);
+void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid);
 
 /* Spectrum management */
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6cb5541..37d818d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -595,14 +595,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 	u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
 	u16 head_seq_num, buf_size;
 	int index;
+	bool ret = true;
 
 	buf_size = tid_agg_rx->buf_size;
 	head_seq_num = tid_agg_rx->head_seq_num;
 
+	spin_lock(&tid_agg_rx->lock);
 	/* frame with out of date sequence number */
 	if (seq_less(mpdu_seq_num, head_seq_num)) {
 		dev_kfree_skb(skb);
-		return true;
+		goto out;
 	}
 
 	/*
@@ -623,7 +625,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 	/* check if we already stored this frame */
 	if (tid_agg_rx->reorder_buf[index]) {
 		dev_kfree_skb(skb);
-		return true;
+		goto out;
 	}
 
 	/*
@@ -633,7 +635,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 	if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
 	    tid_agg_rx->stored_mpdu_num == 0) {
 		tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
-		return false;
+		ret = false;
+		goto out;
 	}
 
 	/* put the frame in the reordering buffer */
@@ -642,14 +645,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 	tid_agg_rx->stored_mpdu_num++;
 	ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);
 
-	return true;
+ out:
+	spin_unlock(&tid_agg_rx->lock);
+	return ret;
 }
 
 static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 					  struct tid_ampdu_rx *tid_agg_rx,
 					  struct sk_buff_head *frames)
 {
-	int index;
+	int index, j;
 
 	/* release the buffer until next missing frame */
 	index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
@@ -660,7 +665,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 		 * No buffers ready to be released, but check whether any
 		 * frames in the reorder buffer have timed out.
 		 */
-		int j;
 		int skipped = 1;
 		for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
 		     j = (j + 1) % tid_agg_rx->buf_size) {
@@ -670,7 +674,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 			}
 			if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
 					HT_RX_REORDER_BUF_TIMEOUT))
-				break;
+				goto set_release_timer;
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
 			if (net_ratelimit())
@@ -694,6 +698,25 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 		index =	seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
 							tid_agg_rx->buf_size;
 	}
+
+	if (tid_agg_rx->stored_mpdu_num) {
+		j = index = seq_sub(tid_agg_rx->head_seq_num,
+				    tid_agg_rx->ssn) % tid_agg_rx->buf_size;
+
+		for (; j != (index - 1) % tid_agg_rx->buf_size;
+		     j = (j + 1) % tid_agg_rx->buf_size) {
+			if (tid_agg_rx->reorder_buf[j])
+				break;
+		}
+
+ set_release_timer:
+
+		mod_timer(&tid_agg_rx->reorder_timer,
+			  tid_agg_rx->reorder_time[j] +
+			  HT_RX_REORDER_BUF_TIMEOUT);
+	} else {
+		del_timer(&tid_agg_rx->reorder_timer);
+	}
 }
 
 /*
@@ -2398,6 +2421,39 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
 	}
 }
 
+void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
+{
+	struct sk_buff_head frames;
+	struct ieee80211_rx_data rx = { };
+
+	__skb_queue_head_init(&frames);
+
+	/* construct rx struct */
+	rx.sta = sta;
+	rx.sdata = sta->sdata;
+	rx.local = sta->local;
+	rx.queue = tid;
+	rx.flags |= IEEE80211_RX_RA_MATCH;
+
+	if (unlikely(test_bit(SCAN_HW_SCANNING, &sta->local->scanning) ||
+		     test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning)))
+		rx.flags |= IEEE80211_RX_IN_SCAN;
+
+	spin_lock(&sta->ampdu_mlme.tid_rx[tid]->lock);
+	ieee80211_sta_reorder_release(&sta->local->hw,
+		sta->ampdu_mlme.tid_rx[tid], &frames);
+	spin_unlock(&sta->ampdu_mlme.tid_rx[tid]->lock);
+
+	/*
+	 * key references and virtual interfaces are protected using RCU
+	 * and this requires that we are in a read-side RCU section during
+	 * receive processing
+	 */
+	rcu_read_lock();
+	ieee80211_rx_handlers(&rx, &frames);
+	rcu_read_unlock();
+}
+
 /* main receive path */
 
 static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 54262e7..5e83c83 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -110,6 +110,7 @@ struct tid_ampdu_tx {
  * @timeout: reset timer value (in TUs).
  * @dialog_token: dialog token for aggregation session
  * @rcu_head: RCU head used for freeing this struct
+ * @lock: controls exclusive access to the struct
  *
  * This structure is protected by RCU and the per-station
  * spinlock. Assignments to the array holding it must hold
@@ -121,9 +122,11 @@ struct tid_ampdu_tx {
  */
 struct tid_ampdu_rx {
 	struct rcu_head rcu_head;
+	spinlock_t lock;
 	struct sk_buff **reorder_buf;
 	unsigned long *reorder_time;
 	struct timer_list session_timer;
+	struct timer_list reorder_timer;
 	u16 head_seq_num;
 	u16 stored_mpdu_num;
 	u16 ssn;

^ permalink raw reply related

* Re: [PATCH 1/3] mac80211: put rx handlers into seperate functions
From: Johannes Berg @ 2010-08-02 13:22 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless, John W. Linville
In-Reply-To: <201008021515.06013.chunkeey@googlemail.com>

On Mon, 2010-08-02 at 15:15 +0200, Christian Lamparter wrote:
> Note: In order to keep diff from removing and re-adding code,
> I used forward declarations. So it should be easier to verify
> that I didn't change anything related to the reordering logic.

FWIW, I'd prefer you didn't do that but moved the code instead.

johannes



^ permalink raw reply

* Re: [PATCH 3/3] mac80211: AMPDU rx reorder timeout timer
From: Johannes Berg @ 2010-08-02 13:24 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless, John W. Linville
In-Reply-To: <201008021516.29731.chunkeey@googlemail.com>

On Mon, 2010-08-02 at 15:16 +0200, Christian Lamparter wrote:

> @@ -110,6 +110,7 @@ struct tid_ampdu_tx {
>   * @timeout: reset timer value (in TUs).
>   * @dialog_token: dialog token for aggregation session
>   * @rcu_head: RCU head used for freeing this struct
> + * @lock: controls exclusive access to the struct
>   *
>   * This structure is protected by RCU and the per-station
>   * spinlock. Assignments to the array holding it must hold

I think that's misleading. You're only using it to control access to the
reorder stuff here, not any of the other things that are used in
agg-rx.c.

Also, documentation for reorder_timer is missing.

johannes


^ permalink raw reply

* Re: MX27 libertas_sdio SDIO Interrupts vs available bitrate
From: Andreas Feuersinger @ 2010-08-02 13:46 UTC (permalink / raw)
  To: Julien Boibessot; +Cc: libertas-dev, linux-mmc, linux-wireless
In-Reply-To: <4C51795F.8000800@free.fr>


Hi Julien!

Julien Boibessot <julien.boibessot@free.fr> wrote:
> Andreas Feuersinger a écrit :
> > Everything works except for very bad datarate. So far the mxc_mmc
> > driver does not handle any SDIO interrupts. Could that be the reason
> > for the bad performance? 
> >   
> Definitly !
> (I had the same "problem" on my i.MX27 platform before using SDIO
> interrupts)

thank you! At least I know where to go ;)

While trying to enable SDIO handling I look at the mainline kernel
patch for SDIO interrupts in mxcmmc.c.

But in order to apply that I have to port that driver, introduced in
2.6.29 to my 2.6.22 kernel version. 

In the first step I try to get it run without sdio support.
The driver seems to load helper firmware successfully and also real
firmware. After that it stops where the libertas driver says:
"waiting for firmware to boot."

Register status is as follows:
mxcmci_irq:status: <6>BUF_WRITE_RDY |<6>END_CMD_RESP |<6>BUF_UND_RUN
|<6>XBUF_EMPTY |<6>YBUF_EMPTY |<6>

Looks like stopped clock? Is the firmware supposed to start some cmd?


I have a different question:
Does anybody know if it is possible to boot freescale development board
mx27pdk  using kernel versions greater 2.6.30 ?

thanks

Andreas



^ permalink raw reply

* [PATCH 4/4] ath9k: shorten the calibration interval during strong interference
From: Felix Fietkau @ 2010-08-02 13:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez
In-Reply-To: <1280757195-9532-3-git-send-email-nbd@openwrt.org>

When the noise floor limits are being bypassed because of strong
interference, sensitivity is also reduced.
In order to recover from this as quickly as possible, trigger a
long periodic calibration every second instead of every 30 seconds,
until the NF median is within limits again. This is especially important
if the interference lasts for a while, since it takes multiple clean
NF calibrations to bring the median back to normal.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    1 +
 drivers/net/wireless/ath/ath9k/main.c  |    9 +++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 07f26ee..def0cd3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -423,6 +423,7 @@ int ath_beaconq_config(struct ath_softc *sc);
 #define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
 #define ATH_ANI_POLLINTERVAL_OLD  100     /* 100 ms */
 #define ATH_ANI_POLLINTERVAL_NEW  1000    /* 1000 ms */
+#define ATH_LONG_CALINTERVAL_INT  1000    /* 1000 ms */
 #define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
 #define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3caa323..ca80dbb 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -395,7 +395,12 @@ void ath_ani_calibrate(unsigned long data)
 	bool shortcal = false;
 	bool aniflag = false;
 	unsigned int timestamp = jiffies_to_msecs(jiffies);
-	u32 cal_interval, short_cal_interval;
+	u32 cal_interval, short_cal_interval, long_cal_interval;
+
+	if (ah->caldata && ah->caldata->nfcal_interference)
+		long_cal_interval = ATH_LONG_CALINTERVAL_INT;
+	else
+		long_cal_interval = ATH_LONG_CALINTERVAL;
 
 	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
 		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
@@ -407,7 +412,7 @@ void ath_ani_calibrate(unsigned long data)
 	ath9k_ps_wakeup(sc);
 
 	/* Long calibration runs independently of short calibration. */
-	if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+	if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
 		longcal = true;
 		ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
 		common->ani.longcal_timer = timestamp;
-- 
1.6.4.2


^ permalink raw reply related

* [PATCH 1/4] ath9k: add a separate debug level for stuck beacons
From: Felix Fietkau @ 2010-08-02 13:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

Stuck beacons are a useful indicator for debugging various PHY
issues such as calibration. Putting them on the same debug level
as the other beacon stuff makes it hard to spot them in huge amounts
of spam.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/beacon.c |    6 +++---
 drivers/net/wireless/ath/debug.h        |    2 ++
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 4d4b22d..102f123 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -359,11 +359,11 @@ void ath_beacon_tasklet(unsigned long data)
 		sc->beacon.bmisscnt++;
 
 		if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
-			ath_print(common, ATH_DBG_BEACON,
+			ath_print(common, ATH_DBG_BSTUCK,
 				  "missed %u consecutive beacons\n",
 				  sc->beacon.bmisscnt);
 		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-			ath_print(common, ATH_DBG_BEACON,
+			ath_print(common, ATH_DBG_BSTUCK,
 				  "beacon is officially stuck\n");
 			sc->sc_flags |= SC_OP_TSF_RESET;
 			ath_reset(sc, false);
@@ -373,7 +373,7 @@ void ath_beacon_tasklet(unsigned long data)
 	}
 
 	if (sc->beacon.bmisscnt != 0) {
-		ath_print(common, ATH_DBG_BEACON,
+		ath_print(common, ATH_DBG_BSTUCK,
 			  "resume beacon xmit after %u misses\n",
 			  sc->beacon.bmisscnt);
 		sc->beacon.bmisscnt = 0;
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 873bf52..fd3a020 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -36,6 +36,7 @@
  * @ATH_DBG_PS: power save processing
  * @ATH_DBG_HWTIMER: hardware timer handling
  * @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
  * @ATH_DBG_ANY: enable all debugging
  *
  * The debug level is used to control the amount and type of debugging output
@@ -60,6 +61,7 @@ enum ATH_DEBUG {
 	ATH_DBG_HWTIMER		= 0x00001000,
 	ATH_DBG_BTCOEX		= 0x00002000,
 	ATH_DBG_WMI		= 0x00004000,
+	ATH_DBG_BSTUCK		= 0x00008000,
 	ATH_DBG_ANY		= 0xffffffff
 };
 
-- 
1.6.4.2


^ permalink raw reply related

* [PATCH 3/4] ath9k: use AP beacon miss as a trigger for fast recalibration
From: Felix Fietkau @ 2010-08-02 13:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez
In-Reply-To: <1280757195-9532-2-git-send-email-nbd@openwrt.org>

When beacons get stuck in AP mode, the most likely cause is interference.
Such interference can often go on for a while, and too many consecutive
beacon misses can lead to connected clients getting dropped.

Since connected clients might not be subjected to the same interference
if that happens to be very local, the AP should try to deal with it as
good as it can. One way to do this is to trigger an NF calibration with
automatic baseband update right after the beacon miss. In my tests with
very strong interference, this allowed the AP to continue transmitting
beacons after only 2-3 misses, which allows a normal client to stay
connected.

With some of the newer - really sensitive - chips, the maximum noise
floor limit is very low, which can be problematic during very strong
interference. To avoid an endless loop of stuck beacons -> nfcal ->
periodic calibration -> stuck beacons, the beacon miss event also sets
a flag, which allows the calibration code to bypass the chip specific
maximum NF value. This flag is automatically cleared, as soon as the
first NF median goes back below the limits for all chains.

In my tests, this allowed an ath9k AP to survive very strong interference
(measured NF: -68, or sometimes even higher) without losing connectivity
to its clients. Even under these conditions, I was able to transmit
several mbits/s through the interface.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/beacon.c |    1 +
 drivers/net/wireless/ath/ath9k/calib.c  |   66 +++++++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/calib.h  |    1 +
 drivers/net/wireless/ath/ath9k/hw.h     |    1 +
 4 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 102f123..081192e 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -362,6 +362,7 @@ void ath_beacon_tasklet(unsigned long data)
 			ath_print(common, ATH_DBG_BSTUCK,
 				  "missed %u consecutive beacons\n",
 				  sc->beacon.bmisscnt);
+			ath9k_hw_bstuck_nfcal(ah);
 		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
 			ath_print(common, ATH_DBG_BSTUCK,
 				  "beacon is officially stuck\n");
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index ccb1b2e..67ee5d7 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -65,12 +65,16 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
 
 
 static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
-					      struct ath9k_nfcal_hist *h,
+					      struct ath9k_hw_cal_data *cal,
 					      int16_t *nfarray)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_nf_limits *limit;
+	struct ath9k_nfcal_hist *h;
+	bool high_nf_mid = false;
 	int i;
 
+	h = cal->nfCalHist;
 	limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
 
 	for (i = 0; i < NUM_NF_READINGS; i++) {
@@ -87,9 +91,38 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
 				ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
 		}
 
-		if (h[i].privNF > limit->max)
-			h[i].privNF = limit->max;
+		if (!h[i].privNF)
+			continue;
+
+		if (h[i].privNF > limit->max) {
+			high_nf_mid = true;
+
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "NFmid[%d] (%d) > MAX (%d), %s\n",
+				  i, h[i].privNF, limit->max,
+				  (cal->nfcal_interference ?
+				   "not corrected (due to interference)" :
+				   "correcting to MAX"));
+
+			/*
+			 * Normally we limit the average noise floor by the
+			 * hardware specific maximum here. However if we have
+			 * encountered stuck beacons because of interference,
+			 * we bypass this limit here in order to better deal
+			 * with our environment.
+			 */
+			if (!cal->nfcal_interference)
+				h[i].privNF = limit->max;
+		}
 	}
+
+	/*
+	 * If the noise floor seems normal for all chains, assume that
+	 * there is no significant interference in the environment anymore.
+	 * Re-enable the enforcement of the NF maximum again.
+	 */
+	if (!high_nf_mid)
+		cal->nfcal_interference = false;
 }
 
 static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
@@ -339,7 +372,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
 
 	h = caldata->nfCalHist;
 	caldata->nfcal_pending = false;
-	ath9k_hw_update_nfcal_hist_buffer(ah, h, nfarray);
+	ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
 	caldata->rawNoiseFloor = h[0].privNF;
 	return true;
 }
@@ -374,3 +407,28 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
 	return ah->caldata->rawNoiseFloor;
 }
 EXPORT_SYMBOL(ath9k_hw_getchan_noise);
+
+void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
+{
+	struct ath9k_hw_cal_data *caldata = ah->caldata;
+
+	if (unlikely(!caldata))
+		return;
+
+	/*
+	 * If beacons are stuck, the most likely cause is interference.
+	 * Triggering a noise floor calibration at this point helps the
+	 * hardware adapt to a noisy environment much faster.
+	 * To ensure that we recover from stuck beacons quickly, let
+	 * the baseband update the internal NF value itself, similar to
+	 * what is being done after a full reset.
+	 */
+	if (!caldata->nfcal_pending)
+		ath9k_hw_start_nfcal(ah, true);
+	else if (!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF))
+		ath9k_hw_getnf(ah, ah->curchan);
+
+	caldata->nfcal_interference = true;
+}
+EXPORT_SYMBOL(ath9k_hw_bstuck_nfcal);
+
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 0a304b3..5b053a6 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -113,6 +113,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
 bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
 				  struct ath9k_channel *chan);
+void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
 void ath9k_hw_reset_calibration(struct ath_hw *ah,
 				struct ath9k_cal_list *currCal);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 399f7c1..1601dd4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -355,6 +355,7 @@ struct ath9k_hw_cal_data {
 	int16_t rawNoiseFloor;
 	bool paprd_done;
 	bool nfcal_pending;
+	bool nfcal_interference;
 	u16 small_signal_gain[AR9300_MAX_CHAINS];
 	u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
 	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-- 
1.6.4.2


^ permalink raw reply related

* [PATCH 2/4] ath9k_hw: apply the noise floor validation to the median instead of single
From: Felix Fietkau @ 2010-08-02 13:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez
In-Reply-To: <1280757195-9532-1-git-send-email-nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/calib.c |   51 ++++++++++++++++++++------------
 1 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 4520869..ccb1b2e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -19,8 +19,7 @@
 
 /* Common calibration code */
 
-/* We can tune this as we go by monitoring really low values */
-#define ATH9K_NF_TOO_LOW	-60
+#define ATH9K_NF_TOO_HIGH	-60
 
 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
 {
@@ -45,11 +44,35 @@ static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
 	return nfval;
 }
 
-static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
+static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah,
+						    struct ath9k_channel *chan)
+{
+	struct ath_nf_limits *limit;
+
+	if (!chan || IS_CHAN_2GHZ(chan))
+		limit = &ah->nf_2g;
+	else
+		limit = &ah->nf_5g;
+
+	return limit;
+}
+
+static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
+				   struct ath9k_channel *chan)
+{
+	return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+}
+
+
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
+					      struct ath9k_nfcal_hist *h,
 					      int16_t *nfarray)
 {
+	struct ath_nf_limits *limit;
 	int i;
 
+	limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
+
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
 
@@ -63,6 +86,9 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
 			h[i].privNF =
 				ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
 		}
+
+		if (h[i].privNF > limit->max)
+			h[i].privNF = limit->max;
 	}
 }
 
@@ -104,19 +130,6 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah,
 	ah->cal_samples = 0;
 }
 
-static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
-				   struct ath9k_channel *chan)
-{
-	struct ath_nf_limits *limit;
-
-	if (!chan || IS_CHAN_2GHZ(chan))
-		limit = &ah->nf_2g;
-	else
-		limit = &ah->nf_5g;
-
-	return limit->nominal;
-}
-
 /* This is done for the currently configured channel */
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
 {
@@ -277,10 +290,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
 			  "NF calibrated [%s] [chain %d] is %d\n",
 			  (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
 
-		if (nf[i] > limit->max) {
+		if (nf[i] > ATH9K_NF_TOO_HIGH) {
 			ath_print(common, ATH_DBG_CALIBRATE,
 				  "NF[%d] (%d) > MAX (%d), correcting to MAX",
-				  i, nf[i], limit->max);
+				  i, nf[i], ATH9K_NF_TOO_HIGH);
 			nf[i] = limit->max;
 		} else if (nf[i] < limit->min) {
 			ath_print(common, ATH_DBG_CALIBRATE,
@@ -326,7 +339,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
 
 	h = caldata->nfCalHist;
 	caldata->nfcal_pending = false;
-	ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
+	ath9k_hw_update_nfcal_hist_buffer(ah, h, nfarray);
 	caldata->rawNoiseFloor = h[0].privNF;
 	return true;
 }
-- 
1.6.4.2


^ permalink raw reply related

* Re: [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Vitaly Wool @ 2010-08-02 15:12 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Luciano Coelho, Ohad Ben-Cohen, Kalle Valo, Pandita Vikram,
	linux@arm.linux.org.uk, Quadros Roger (Nokia-MS/Helsinki),
	linux-wireless@vger.kernel.org, Nicolas Pitre,
	linux-mmc@vger.kernel.org, ext John W. Linville, San Mehat,
	Chikkature Rajashekar Madhusudhan, akpm@linux-foundation.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20100802114256.GE12293@atomide.com>

On Mon, Aug 2, 2010 at 1:42 PM, Tony Lindgren <tony@atomide.com> wrote:

> Nicolas Pitre made a comment saying he wants to look at these patches
> more, are there other pending comments?

Yep, I'm feeling quite uncomfortable with the way platform data is
being passed over to sdio device now.

Also, specifically to 12xx, I'd like to see REF_CLOCK moved on and
have this set by platform too (I haven't found anything like that in
the patches but maybe I've overlooked that).

Thanks,
   Vitaly

^ permalink raw reply

* Re: iwlwifi connection problems
From: Alex Romosan @ 2010-08-02 15:42 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Guy, Wey-Yi, linux-wireless@vger.kernel.org
In-Reply-To: <1280746705.3923.11.camel@jlt3.sipsolutions.net>

[-- Attachment #1: Type: text/plain, Size: 1332 bytes --]

Johannes Berg <johannes@sipsolutions.net> writes:

> However, if that doesn't help this seems like an ideal candidate for
> bisection, would you be willing to try that? I'd restrict to wireless
> code, i.e.
>
> git bisect start -- net/wireless net/mac80211 drivers/net/wireless/iwlwifi

so i think i finally managed to track this down. doing a git bisect i
get:

3474ad635db371b0d8d0ee40086f15d223d5b6a4 is the first bad commit
commit 3474ad635db371b0d8d0ee40086f15d223d5b6a4
Author: Johannes Berg <johannes.berg@intel.com>
Date:   Thu Apr 29 04:43:05 2010 -0700

    iwlwifi: apply filter flags directly

    Since iwl_configure_filter can now sleep since
    the mac80211 callback was changed, we can now
    apply filter flags changes directly.

    Also, while at it, make the code a bit more
    generic with a local macro. There's no need
    to check changed_flags since we apply all at
    the same time anyway.

    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>

:040000 040000 40b7db1c9366981ce696f96a9e4a515bfafa6437 824fbd988db160dc0067bced1a8e907edc0fed97 M      drivers

then i did a git revert 3474ad635db371b0d8d0ee40086f15d223d5b6a4 there
was a conflict i had to edit by hand but the actual diff between 2.6.35
and the version that works is:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bad commit --]
[-- Type: text/x-diff, Size: 2202 bytes --]

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5bbc529..350a4a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1301,32 +1301,41 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
 			  u64 multicast)
 {
 	struct iwl_priv *priv = hw->priv;
-	__le32 filter_or = 0, filter_nand = 0;
-
-#define CHK(test, flag)	do { \
-	if (*total_flags & (test))		\
-		filter_or |= (flag);		\
-	else					\
-		filter_nand |= (flag);		\
-	} while (0)
+	__le32 *filter_flags = &priv->staging_rxon.filter_flags;
 
 	IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
 			changed_flags, *total_flags);
 
-	CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
-	CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
-	CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
-
-#undef CHK
-
-	mutex_lock(&priv->mutex);
-
-	priv->staging_rxon.filter_flags &= ~filter_nand;
-	priv->staging_rxon.filter_flags |= filter_or;
-
-	iwlcore_commit_rxon(priv);
+	if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+		if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
+			*filter_flags |= RXON_FILTER_PROMISC_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_PROMISC_MSK;
+	}
+	if (changed_flags & FIF_ALLMULTI) {
+		if (*total_flags & FIF_ALLMULTI)
+			*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
+	}
+	if (changed_flags & FIF_CONTROL) {
+		if (*total_flags & FIF_CONTROL)
+			*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
+	}
+	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+			*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
+	}
 
-	mutex_unlock(&priv->mutex);
+	/* We avoid iwl_commit_rxon here to commit the new filter flags
+	 * since mac80211 will call ieee80211_hw_config immediately.
+	 * (mc_list is not supported at this time). Otherwise, we need to
+	 * queue a background iwl_commit_rxon work.
+	 */
 
 	/*
 	 * Receiving all multicast frames is always enabled by the

[-- Attachment #3: Type: text/plain, Size: 524 bytes --]


and now 2.6.35 with this commit reverted (the above patch applied)
connects to my access point. 

i am willing to test an official patch against 2.6.35 (i'm just about to
leave for work so it might not happen until later today though).

--alex--

-- 
| I believe the moment is at hand when, by a paranoiac and active |
|  advance of the mind, it will be possible (simultaneously with  |
|  automatism and other passive states) to systematize confusion  |
|  and thus to help to discredit completely the world of reality. |

^ permalink raw reply related

* Re: [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Ohad Ben-Cohen @ 2010-08-02 15:59 UTC (permalink / raw)
  To: Vitaly Wool
  Cc: Tony Lindgren, Luciano Coelho, Kalle Valo, Pandita Vikram,
	linux@arm.linux.org.uk, Quadros Roger (Nokia-MS/Helsinki),
	linux-wireless@vger.kernel.org, Nicolas Pitre,
	linux-mmc@vger.kernel.org, ext John W. Linville, San Mehat,
	Chikkature Rajashekar Madhusudhan, akpm@linux-foundation.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <AANLkTikvtMbqUdwHtCtdL2xXbQh64pxjApo6ZH6hAXnP@mail.gmail.com>

On Mon, Aug 2, 2010 at 6:12 PM, Vitaly Wool <vitalywool@gmail.com> wrote:
> Also, specifically to 12xx, I'd like to see REF_CLOCK moved on and
> have this set by platform too (I haven't found anything like that in
> the patches but maybe I've overlooked that).

Check out patch no. 9:

http://www.spinics.net/lists/arm-kernel/msg93836.html


>
> Thanks,
>   Vitaly
> --
> 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: [PATCH v2 03/20] mmc: support embedded data field in mmc_host
From: Ohad Ben-Cohen @ 2010-08-02 15:54 UTC (permalink / raw)
  To: Vitaly Wool
  Cc: linux-wireless, linux-mmc, linux-omap, Kalle Valo, Pandita Vikram,
	linux, Nicolas Pitre, Tony Lindgren, Roger Quadros, San Mehat,
	Chikkature Rajashekar Madhusudhan, Luciano Coelho, akpm,
	linux-arm-kernel
In-Reply-To: <AANLkTi=BUX59heXAW2Uf4wZo2dSS19Je54dkQ5u2YGAW@mail.gmail.com>

Hi Vitaly,

On Thu, Jul 29, 2010 at 7:16 PM, Vitaly Wool <vitalywool@gmail.com> wrote:
> On Thu, Jul 29, 2010 at 8:00 AM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
>>> To my understanding, this data doesn't belong to mmc_host. It's not a
>>> host data at all. E. g. imagine a GPIO IRQ for some SDIO chip -- it's
>>> totally unrelated to host.
>>>
>>> I think a cleaner way would be to introduce something similar to what
>>> we have for SPI, e. g. struct sdio_board_info. This board info will
>>> contain platform-specific stuff and vendor id/chip id for each onboard
>>> SDIO device. Then the SDIO core will pick up the appropriate data
>>> basing on vendor id/chip id.
>>
>> Can you please elaborate some more about your proposal (specifically
>> where does this sdio_board_info get set and how do function drivers
>> access it) ?
>>
>> If I understand you correctly, you suggest to have a global,
>> board-specific table of sdio_board_info structures, which would be
>> accessible to the SDIO core (through the host driver ?). When a new
>> SDIO device is found the core would search this table for the
>> appropriate sdio_board_info struct and make it accessible to the SDIO
>> function driver ?
>
> Well, let's look at how it's implemented for SPI. There is the
> function spi_register_board_info in the SPI core which copies the
> board info into the local data structure (a linked list, actually).
> Whenever needed, the core walks through the list to find the
> appropriate board_info basing on some search key.
>
> I think this may be the way to go for SDIO as well.

IMHO this is a bit overkill solution for our problem.

SPI is using these spi_board_info tables to populate the SPI device
trees. These tables are registered early at the board-specific init
code, and are later used by SPI core to populate the devices when the
SPI master controller is registered.

SDIO doesn't normally needs any kind of hard coded data: most devices
are dynamically probed and populated.

On rare cases like the wl1271, we have some platform-specific data we
need to deliver the SDIO function driver (i.e. the irq info in this
case). Since the device is hardwired to a specific controller, it does
make some sense to pass this private data from the controller's info
in the board files, through the host driver, and make it accessible
through the specific host instance that drives this controller.

Btw, if our problem was be broader (e.g., needs to supply private data
for non-hardwired devices), then I agree that a more complex
mechanism, such as the one you suggest, would be needed. But currently
the problem is very simple and the solution is even simpler: just add
1 private pointer to the host.

Hope you find this reasonable,

Thanks,
Ohad.

>
> ~Vitaly
>

^ permalink raw reply

* Re: [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Vitaly Wool @ 2010-08-02 16:19 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Tony Lindgren, Luciano Coelho, Kalle Valo, Pandita Vikram,
	linux@arm.linux.org.uk, Quadros Roger (Nokia-MS/Helsinki),
	linux-wireless@vger.kernel.org, Nicolas Pitre,
	linux-mmc@vger.kernel.org, ext John W. Linville, San Mehat,
	Chikkature Rajashekar Madhusudhan, akpm@linux-foundation.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <AANLkTimaSeLqowRHSCivGXTiSE7NatNTR=jLWQYsSo-6@mail.gmail.com>

Hi Ohad,

On Mon, Aug 2, 2010 at 5:59 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
>
> Check out patch no. 9:

sorry for the confusion. However, I guess if the platform doesn't
supply this value, we'll just consider it 0? Without any warning,
right?

The problem is, we can't really distinguish between this field not set
and value zero, and that means something is wrong with the design. The
easiest way is probably changing the clock ids to start with 1.

Thanks,
   Vitaly

^ permalink raw reply

* Re: iwlwifi connection problems
From: Johannes Berg @ 2010-08-02 16:23 UTC (permalink / raw)
  To: Alex Romosan; +Cc: Guy, Wey-Yi, linux-wireless@vger.kernel.org
In-Reply-To: <878w4pvx5e.fsf@sycorax.lbl.gov>

On Mon, 2010-08-02 at 08:42 -0700, Alex Romosan wrote:

> so i think i finally managed to track this down. doing a git bisect i
> get:
> 
> 3474ad635db371b0d8d0ee40086f15d223d5b6a4 is the first bad commit
> commit 3474ad635db371b0d8d0ee40086f15d223d5b6a4
> Author: Johannes Berg <johannes.berg@intel.com>
> Date:   Thu Apr 29 04:43:05 2010 -0700
> 
>     iwlwifi: apply filter flags directly

> ...

Thanks. I'll take a closer look tomorrow, am about to leave for today.

johannes


^ permalink raw reply

* Re: [PATCH v2 03/20] mmc: support embedded data field in mmc_host
From: Vitaly Wool @ 2010-08-02 16:25 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: linux-wireless, linux-mmc, linux-omap, Kalle Valo, Pandita Vikram,
	linux, Nicolas Pitre, Tony Lindgren, Roger Quadros, San Mehat,
	Chikkature Rajashekar Madhusudhan, Luciano Coelho, akpm,
	linux-arm-kernel
In-Reply-To: <AANLkTimZQKj7H_GeE=+O9cwxEMTR+LhfFbt=AyXGzN3d@mail.gmail.com>

Hi Ohad,

On Mon, Aug 2, 2010 at 5:54 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:

> SPI is using these spi_board_info tables to populate the SPI device
> trees. These tables are registered early at the board-specific init
> code, and are later used by SPI core to populate the devices when the
> SPI master controller is registered.
>
> SDIO doesn't normally needs any kind of hard coded data: most devices
> are dynamically probed and populated.
>
> On rare cases like the wl1271, we have some platform-specific data we
> need to deliver the SDIO function driver (i.e. the irq info in this
> case). Since the device is hardwired to a specific controller, it does
> make some sense to pass this private data from the controller's info
> in the board files, through the host driver, and make it accessible
> through the specific host instance that drives this controller.
>
> Btw, if our problem was be broader (e.g., needs to supply private data
> for non-hardwired devices), then I agree that a more complex
> mechanism, such as the one you suggest, would be needed. But currently
> the problem is very simple and the solution is even simpler: just add
> 1 private pointer to the host.
>
> Hope you find this reasonable,

no, actually I don't. I think this is a hack that intrudes into the
area it completely doesn't belong to.

In fact, one can have 2 views on this problem: either this is a fairly
generic problem we need to address, or this is a very specific corner
case.
Your solution will be treated as a hack in both cases.

If we consider it a generic problem, then we need to find a generic
solution, which is the board_info solution, for instance. FWIW, I2C
also uses this approach now.

If we consider it to be a corner case, let's just add a dummy
platform_device like it's done in WL1251 implementation and keep the
MMC subsystem clean.

Thanks,
   Vitaly

^ permalink raw reply

* Re: 2.6.35-rc6-git6: Reported regressions from 2.6.34
From: Tejun Heo @ 2010-08-02 16:32 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Rafael J. Wysocki, Jens Axboe, Linux Kernel Mailing List,
	Maciej Rutecki, Andrew Morton, Kernel Testers List,
	Network Development, Linux ACPI, Linux PM List, Linux SCSI List,
	Linux Wireless List, DRI
In-Reply-To: <AANLkTimcH7+Bq1UEbaSU7SQpzArPgmSLegiqE13V8=CF@mail.gmail.com>

Hello, Linus.

On 08/01/2010 08:01 PM, Linus Torvalds wrote:
> This has a proposed patch. I don't know what the status of it is, though. Jens?
> 
>    http://marc.info/?l=linux-kernel&m=127950018204029&w=2
> 
>> Bug-Entry       : http://bugzilla.kernel.org/show_bug.cgi?id=16393
>> Subject         : kernel BUG at fs/block_dev.c:765!
>> Submitter       : Markus Trippelsdorf <markus@trippelsdorf.de>
>> Date            : 2010-07-14 13:52 (19 days old)
>> Message-ID      : <20100714135217.GA1797@arch.tripp.de>
>> References      : http://marc.info/?l=linux-kernel&m=127911564213748&w=2
> 
> This one is interesting. And I think I perhaps see where it's coming from.
> 
> bd_start_claiming() (through bd_prepare_to_claim()) has two separate
> success cases: either there was no holder (bd_claiming is NULL) or the
> new holder was already claiming it (bd_claiming == holder).
> 
> Note in particular the case of the holder _already_ holding it. What happens is:
> 
>  - bd_start_claiming() succeeds because we had _already_ claimed it
> with the same holder
> 
>  - then some error happens, and we call bd_abort_claiming(), which
> does whole->bd_claiming = NULL;
> 
>  - the original holder thinks it still holds the bd, but it has been released!
> 
>  - a new claimer comes in, and succeeds because bd_claiming is now NULL.
> 
>  - we now have two "owners" of the bd, but bd_claiming only points to
> the second one.
> 
> I think bd_start_claiming() needs to do some kind of refcount for the
> nested holder case, and bd_abort_claiming() needs to decrement the
> refcount and only clear the bd_claiming field when it goes down to
> zero.
> 
> I dunno. Maybe there's something else going on, but it does look
> suspicious, and the above would explain the BUG_ON().

Yeah, that definitely sounds plausible.  I think the condition check
in bd_prepare_to_claim() should have been "if (whole->bd_claiming)"
instead of "if (whole->bd_claiming && whole->bd_claiming != holder)".
It doesn't make much sense to allow multiple parallel claiming
operations anyway and the comment above already says - "This function
fails if @bdev is already claimed by another holder and waits if
another claiming is in progress."

I'll try to build a test case and verify it.

Thank you.

-- 
tejun

^ 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