Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v3 1/8] ath9k_hw: only use the PCIe disable register write sequence for AR5416
From: Rajkumar Manoharan @ 2010-12-13 11:12 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless@vger.kernel.org, linville@tuxdriver.com,
	Luis Rodriguez
In-Reply-To: <1292111474-70939-1-git-send-email-nbd@openwrt.org>

On Sun, Dec 12, 2010 at 05:21:07AM +0530, Felix Fietkau wrote:
> Newer chips do not need this, and maybe these register writes could have
> negative side effects on newer hardware.
> 
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
>  drivers/net/wireless/ath/ath9k/hw.c |    6 +-----
>  1 files changed, 1 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
> index 516227f..7bc6d22 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.c
> +++ b/drivers/net/wireless/ath/ath9k/hw.c
> @@ -284,11 +284,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
>  
>  static void ath9k_hw_disablepcie(struct ath_hw *ah)
>  {
> -	if (AR_SREV_9100(ah))
> +	if (!AR_SREV_5416(ah))
>  		return;
>  
> -	ENABLE_REGWRITE_BUFFER(ah);

Why to disable multiple register write?

--
Rajkumar

^ permalink raw reply

* Re: [PATCH v2 5/7] ath9k_hw: fix PA predistortion training power selection
From: Christian Lamparter @ 2010-12-13 11:28 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Felix Fietkau, linux-wireless, linville, lrodriguez, vasanth
In-Reply-To: <1292235614.3539.14.camel@jlt3.sipsolutions.net>

On Monday 13 December 2010 11:20:14 Johannes Berg wrote:
> On Mon, 2010-12-13 at 11:52 +0100, Christian Lamparter wrote:
> 
> > > +	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
> > > +}
> > > +
> > I think there's a generic library function for that:
> > hweight[8|16|32].
> 
> but note the !!, which makes this return 0, 1, 2 or 3 only, not the bit
> weight.
> 
what?

the "Hamming weight/Population count" returns the
number of symbols that are different from the zero-symbol.

e.g.: The Hamming weight of 0x800000000000000000000000000000000
is just "1".

Furthermore, if tx_chainmask contains now more than just the available
tx_chains, then they can always mask the hweight* input with: 
AR9300_ANT_CHAIN_MASK (for 3x3) or
AR9300_ANT_COMMON_MASK (for future 4x4)

Regards,
	Chr

^ permalink raw reply

* Re: Cannot set regdomain
From: Dennis Borgmann @ 2010-12-13 10:20 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <4D0384B3.8020702@googlemail.com>

Sorry folks! Absolutely my fault, since I did not install crda. I must
have forgotten it.

Sorry for bothering,
Dennis

Dennis Borgmann schrieb:
> Hello linux-wireless list!
>
> I tried the IRC, but there was no answer, so I try the mailing-list.
>
> I want to change my regdomain issuing this command:
>
> iw reg set DE
>
> But I get no change in regdomain, which I can observe using
>
> iw reg get
>
> which always shows me, I am in domain "00". If I start udevadm like this:
>
> udevadm monitor --environment kernel
>
> there is no output while issueing any of the commands shown above. I am
> using these commands with respect to this webpage-documentation:
>
> http://wireless.kernel.org/en/developers/Regulatory/CRDA
>
> Could anyone please tell me, why I cannot set the regdomain? I did
> follow the steps presented at
>
> http://acx100.erley.org/stable.html
>
> Kind regards,
> Dennis
>   


^ permalink raw reply

* Re: [PATCH v2 5/7] ath9k_hw: fix PA predistortion training power selection
From: Johannes Berg @ 2010-12-13 10:20 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: Felix Fietkau, linux-wireless, linville, lrodriguez, vasanth
In-Reply-To: <201012131152.50095.chunkeey@googlemail.com>

On Mon, 2010-12-13 at 11:52 +0100, Christian Lamparter wrote:

> > +	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
> > +}
> > +
> I think there's a generic library function for that:
> hweight[8|16|32].

but note the !!, which makes this return 0, 1, 2 or 3 only, not the bit
weight.

johannes


^ permalink raw reply

* Re: [PATCH v2 5/7] ath9k_hw: fix PA predistortion training power selection
From: Christian Lamparter @ 2010-12-13 10:52 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linville, lrodriguez, vasanth
In-Reply-To: <1292226056-56008-5-git-send-email-nbd@openwrt.org>

On Monday 13 December 2010 08:40:54 Felix Fietkau wrote:
>
> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> index cdca4c3..69f7792 100644
> --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> @@ -30,9 +30,69 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
> +
> +static int get_streams(int mask)
> +{
> +	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
> +}
> +
I think there's a generic library function for that:
hweight[8|16|32].

Also, some CPUs have a special "population count" instruction
and hweight* takes full advantage of that too. 

Regards,
	Chr

^ permalink raw reply

* Re: [PATCH 2/2] mac80211: Send mesh non-HWMP path selection frames to userspace
From: Johannes Berg @ 2010-12-13 10:11 UTC (permalink / raw)
  To: Javier Cardona; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292022251-12616-3-git-send-email-javier@cozybit.com>

On Fri, 2010-12-10 at 15:04 -0800, Javier Cardona wrote:

> --- a/lib/nlattr.c
> +++ b/lib/nlattr.c

I really don't think you should be changing this file in this patch :-)

> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index 4fee008..8093439 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -1673,6 +1673,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
>  	case NL80211_IFTYPE_AP:
>  	case NL80211_IFTYPE_AP_VLAN:
>  	case NL80211_IFTYPE_P2P_GO:
> +	case NL80211_IFTYPE_MESH_POINT:
>  		if (!ieee80211_is_action(mgmt->frame_control) ||
>  		    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
>  			break;

Might be worthwhile to update the subject to say something along the
lines of allowing send/receive in mesh.

>  struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
> index 80723d8..c38c833 100644
> --- a/net/mac80211/mesh.c
> +++ b/net/mac80211/mesh.c
> @@ -126,13 +126,21 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
>  
>  void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
>  {
> -	sta->mesh_pp_id = 0;	/* HWMP */
> -	sta->mesh_pm_id = 0;	/* Airtime */
> +	sta->mesh_pp_id = MESH_PATH_PROTOCOL_HWMP;
> +	sta->mesh_pm_id = MESH_PATH_PROTOCOL_VENDOR;

Doesn't that belong into the other patch? Come to think of it -- maybe
just move the remaining three lines into start_mesh() there, since these
two at least aren't necessary since we will always go through start_mesh
before using the values -- can even remove mesh_ids_set_default.

> +	case WLAN_CATEGORY_MESH_PATH_SEL:
> +		if (!ieee80211_vif_is_mesh(&sdata->vif) ||
> +				!mesh_path_sel_match(sdata,
> +					MESH_PATH_PROTOCOL_HWMP))
> +			break;
> +		goto queue;

I don't think I'd mind an ifdef here since that'd allow simplifying this
code a lot with the function call. Or at least make that an inline I
guess, a real function call for a comparison seems a bit odd. Maybe just
do

static inline bool mesh_path_sel_is_hwmp(sdata)
{
#ifdef CONFIG_MAC80211_MESH
	return sdata->u.mesh.mesh_pp_id == MESH_PATH_PROTOCOL_HWMP;
#endif
	return false;
}

and then you can even remove the !ieee80211_vif_is_mesh check :-)

johannes


^ permalink raw reply

* Re: [PATCH 1/2] mac80211: Let userspace enable and configure vendor specific path selection.
From: Johannes Berg @ 2010-12-13 10:04 UTC (permalink / raw)
  To: Javier Cardona; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292022251-12616-2-git-send-email-javier@cozybit.com>

On Fri, 2010-12-10 at 15:04 -0800, Javier Cardona wrote:

> +++ b/include/net/cfg80211.h
> @@ -643,6 +643,12 @@ struct mesh_config {
>  	u16 dot11MeshHWMPpreqMinInterval;
>  	u16 dot11MeshHWMPnetDiameterTraversalTime;
>  	u8  dot11MeshHWMPRootMode;
> +	u8  vendor_path_sel_enabled;
> +	u8  vendor_metric_enabled;
> +	struct {
> +		u8  *data;

const -- and I really wouldn't do a substruct for this.

> +		u8  length;
> +	} vendor_ie;
>  };

Should these really be part of mesh_config, rather than mesh_setup? I
may accept a need to change beacon IEs, but I don't think it makes any
sense to change the path selection at mesh runtime since changing it
will change the mesh network the node belongs to per mesh_matches_local.

> @@ -522,6 +528,10 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
>  	ieee80211_mesh_root_setup(ifmsh);
>  	ieee80211_queue_work(&local->hw, &sdata->work);
>  	sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
> +	sdata->u.mesh.mesh_pp_id = ifmsh->mshcfg.vendor_path_sel_enabled ?
> +		MESH_PATH_PROTOCOL_VENDOR : MESH_PATH_PROTOCOL_HWMP;
> +	sdata->u.mesh.mesh_pm_id = ifmsh->mshcfg.vendor_metric_enabled ?
> +		MESH_PATH_METRIC_VENDOR : MESH_PATH_METRIC_AIRTIME;

In fact, it looks like you only honour changes to them in start_mesh().

> +++ b/net/mac80211/mesh.h
> @@ -44,6 +44,30 @@ enum mesh_path_flags {
>  };
>  
>  /**
> + * enum - mesh path selection protocol identifier
> + *
> + * @MESH_PATH_PROTOCOL_HWMP: the default path selection protocol
> + * @MESH_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will be
> + * specified in a vendor specific information element
> + */
> +enum {
> +	MESH_PATH_PROTOCOL_HWMP = 0,
> +	MESH_PATH_PROTOCOL_VENDOR = 255,
> +};

> +/**
> + * enum - mesh path selection metric identifier
> + *
> + * @MESH_PATH_METRIC_AIRTIME: the default path selection metric
> + * @MESH_PATH_METRIC_VENDOR: a vendor specific metric that will be
> + * specified in a vendor specific information element
> + */
> +enum {
> +	MESH_PATH_METRIC_AIRTIME = 0,
> +	MESH_PATH_METRIC_VENDOR = 255,
> +};

Should these get an IEEE80211 prefix and move to
include/linux/ieee80211.h?

johannes


^ permalink raw reply

* [PATCH] wl12xx: Change TX queue to be per AC
From: juuso.oikarinen @ 2010-12-13  7:52 UTC (permalink / raw)
  To: luciano.coelho; +Cc: linux-wireless

From: Juuso Oikarinen <juuso.oikarinen@nokia.com>

With the current single-queue implementation traffic priorization is not
working correctly - when using multiple BE streams and one, say VI stream,
the VI stream will share bandwidth almost equally with the BE streams.

To fix the issue, implement per AC queues, which are emptied in priority
order to the firmware. To keep it relatively simple, maintain a global
buffer count and global queue stop/wake instead of per-AC.

With these changes, priorization appears to work just fine.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
 drivers/net/wireless/wl12xx/debugfs.c |    2 +-
 drivers/net/wireless/wl12xx/main.c    |   12 ++++--
 drivers/net/wireless/wl12xx/tx.c      |   60 +++++++++++++++++++++++++++------
 drivers/net/wireless/wl12xx/wl12xx.h  |    3 +-
 4 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 8106a6c..e18e78b 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -225,7 +225,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
 	char buf[20];
 	int res;
 
-	queue_len = skb_queue_len(&wl->tx_queue);
+	queue_len = wl->tx_queue_count;
 
 	res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index dc3a093..4884748 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -576,7 +576,7 @@ static void wl1271_irq_work(struct work_struct *work)
 
 			/* Check if any tx blocks were freed */
 			if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
-					!skb_queue_empty(&wl->tx_queue)) {
+			    wl->tx_queue_count) {
 				/*
 				 * In order to avoid starvation of the TX path,
 				 * call the work function directly.
@@ -897,6 +897,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
 	struct ieee80211_sta *sta = txinfo->control.sta;
 	unsigned long flags;
+	int q;
 
 	/*
 	 * peek into the rates configured in the STA entry.
@@ -924,10 +925,12 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 		set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
 	}
 #endif
+	wl->tx_queue_count++;
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
 	/* queue the packet */
-	skb_queue_tail(&wl->tx_queue, skb);
+	q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
+	skb_queue_tail(&wl->tx_queue[q], skb);
 
 	/*
 	 * The chip specific setup must run before the first TX packet -
@@ -941,7 +944,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	 * The workqueue is slow to process the tx_queue and we need stop
 	 * the queue here, otherwise the queue will get too long.
 	 */
-	if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
+	if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
 		wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
 
 		spin_lock_irqsave(&wl->wl_lock, flags);
@@ -2692,7 +2695,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
 	wl->hw = hw;
 	wl->plat_dev = plat_dev;
 
-	skb_queue_head_init(&wl->tx_queue);
+	for (i = 0; i < NUM_TX_QUEUES; i++)
+		skb_queue_head_init(&wl->tx_queue[i]);
 
 	INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
 	INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index d332b3f..b44c75c 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -125,7 +125,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
 	/* queue (we use same identifiers for tid's and ac's */
 	ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
 	desc->tid = ac;
-
 	desc->aid = TX_HW_DEFAULT_AID;
 	desc->reserved = 0;
 
@@ -228,7 +227,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
 	unsigned long flags;
 
 	if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
-	    skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
+	    wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) {
 		/* firmware buffer has space, restart queues */
 		spin_lock_irqsave(&wl->wl_lock, flags);
 		ieee80211_wake_queues(wl->hw);
@@ -237,6 +236,43 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
 	}
 }
 
+static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
+{
+	struct sk_buff *skb = NULL;
+	unsigned long flags;
+
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]);
+	if (skb)
+		goto out;
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]);
+	if (skb)
+		goto out;
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]);
+	if (skb)
+		goto out;
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]);
+
+out:
+	if (skb) {
+		spin_lock_irqsave(&wl->wl_lock, flags);
+		wl->tx_queue_count--;
+		spin_unlock_irqrestore(&wl->wl_lock, flags);
+	}
+
+	return skb;
+}
+
+static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
+{
+	unsigned long flags;
+	int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
+
+	skb_queue_head(&wl->tx_queue[q], skb);
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	wl->tx_queue_count++;
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+}
+
 void wl1271_tx_work_locked(struct wl1271 *wl)
 {
 	struct sk_buff *skb;
@@ -270,7 +306,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
 		wl1271_acx_rate_policies(wl);
 	}
 
-	while ((skb = skb_dequeue(&wl->tx_queue))) {
+	while ((skb = wl1271_skb_dequeue(wl))) {
 		if (!woken_up) {
 			ret = wl1271_ps_elp_wakeup(wl, false);
 			if (ret < 0)
@@ -284,9 +320,9 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
 			 * Aggregation buffer is full.
 			 * Flush buffer and try again.
 			 */
-			skb_queue_head(&wl->tx_queue, skb);
+			wl1271_skb_queue_head(wl, skb);
 			wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
-				buf_offset, true);
+				     buf_offset, true);
 			sent_packets = true;
 			buf_offset = 0;
 			continue;
@@ -295,7 +331,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
 			 * Firmware buffer is full.
 			 * Queue back last skb, and stop aggregating.
 			 */
-			skb_queue_head(&wl->tx_queue, skb);
+			wl1271_skb_queue_head(wl, skb);
 			/* No work left, avoid scheduling redundant tx work */
 			set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
 			goto out_ack;
@@ -440,10 +476,13 @@ void wl1271_tx_reset(struct wl1271 *wl)
 	struct sk_buff *skb;
 
 	/* TX failure */
-	while ((skb = skb_dequeue(&wl->tx_queue))) {
-		wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
-		ieee80211_tx_status(wl->hw, skb);
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
+			wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
+			ieee80211_tx_status(wl->hw, skb);
+		}
 	}
+	wl->tx_queue_count = 0;
 
 	/*
 	 * Make sure the driver is at a consistent state, in case this
@@ -472,8 +511,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
 		mutex_lock(&wl->mutex);
 		wl1271_debug(DEBUG_TX, "flushing tx buffer: %d",
 			     wl->tx_frames_cnt);
-		if ((wl->tx_frames_cnt == 0) &&
-		    skb_queue_empty(&wl->tx_queue)) {
+		if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) {
 			mutex_unlock(&wl->mutex);
 			return;
 		}
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index e904c72..78084c3 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -291,7 +291,8 @@ struct wl1271 {
 	int session_counter;
 
 	/* Frames scheduled for transmission, not handled yet */
-	struct sk_buff_head tx_queue;
+	struct sk_buff_head tx_queue[NUM_TX_QUEUES];
+	int tx_queue_count;
 
 	struct work_struct tx_work;
 
-- 
1.7.1


^ permalink raw reply related

* Re: Start dropping PCMCIA from compat-wireless for 2.6.38+
From: Holger Schurig @ 2010-12-13  7:46 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless, linux-kernel, linux-bluetooth
In-Reply-To: <AANLkTik4W+UxgyPjVyHDeEFTRCkXdDBQ9obgPkpnhzGW@mail.gmail.com>

Please, if the burden is not too much, keep it for the benefit of 
embedded people.

If you have some embedded device (e.g. ARM based), it's usually not so 
easy to hieve this device to newest 2.6.3[5-7] kernel. However, it's 
easy to use your adapted kernel, and compile compat-wireless against it.

I'm in such a situation with libertas_cs.

Greetings,
Holger

-- 
Homepage: http://www.holgerschurig.de

^ permalink raw reply

* [PATCH v2 5/7] ath9k_hw: fix PA predistortion training power selection
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau
In-Reply-To: <1292226056-56008-4-git-send-email-nbd@openwrt.org>

The EEPROM contains scale factors for the tx power, which define
the range of allowable difference between target power and training
power. If the difference is too big, PA predistortion cannot be used.
For 2.4 GHz there is only one scale factor, for 5 GHz there are
three, depending on the specific frequency range.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |   13 +++
 drivers/net/wireless/ath/ath9k/ar9003_paprd.c  |  102 ++++++++++++++++++++----
 drivers/net/wireless/ath/ath9k/ar9003_phy.h    |    8 ++
 drivers/net/wireless/ath/ath9k/hw.h            |    2 +
 drivers/net/wireless/ath/ath9k/main.c          |    4 +-
 5 files changed, 112 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 5ad37d0..4149ffb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4798,6 +4798,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
 	/* Write target power array to registers */
 	ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
 	ar9003_hw_calibration_apply(ah, chan->channel);
+
+	if (IS_CHAN_2GHZ(chan)) {
+		if (IS_CHAN_HT40(chan))
+			i = ALL_TARGET_HT40_0_8_16;
+		else
+			i = ALL_TARGET_HT20_0_8_16;
+	} else {
+		if (IS_CHAN_HT40(chan))
+			i = ALL_TARGET_HT40_7;
+		else
+			i = ALL_TARGET_HT20_7;
+	}
+	ah->paprd_target_power = targetPowerValT2[i];
 }
 
 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index cdca4c3..69f7792 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -30,9 +30,69 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
 }
 EXPORT_SYMBOL(ar9003_paprd_enable);
 
-static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
+static int ar9003_get_training_power_2g(struct ath_hw *ah)
 {
 	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
+	unsigned int power, scale, delta;
+
+	scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
+	power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
+			       AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
+
+	delta = abs((int) ah->paprd_target_power - (int) power);
+	if (delta > scale)
+		return -1;
+
+	if (delta < 4)
+		power -= 4 - delta;
+
+	return power;
+}
+
+static int get_streams(int mask)
+{
+	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
+}
+
+static int ar9003_get_training_power_5g(struct ath_hw *ah)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
+	struct ath9k_channel *chan = ah->curchan;
+	unsigned int power, scale, delta;
+
+	if (chan->channel >= 5700)
+		scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
+			   AR9300_PAPRD_SCALE_1);
+	else if (chan->channel >= 5400)
+		scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
+			   AR9300_PAPRD_SCALE_2);
+	else
+		scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
+			   AR9300_PAPRD_SCALE_1);
+
+	if (IS_CHAN_HT40(chan))
+		power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
+			AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
+	else
+		power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
+			AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
+
+	power += scale;
+	delta = abs((int) ah->paprd_target_power - (int) power);
+	if (delta > scale)
+		return -1;
+
+	power += 2 * get_streams(common->tx_chainmask);
+	return power;
+}
+
+static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
 	struct ar9300_modal_eep_header *hdr;
 	static const u32 ctrl0[3] = {
 		AR_PHY_PAPRD_CTRL0_B0,
@@ -45,6 +105,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
 		AR_PHY_PAPRD_CTRL1_B2
 	};
 	u32 am_mask, ht40_mask;
+	int training_power;
 	int i;
 
 	if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
@@ -55,11 +116,25 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
 	am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK;
 	ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK;
 
+	if (IS_CHAN_2GHZ(ah->curchan))
+		training_power = ar9003_get_training_power_2g(ah);
+	else
+		training_power = ar9003_get_training_power_5g(ah);
+
+	if (training_power < 0) {
+		ath_dbg(common, ATH_DBG_CALIBRATE,
+			"PAPRD target power delta out of range");
+		return -ERANGE;
+	}
+	ah->paprd_training_power = training_power;
+	ath_dbg(common, ATH_DBG_CALIBRATE,
+		"Training power: %d, Target power: %d\n",
+		ah->paprd_training_power, ah->paprd_target_power);
+
 	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
 	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
 	REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
 
-
 	for (i = 0; i < ah->caps.max_txchains; i++) {
 		REG_RMW_FIELD(ah, ctrl0[i],
 			      AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
@@ -141,6 +216,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
 		      AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
 	REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
 		      AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
+	return 0;
 }
 
 static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
@@ -595,15 +671,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
 {
 	u32 *paprd_table_val = caldata->pa_table[chain];
 	u32 small_signal_gain = caldata->small_signal_gain[chain];
-	u32 training_power;
+	u32 training_power = ah->paprd_training_power;
 	u32 reg = 0;
 	int i;
 
-	training_power =
-	    REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
-			   AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
-	training_power -= 4;
-
 	if (chain == 0)
 		reg = AR_PHY_PAPRD_MEM_TAB_B0;
 	else if (chain == 1)
@@ -643,14 +714,8 @@ EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
 
 int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
 {
-
 	unsigned int i, desired_gain, gain_index;
-	unsigned int train_power;
-
-	train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
-				     AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
-
-	train_power = train_power - 4;
+	unsigned int train_power = ah->paprd_training_power;
 
 	desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
 
@@ -716,7 +781,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve);
 
 int ar9003_paprd_init_table(struct ath_hw *ah)
 {
-	ar9003_paprd_setup_single_table(ah);
+	int ret;
+
+	ret = ar9003_paprd_setup_single_table(ah);
+	if (ret < 0)
+	    return ret;
+
 	ar9003_paprd_get_gain_table(ah);
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 6f811c7..59bab6b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -1090,6 +1090,14 @@
 #define AR_PHY_POWERTX_RATE5_POWERTXHT20_0	0x3F
 #define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S	0
 
+#define AR_PHY_POWERTX_RATE6			(AR_SM_BASE + 0x1d4)
+#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5	0x3F00
+#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S	8
+
+#define AR_PHY_POWERTX_RATE8			(AR_SM_BASE + 0x1dc)
+#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5	0x3F00
+#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S	8
+
 void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
 
 #endif  /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c20e047..97f22c4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -833,6 +833,8 @@ struct ath_hw {
 	u32 bb_watchdog_last_status;
 	u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
 
+	unsigned int paprd_target_power;
+	unsigned int paprd_training_power;
 	u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
 	u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
 	/*
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index bcadf9c..378485b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -373,6 +373,9 @@ void ath_paprd_calibrate(struct work_struct *work)
 	if (!caldata)
 		return;
 
+	if (ar9003_paprd_init_table(ah) < 0)
+		return;
+
 	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb)
 		return;
@@ -388,7 +391,6 @@ void ath_paprd_calibrate(struct work_struct *work)
 	memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
 
 	ath9k_ps_wakeup(sc);
-	ar9003_paprd_init_table(ah);
 	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
 		if (!(common->tx_chainmask & BIT(chain)))
 			continue;
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH v2 1/7] ath9k_hw: initialize ah->slottime
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau

(u32) -1 is not particularly useful as a slottime default, so even though
the ath9k_hw default should never get used, it's better to pick something
sane here.

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

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d44f74e..856a76e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -408,7 +408,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
 		AR_STA_ID1_CRPT_MIC_ENABLE |
 		AR_STA_ID1_MCAST_KSRCH;
 	ah->enable_32kHz_clock = DONT_USE_32KHZ;
-	ah->slottime = (u32) -1;
+	ah->slottime = 20;
 	ah->globaltxtimeout = (u32) -1;
 	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH v2 7/7] ath9k_hw: update AR9003 initvals to improve carrier leak calibration/correction
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau
In-Reply-To: <1292226056-56008-6-git-send-email-nbd@openwrt.org>

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 .../net/wireless/ath/ath9k/ar9003_2p2_initvals.h   |  100 ++++++++++----------
 1 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index ec50ca1..81f9cf2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -34,9 +34,9 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
 
 static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
+	{0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
+	{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
+	{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
 	{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
 	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -56,21 +56,21 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
 	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
 	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
 	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-	{0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
-	{0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
-	{0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
-	{0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
-	{0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
-	{0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
-	{0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
+	{0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
 	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
 	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
 	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
@@ -88,44 +88,44 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
 	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
 	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
 	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
-	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
-	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
-	{0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
-	{0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
-	{0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
-	{0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
-	{0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
-	{0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
-	{0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
 	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
-	{0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
-	{0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
-	{0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
-	{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-	{0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
-	{0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
-	{0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
+	{0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+	{0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+	{0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
+	{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
+	{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
 	{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
+	{0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
+	{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
+	{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
 	{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
 	{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH v2 4/7] ath9k_hw: fix the PA predistortion rate mask
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau
In-Reply-To: <1292226056-56008-3-git-send-email-nbd@openwrt.org>

The EEPROM PAPRD rate mask fields only contain mask values for actual
rates in the low 25 bits. The upper bits are reserved for tx power
scale values. Add the proper mask definitions and use them before
writing the values to the register.

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 620821e..efb6a02 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -31,6 +31,12 @@
 #define AR9300_ANT_16S               25
 #define AR9300_FUTURE_MODAL_SZ       6
 
+#define AR9300_PAPRD_RATE_MASK		0x01ffffff
+#define AR9300_PAPRD_SCALE_1		0x0e000000
+#define AR9300_PAPRD_SCALE_1_S		25
+#define AR9300_PAPRD_SCALE_2		0x70000000
+#define AR9300_PAPRD_SCALE_2_S		28
+
 /* Delta from which to start power to pdadc table */
 /* This offset is used in both open loop and closed loop power control
  * schemes. In open loop power control, it is not really needed, but for
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 74cff43..cdca4c3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -52,8 +52,8 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
 	else
 		hdr = &eep->modalHeader2G;
 
-	am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
-	ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
+	am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK;
+	ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK;
 
 	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
 	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH v2 3/7] ath9k: fix PA predistortion thermal measurement handling
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau
In-Reply-To: <1292226056-56008-2-git-send-email-nbd@openwrt.org>

To be able to measure the thermal values correctly for PAPRD, we need
to send training frames before setting up the gain table for the measurement,
and then again afterwards for the actual training.

For further improvement, send training frames at MCS0 instead of 54 MBit/s
legacy. That way we can use the No-ACK flag for the transmission, which
speeds up PAPRD training in general, as the hardware won't have to
retransmit and wait for ACK timeout (was previously set to 4 * 6
transmission attempts).

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

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index daa3c9f..bcadf9c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -320,6 +320,42 @@ static void ath_paprd_activate(struct ath_softc *sc)
 	ath9k_ps_restore(sc);
 }
 
+static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
+{
+	struct ieee80211_hw *hw = sc->hw;
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+	struct ath_tx_control txctl;
+	int time_left;
+
+	memset(&txctl, 0, sizeof(txctl));
+	txctl.txq = sc->tx.txq_map[WME_AC_BE];
+
+	memset(tx_info, 0, sizeof(*tx_info));
+	tx_info->band = hw->conf.channel->band;
+	tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
+	tx_info->control.rates[0].idx = 0;
+	tx_info->control.rates[0].count = 1;
+	tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
+	tx_info->control.rates[1].idx = -1;
+
+	init_completion(&sc->paprd_complete);
+	sc->paprd_pending = true;
+	txctl.paprd = BIT(chain);
+	if (ath_tx_start(hw, skb, &txctl) != 0)
+		return false;
+
+	time_left = wait_for_completion_timeout(&sc->paprd_complete,
+			msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
+	sc->paprd_pending = false;
+
+	if (!time_left)
+		ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE,
+			"Timeout waiting for paprd training on TX chain %d\n",
+			chain);
+
+	return !!time_left;
+}
+
 void ath_paprd_calibrate(struct work_struct *work)
 {
 	struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
@@ -327,18 +363,12 @@ void ath_paprd_calibrate(struct work_struct *work)
 	struct ath_hw *ah = sc->sc_ah;
 	struct ieee80211_hdr *hdr;
 	struct sk_buff *skb = NULL;
-	struct ieee80211_tx_info *tx_info;
-	int band = hw->conf.channel->band;
-	struct ieee80211_supported_band *sband = &sc->sbands[band];
-	struct ath_tx_control txctl;
 	struct ath9k_hw_cal_data *caldata = ah->caldata;
 	struct ath_common *common = ath9k_hw_common(ah);
 	int ftype;
 	int chain_ok = 0;
 	int chain;
 	int len = 1800;
-	int time_left;
-	int i;
 
 	if (!caldata)
 		return;
@@ -347,8 +377,6 @@ void ath_paprd_calibrate(struct work_struct *work)
 	if (!skb)
 		return;
 
-	tx_info = IEEE80211_SKB_CB(skb);
-
 	skb_put(skb, len);
 	memset(skb->data, 0, len);
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -359,9 +387,6 @@ void ath_paprd_calibrate(struct work_struct *work)
 	memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
 	memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
 
-	memset(&txctl, 0, sizeof(txctl));
-	txctl.txq = sc->tx.txq_map[WME_AC_BE];
-
 	ath9k_ps_wakeup(sc);
 	ar9003_paprd_init_table(ah);
 	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
@@ -369,30 +394,19 @@ void ath_paprd_calibrate(struct work_struct *work)
 			continue;
 
 		chain_ok = 0;
-		memset(tx_info, 0, sizeof(*tx_info));
-		tx_info->band = band;
 
-		for (i = 0; i < 4; i++) {
-			tx_info->control.rates[i].idx = sband->n_bitrates - 1;
-			tx_info->control.rates[i].count = 6;
-		}
+		ath_dbg(common, ATH_DBG_CALIBRATE,
+			"Sending PAPRD frame for thermal measurement "
+			"on chain %d\n", chain);
+		if (!ath_paprd_send_frame(sc, skb, chain))
+			goto fail_paprd;
 
-		init_completion(&sc->paprd_complete);
-		sc->paprd_pending = true;
 		ar9003_paprd_setup_gain_table(ah, chain);
-		txctl.paprd = BIT(chain);
-		if (ath_tx_start(hw, skb, &txctl) != 0)
-			break;
 
-		time_left = wait_for_completion_timeout(&sc->paprd_complete,
-				msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
-		sc->paprd_pending = false;
-		if (!time_left) {
-			ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-				"Timeout waiting for paprd training on TX chain %d\n",
-				chain);
+		ath_dbg(common, ATH_DBG_CALIBRATE,
+			"Sending PAPRD training frame on chain %d\n", chain);
+		if (!ath_paprd_send_frame(sc, skb, chain))
 			goto fail_paprd;
-		}
 
 		if (!ar9003_paprd_is_done(ah))
 			break;
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH v2 6/7] ath9k_hw: update AR9003 initvals for improved radar detection
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau
In-Reply-To: <1292226056-56008-5-git-send-email-nbd@openwrt.org>

Reduces the likelihood of false pulse detects in the hardware

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index a14a5e4..ec50ca1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -638,6 +638,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
 	{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
 	{0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
 	{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+	{0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f},
 	{0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
 	{0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
 	{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
@@ -680,7 +681,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
 	{0x0000981c, 0x00020028},
 	{0x00009834, 0x6400a290},
 	{0x00009838, 0x0108ecff},
-	{0x0000983c, 0x14750600},
+	{0x0000983c, 0x0d000600},
 	{0x00009880, 0x201fff00},
 	{0x00009884, 0x00001042},
 	{0x000098a4, 0x00200400},
@@ -722,7 +723,6 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
 	{0x0000a220, 0x00000000},
 	{0x0000a224, 0x00000000},
 	{0x0000a228, 0x10002310},
-	{0x0000a22c, 0x01036a27},
 	{0x0000a23c, 0x00000000},
 	{0x0000a244, 0x0c000000},
 	{0x0000a2a0, 0x00000001},
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH v2 2/7] ath9k_hw: fix the slot time setting for long distance links
From: Felix Fietkau @ 2010-12-13  7:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, vasanth, Felix Fietkau
In-Reply-To: <1292226056-56008-1-git-send-email-nbd@openwrt.org>

Testing shows that adjusting the slot time based on the coverage class
produces very high latencies and very low throughput on long distance links.

Adjusting only the ACK timeout and leaving the slot time at the regular
values - while technically not optimal for CSMA - works a lot better on
long links (tested with 10 km distance)

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

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 856a76e..3c8db81 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -808,7 +808,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
 	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
 		acktimeout += 64 - sifstime - ah->slottime;
 
-	ath9k_hw_setslottime(ah, slottime);
+	ath9k_hw_setslottime(ah, ah->slottime);
 	ath9k_hw_set_ack_timeout(ah, acktimeout);
 	ath9k_hw_set_cts_timeout(ah, acktimeout);
 	if (ah->globaltxtimeout != (u32) -1)
-- 
1.7.3.2


^ permalink raw reply related

* Re: [PATCH 5/7] ath9k_hw: fix PA predistortion training power selection
From: Vasanthakumar Thiagarajan @ 2010-12-13  7:26 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Vasanth Thiagarajan, linux-wireless@vger.kernel.org,
	linville@tuxdriver.com, Luis Rodriguez
In-Reply-To: <4D05C8EF.6030603@openwrt.org>

On Mon, Dec 13, 2010 at 12:49:11PM +0530, Felix Fietkau wrote:
> On 2010-12-13 7:02 AM, Vasanthakumar Thiagarajan wrote:
> > On Sun, Dec 12, 2010 at 07:04:35PM +0530, Felix Fietkau wrote:
> >> The EEPROM contains scale factors for the tx power, which define
> >> the range of allowable difference between target power and training
> >> power. If the difference is too big, PA predistortion cannot be used.
> >> For 2.4 GHz there is only one scale factor, for 5 GHz there are
> >> three, depending on the specific frequency range.
> >> 
> >> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> >> ---
> >>  drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |    8 ++
> >>  drivers/net/wireless/ath/ath9k/ar9003_paprd.c  |   99 ++++++++++++++++++++----
> >>  drivers/net/wireless/ath/ath9k/ar9003_phy.h    |    8 ++
> >>  drivers/net/wireless/ath/ath9k/hw.h            |    2 +
> >>  drivers/net/wireless/ath/ath9k/main.c          |    4 +-
> >>  5 files changed, 104 insertions(+), 17 deletions(-)

> >> +static int get_streams(int mask)
> >> +{
> >> +	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
> >> +}
> > ah->caps.max_txchains can be used instead of this function.
> No, it cannot. I need the number of active chains, not the number of
> chains that the hardware is capable of using.

Ah, right.
> 
> >> +
> >> +static int ar9003_get_training_power_5g(struct ath_hw *ah)
> >> +{
> >> +	struct ath_common *common = ath9k_hw_common(ah);
> >> +	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
> >> +	struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
> >> +	struct ath9k_channel *chan = ah->curchan;
> >> +	unsigned int power, scale, delta;
> >> +
> >> +	if (chan->channel >= 5700)
> >> +		scale = MS(hdr->papdRateMaskHt20, AR9300_PAPRD_SCALE_1);
> >> +	else if (chan->channel >= 5400)
> >> +		scale = MS(hdr->papdRateMaskHt40, AR9300_PAPRD_SCALE_2);
> >> +	else
> >> +		scale = MS(hdr->papdRateMaskHt40, AR9300_PAPRD_SCALE_1);
> > 
> > A helper function would be nice to get the paprd scale factor which
> > will also be used to disable paprd for particular rates. Anyway, i'm
> > doing changes to disable paprd based on scale factor and tx power,
> > i'll add a helper in my series.
> OK.

seems like it is missing endian conversion for big endian platform ?.

Vasanth

^ permalink raw reply

* Re: [PATCH 5/7] ath9k_hw: fix PA predistortion training power selection
From: Felix Fietkau @ 2010-12-13  7:19 UTC (permalink / raw)
  To: Vasanthakumar Thiagarajan
  Cc: linux-wireless@vger.kernel.org, linville@tuxdriver.com,
	Luis Rodriguez
In-Reply-To: <20101213060253.GA13721@vasanth-laptop>

On 2010-12-13 7:02 AM, Vasanthakumar Thiagarajan wrote:
> On Sun, Dec 12, 2010 at 07:04:35PM +0530, Felix Fietkau wrote:
>> The EEPROM contains scale factors for the tx power, which define
>> the range of allowable difference between target power and training
>> power. If the difference is too big, PA predistortion cannot be used.
>> For 2.4 GHz there is only one scale factor, for 5 GHz there are
>> three, depending on the specific frequency range.
>> 
>> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>> ---
>>  drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |    8 ++
>>  drivers/net/wireless/ath/ath9k/ar9003_paprd.c  |   99 ++++++++++++++++++++----
>>  drivers/net/wireless/ath/ath9k/ar9003_phy.h    |    8 ++
>>  drivers/net/wireless/ath/ath9k/hw.h            |    2 +
>>  drivers/net/wireless/ath/ath9k/main.c          |    4 +-
>>  5 files changed, 104 insertions(+), 17 deletions(-)
>> 
>> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
>> index 5ad37d0..ff03b42 100644
>> --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
>> +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
>> @@ -4798,6 +4798,14 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
>>  	/* Write target power array to registers */
>>  	ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
>>  	ar9003_hw_calibration_apply(ah, chan->channel);
>> +
>> +	if (IS_CHAN_2GHZ(chan))
>> +		i = ALL_TARGET_HT20_0_8_16;
>> +	else if (IS_CHAN_HT40(chan))
>> +		i = ALL_TARGET_HT40_7;
> 
> It looks like ALL_TARGET_HT40_0_8_16 being used in 11NGHT40.
You're right, I'll resend.

>> +	else
>> +		i = ALL_TARGET_HT20_7;
>> +	ah->paprd_target_power = targetPowerValT2[i];
>>  }
>>  
>>  static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
>> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
>> +static int get_streams(int mask)
>> +{
>> +	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
>> +}
> ah->caps.max_txchains can be used instead of this function.
No, it cannot. I need the number of active chains, not the number of
chains that the hardware is capable of using.

>> +
>> +static int ar9003_get_training_power_5g(struct ath_hw *ah)
>> +{
>> +	struct ath_common *common = ath9k_hw_common(ah);
>> +	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
>> +	struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
>> +	struct ath9k_channel *chan = ah->curchan;
>> +	unsigned int power, scale, delta;
>> +
>> +	if (chan->channel >= 5700)
>> +		scale = MS(hdr->papdRateMaskHt20, AR9300_PAPRD_SCALE_1);
>> +	else if (chan->channel >= 5400)
>> +		scale = MS(hdr->papdRateMaskHt40, AR9300_PAPRD_SCALE_2);
>> +	else
>> +		scale = MS(hdr->papdRateMaskHt40, AR9300_PAPRD_SCALE_1);
> 
> A helper function would be nice to get the paprd scale factor which
> will also be used to disable paprd for particular rates. Anyway, i'm
> doing changes to disable paprd based on scale factor and tx power,
> i'll add a helper in my series.
OK.

- Felix

^ permalink raw reply

* Re: [PATCH 5/7] ath9k_hw: fix PA predistortion training power selection
From: Vasanthakumar Thiagarajan @ 2010-12-13  6:02 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless@vger.kernel.org, linville@tuxdriver.com,
	Luis Rodriguez
In-Reply-To: <1292160877-50618-5-git-send-email-nbd@openwrt.org>

On Sun, Dec 12, 2010 at 07:04:35PM +0530, Felix Fietkau wrote:
> The EEPROM contains scale factors for the tx power, which define
> the range of allowable difference between target power and training
> power. If the difference is too big, PA predistortion cannot be used.
> For 2.4 GHz there is only one scale factor, for 5 GHz there are
> three, depending on the specific frequency range.
> 
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
>  drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |    8 ++
>  drivers/net/wireless/ath/ath9k/ar9003_paprd.c  |   99 ++++++++++++++++++++----
>  drivers/net/wireless/ath/ath9k/ar9003_phy.h    |    8 ++
>  drivers/net/wireless/ath/ath9k/hw.h            |    2 +
>  drivers/net/wireless/ath/ath9k/main.c          |    4 +-
>  5 files changed, 104 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> index 5ad37d0..ff03b42 100644
> --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> @@ -4798,6 +4798,14 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
>  	/* Write target power array to registers */
>  	ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
>  	ar9003_hw_calibration_apply(ah, chan->channel);
> +
> +	if (IS_CHAN_2GHZ(chan))
> +		i = ALL_TARGET_HT20_0_8_16;
> +	else if (IS_CHAN_HT40(chan))
> +		i = ALL_TARGET_HT40_7;

It looks like ALL_TARGET_HT40_0_8_16 being used in 11NGHT40.
> +	else
> +		i = ALL_TARGET_HT20_7;
> +	ah->paprd_target_power = targetPowerValT2[i];
>  }
>  
>  static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> +static int get_streams(int mask)
> +{
> +	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
> +}

ah->caps.max_txchains can be used instead of this function.

> +
> +static int ar9003_get_training_power_5g(struct ath_hw *ah)
> +{
> +	struct ath_common *common = ath9k_hw_common(ah);
> +	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
> +	struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
> +	struct ath9k_channel *chan = ah->curchan;
> +	unsigned int power, scale, delta;
> +
> +	if (chan->channel >= 5700)
> +		scale = MS(hdr->papdRateMaskHt20, AR9300_PAPRD_SCALE_1);
> +	else if (chan->channel >= 5400)
> +		scale = MS(hdr->papdRateMaskHt40, AR9300_PAPRD_SCALE_2);
> +	else
> +		scale = MS(hdr->papdRateMaskHt40, AR9300_PAPRD_SCALE_1);

A helper function would be nice to get the paprd scale factor which
will also be used to disable paprd for particular rates. Anyway, i'm
doing changes to disable paprd based on scale factor and tx power,
i'll add a helper in my series.
 
Vasanth

^ permalink raw reply

* Re: ath5k: IBSS Join Fail
From: Bruno Randolf @ 2010-12-13  2:18 UTC (permalink / raw)
  To: Jonathan Guerin; +Cc: linux-wireless, ath5k-devel
In-Reply-To: <AANLkTin6kK69ZGHyDZWFF=yYk8g2PmAuuPc_U-=U=pL=@mail.gmail.com>

On Thu December 9 2010 11:36:17 Jonathan Guerin wrote:
> Hi,
> 
> I'm currently running 2 Linux nodes. One is running kernel version
> 2.6.37-rc2, the other -rc5. I'm finding that the rc5 node refuses to
> join the IBSS, and simply ignores any probe requests from other
> stations. The card is working fine (i.e. I can see other frames coming
> up on a monitor-mode interface). The rc2 station sends out probe
> requests upon joining the IBSS, but the rc5 station does not.
> Reverting the rc5 station to rc2 means that it joins the IBSS
> correctly. I'm having a look through the commits to see if any changes
> occurred which may affect an IBSS join. I realise I could also bisect,
> but it takes me 40mins to rebuild a kernel, so I'm just wondering if
> anyone can think of something I can start the search on to fix this?

True, something broke IBSS merge. Same problem here, I'll try to bisect.

bruno

^ permalink raw reply

* [PATCH v2] ath9k_htc: Add Ubiquiti wifistation ext to supported devices
From: Sujith @ 2010-12-13  2:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Sujith.Manoharan

From: Sujith Manoharan <Sujith.Manoharan@atheros.com>

Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hif_usb.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 45d4b24..91d6a13 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
 	{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
 	{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
 	{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
+	{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
 
 	{ USB_DEVICE(0x0cf3, 0x7015),
 	  .driver_info = AR9287_USB },  /* Atheros */
-- 
1.7.3.3


^ permalink raw reply related

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


compat-wireless code metrics

    752722 - Total upstream lines of code being pulled
      2198 - backport code changes
      1935 - backport code additions
       263 - backport code deletions
      6637 - backport from compat module
      8835 - total backport code
    1.1737 - % of code consists of backport work
      1532 - Crap changes not yet posted
      1489 - Crap additions not yet posted
        43 - Crap deletions not yet posted
    0.2035 - % of crap code

Base tree: linux-next.git
Base tree version: next-20101210
compat-wireless release: compat-wireless-2010-12-10-1-gc0f962a-pc

^ permalink raw reply

* Re: Deauthentication for reason 6 using Intel 5300 in 2.6.34
From: Rafał Miłecki @ 2010-12-12 18:50 UTC (permalink / raw)
  To: Guy, Wey-Yi
  Cc: Larry Finger, wireless, Zheng, Jiajia,
	ipw3945-devel@lists.sourceforge.net
In-Reply-To: <1288539100.14805.16.camel@wwguy-ubuntu>

W dniu 31 października 2010 16:31 użytkownik Guy, Wey-Yi
<wey-yi.w.guy@intel.com> napisał:
> On Sun, 2010-10-31 at 02:38 -0700, Rafał Miłecki wrote:
>> It's fu* known problem. Intel doesn't seem to care about users, they
>> have fixed firmware but didn't decide to release it for 2 months.
>>
>> http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2214#c19
>>
>
> We do care very much, really sorry the delay. we need to pass regulatory
> before we can release it. I am doing everything I can to move the
> process  as fast as it can.

What about now? After another month of waiting? I'd love to replace
that Intel but it's integrated.

If it takes so long to pass regulatory, maybe Intel should change sth?
Right now?

There is just another user complaining for that:
http://permalink.gmane.org/gmane.linux.kernel.wireless.general/61320

-- 
Rafał

^ permalink raw reply

* Re: carl9170 802.11n-AP
From: Thomas @ 2010-12-12 17:47 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <AANLkTimiNLZ8EFPEwbKW3UA7FMSxmJOV-B9pWY4h9c34@mail.gmail.com>

Hi,

thanks for your answer.
I am afraid I am too much of a linux noob to solve this on my own.
Its not the Intel driver that crashes but carl9170. But I am going to test 
this with other wifi cards as well and then post the results here.

Get well soon! (for carl9170 sake :D)

Regards,

Thomas

Christian Lamparter wrote:

> On Sun, Dec 12, 2010 at 11:14 AM, thomas
> <messier31@gmx.net> wrote:
>> I just saw that there could be "aggregation stalls" with "any Intel N
>> Wifi Link".
>> I am using Intel Wifi Link 5100 and the driver frequently restarts under
>> heavy load.
> 
> see Intel's bugzilla, lots of angry posts there:
> http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2214#c19 (etc...)
> 
> I am ill, so you'll have to do the research on iwlwifi vs. carl9170 on
> your own, but it's all there just take a look at the original vendor
> driver(otus)+firmware(ar9170fw).
> 
> Regards,
>    Chr
> --
> 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] ath9k_htc: Add Ubiquity wifistation ext to supported devices
From: Gábor Stefanik @ 2010-12-12 17:29 UTC (permalink / raw)
  To: Sujith; +Cc: linville, linux-wireless, Sujith.Manoharan
In-Reply-To: <19716.42722.13272.204029@gargle.gargle.HOWL>

On Sun, Dec 12, 2010 at 11:41 AM, Sujith <m.sujith@gmail.com> wrote:
> From: Sujith Manoharan <Sujith.Manoharan@atheros.com>
>
> Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
> ---
>  drivers/net/wireless/ath/ath9k/hif_usb.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
> index 45d4b24..f09c1d8 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.c
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
> @@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
>        { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
>        { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
>        { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
> +       { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquity WifiStation Ext */

Typo: it's spelled Ubiquiti.

>
>        { USB_DEVICE(0x0cf3, 0x7015),
>          .driver_info = AR9287_USB },  /* Atheros */
> --
> 1.7.3.3
>
> --
> 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
>



-- 
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

^ 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