Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 1/2] compat-wireless: remove 28-pm-qos-params.patch
From: Hauke Mehrtens @ 2011-01-09 15:06 UTC (permalink / raw)
  To: mcgrof; +Cc: linux-wireless, Luis R. Rodriguez, Hauke Mehrtens
In-Reply-To: <1294585581-9991-1-git-send-email-hauke@hauke-m.de>

From: Luis R. Rodriguez <lrodriguez@atheros.com>

This is no longer required as Felix backported this
properly through compat.git now :)

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 patches/28-pm-qos-params.patch |  118 ----------------------------------------
 1 files changed, 0 insertions(+), 118 deletions(-)
 delete mode 100644 patches/28-pm-qos-params.patch

diff --git a/patches/28-pm-qos-params.patch b/patches/28-pm-qos-params.patch
deleted file mode 100644
index 7c9dd9e..0000000
--- a/patches/28-pm-qos-params.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-
-This patch is required because now pm-qos has 3 different flavors:
-
-On kernels >= 2.6.36 the pm qos req is kzalloc()'d by pm-qos itself
-On kernel   = 2.6.35 the pm qos req uses the stack
-On kernels <  2.6.35 the pm qos req is pegged to a unique name
-
-On newer kernels we don't use a name to tag a pm-qos requirement, and on
-older kernels we do. Although we can port over the struct pm_qos_request_list
-to older kernels it provides no variable with any unique name we can use
-for older kernels. Perhaps there's a way.. right now I just don't see it.
-
-We also should probably not bother updating pm-qos to newer versions unless 
-we are willing to treat the oldest kernels as newer ones and that'd be a
-little wierd.
-
---- a/drivers/net/wireless/ipw2x00/ipw2100.c
-+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
-@@ -174,7 +174,11 @@ that only one external action is invoked
- #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2100 Network Driver"
- #define DRV_COPYRIGHT	"Copyright(c) 2003-2006 Intel Corporation"
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- static struct pm_qos_request_list ipw2100_pm_qos_req;
-+#else
-+static struct pm_qos_request_list *ipw2100_pm_qos_req;
-+#endif
- 
- /* Debugging stuff */
- #ifdef CONFIG_IPW2100_DEBUG
-@@ -1741,7 +1745,13 @@ static int ipw2100_up(struct ipw2100_pri
- 	/* the ipw2100 hardware really doesn't want power management delays
- 	 * longer than 175usec
- 	 */
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- 	pm_qos_update_request(&ipw2100_pm_qos_req, 175);
-+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-+	pm_qos_update_request(ipw2100_pm_qos_req, 175);
-+#else
-+	pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175);
-+#endif
- 
- 	/* If the interrupt is enabled, turn it off... */
- 	spin_lock_irqsave(&priv->low_lock, flags);
-@@ -1889,7 +1899,14 @@ static void ipw2100_down(struct ipw2100_
- 	ipw2100_disable_interrupts(priv);
- 	spin_unlock_irqrestore(&priv->low_lock, flags);
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- 	pm_qos_update_request(&ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
-+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-+	pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
-+#else
-+	pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
-+				  PM_QOS_DEFAULT_VALUE);
-+#endif
- 
- 	/* We have to signal any supplicant if we are disassociating */
- 	if (associated)
-@@ -6661,8 +6678,16 @@ static int __init ipw2100_init(void)
- 	printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
- 	printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- 	pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
- 			   PM_QOS_DEFAULT_VALUE);
-+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-+	ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
-+						PM_QOS_DEFAULT_VALUE);
-+#else
-+	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
-+			       PM_QOS_DEFAULT_VALUE);
-+#endif
- 
- 	ret = pci_register_driver(&ipw2100_pci_driver);
- 	if (ret)
-@@ -6689,7 +6714,13 @@ static void __exit ipw2100_exit(void)
- 			   &driver_attr_debug_level);
- #endif
- 	pci_unregister_driver(&ipw2100_pci_driver);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- 	pm_qos_remove_request(&ipw2100_pm_qos_req);
-+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-+	pm_qos_remove_request(ipw2100_pm_qos_req);
-+#else
-+	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100");
-+#endif
- }
- 
- module_init(ipw2100_init);
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -609,7 +609,11 @@ void ieee80211_recalc_ps(struct ieee8021
- 		s32 beaconint_us;
- 
- 		if (latency < 0)
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- 			latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
-+#else
-+			latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
-+#endif
- 
- 		beaconint_us = ieee80211_tu_to_usec(
- 					found->vif.bss_conf.beacon_int);
---- a/net/mac80211/scan.c
-+++ b/net/mac80211/scan.c
-@@ -507,7 +507,11 @@ static void ieee80211_scan_state_decisio
- 		bad_latency = time_after(jiffies +
- 				ieee80211_scan_get_channel_time(next_chan),
- 				local->leave_oper_channel_time +
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
- 				usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));
-+#else
-+				usecs_to_jiffies(pm_qos_requirement(PM_QOS_NETWORK_LATENCY)));
-+#endif
- 
- 		listen_int_exceeded = time_after(jiffies +
- 				ieee80211_scan_get_channel_time(next_chan),
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/2] compat-wireless-stable-2.6.37
From: Hauke Mehrtens @ 2011-01-09 15:06 UTC (permalink / raw)
  To: mcgrof; +Cc: linux-wireless, Hauke Mehrtens

These two patches should be backported form compat-wireless based on 
linux-next to the stable version 2.6.37 as they are fixing some build 
issues with some kernel version.

Hauke Mehrtens (1):
  compat-wireless: backport power api in atl1c

Luis R. Rodriguez (1):
  compat-wireless: remove 28-pm-qos-params.patch

 patches/11-dev-pm-ops.patch    |   50 +++++++++++++++++
 patches/28-pm-qos-params.patch |  118 ----------------------------------------
 2 files changed, 50 insertions(+), 118 deletions(-)
 delete mode 100644 patches/28-pm-qos-params.patch


^ permalink raw reply

* [PATCH] compat: backport pci_wake_from_d3
From: Hauke Mehrtens @ 2011-01-09 15:00 UTC (permalink / raw)
  To: mcgrof; +Cc: linux-wireless, Hauke Mehrtens
In-Reply-To: <1294585234-9806-1-git-send-email-hauke@hauke-m.de>

This is needed by atl1c.

This is compat-wireless upstream commit:
	454fb1a4a698bd2935af76800bc17e14b086476a

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 compat/compat-2.6.28.c        |   22 ++++++++++++++++++++++
 include/linux/compat-2.6.28.h |    2 ++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/compat/compat-2.6.28.c b/compat/compat-2.6.28.c
index 7a834d2..72c9e09 100644
--- a/compat/compat-2.6.28.c
+++ b/compat/compat-2.6.28.c
@@ -439,3 +439,25 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
 }
 EXPORT_SYMBOL(n_tty_ioctl_helper);
 
+/**
+ * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
+ * @dev: PCI device to prepare
+ * @enable: True to enable wake-up event generation; false to disable
+ *
+ * Many drivers want the device to wake up the system from D3_hot or D3_cold
+ * and this function allows them to set that up cleanly - pci_enable_wake()
+ * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI
+ * ordering constraints.
+ *
+ * This function only returns error code if the device is not capable of
+ * generating PME# from both D3_hot and D3_cold, and the platform is unable to
+ * enable wake-up power for it.
+ */
+int pci_wake_from_d3(struct pci_dev *dev, bool enable)
+{
+	return pci_pme_capable(dev, PCI_D3cold) ?
+			pci_enable_wake(dev, PCI_D3cold, enable) :
+			pci_enable_wake(dev, PCI_D3hot, enable);
+}
+EXPORT_SYMBOL(pci_wake_from_d3);
+
diff --git a/include/linux/compat-2.6.28.h b/include/linux/compat-2.6.28.h
index 1de39ad..b9024d6 100644
--- a/include/linux/compat-2.6.28.h
+++ b/include/linux/compat-2.6.28.h
@@ -234,6 +234,8 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
 extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
 		       unsigned int cmd, unsigned long arg);
 
+int pci_wake_from_d3(struct pci_dev *dev, bool enable);
+
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) */
 
 #endif /* LINUX_26_28_COMPAT_H */
-- 
1.7.1


^ permalink raw reply related

* [PATCH] compat-stable-2.6.37
From: Hauke Mehrtens @ 2011-01-09 15:00 UTC (permalink / raw)
  To: mcgrof; +Cc: linux-wireless, Hauke Mehrtens

This patch should go into compat stable linux-2.6.37.y as the function 
is also used in linux version 2.6.37. It is already included in compat-
wireless based on linux-next.

Hauke Mehrtens (1):
  compat: backport pci_wake_from_d3

 compat/compat-2.6.28.c        |   22 ++++++++++++++++++++++
 include/linux/compat-2.6.28.h |    2 ++
 2 files changed, 24 insertions(+), 0 deletions(-)


^ permalink raw reply

* Re: [PATCH] ath9k: Implement rx copy-break.
From: Felix Fietkau @ 2011-01-09 14:18 UTC (permalink / raw)
  To: Björn Smedman; +Cc: Ben Greear, linux-wireless, ath9k-devel
In-Reply-To: <AANLkTim0=1wpPGPDZZzVjO0u_jvv5knA2=v4b-dTfRFq@mail.gmail.com>

On 2011-01-09 7:15 AM, Björn Smedman wrote:
> I think we should also consider the added stability/saneness with this
> patch. I for one would be willing to live with some extra cpu load if
> that means the unstoppable rx dma problem can be contained (all the
> time).
I don't think this patch has anything to do with the rx dma stop issue.

- Felix

^ permalink raw reply

* Re: [PATCH] ath9k: Implement rx copy-break.
From: Björn Smedman @ 2011-01-09 14:15 UTC (permalink / raw)
  To: Ben Greear; +Cc: Felix Fietkau, linux-wireless, ath9k-devel
In-Reply-To: <4D290A2C.6040803@candelatech.com>

On Sun, Jan 9, 2011 at 2:06 AM, Ben Greear <greearb@candelatech.com> wrote:
> On 01/08/2011 04:41 PM, Felix Fietkau wrote:
>>
>> On 2011-01-08 5:36 PM, Ben Greear wrote:
>>>
>>> On 01/08/2011 04:20 PM, Felix Fietkau wrote:
>>>>
>>>> I think this should be dependent on packet size, maybe even based on the
>>>> architecture. Especially on embedded hardware, copying large frames is
>>>> probably quite a
>>>> bit more expensive than allocating large buffers. Cache sizes are small,
>>>> memory access takes several cycles, especially during concurrent DMA.
>>>> Once I'm back home, I could try a few packet size threshold to find a
>>>> sweet spot for the typical MIPS hardware that I'm playing with. I expect a
>>>> visible
>>>> performance regression from this patch when applied as-is.
>>>
>>> I see a serious performance improvement with this patch. My current test
>>> is sending 1024 byte UDP
>>> payloads to/from each of 60 stations at 128kbps. Please do try it out on
>>> your system and see how
>>> it performs there. I'm guessing that any time you have more than 1 VIF
>>> this will be a good
>>> improvement since mac80211 does skb_copy (and you would typically be
>>> copying a much smaller
>>> packet with this patch).
>>>
>>> If we do see performance differences on different platforms, this could
>>> perhaps be
>>> something we could tune at run-time.
>>
>> What kind of system are you testing on? If it's a PC, then the performance
>> characteristics will be completely different compared to embedded hardware.
>> I've had
>> to remove a few copybreak-like implementations from various ethernet
>> drivers on similar hardware, because even taking the hit of unaligned
>> load/store exceptions
>> (which are already *very* expensive on MIPS) was less than copying the
>> full packet data, even with packet sizes less than what you're using.
>>
>> I don't have suitable test hardware with me right now, but I'll do some
>> tests in a week or so.
>
> I'm on a dual-core Atom processor.  I'm interested in your MIPs results when
> you get them...

I think we should also consider the added stability/saneness with this
patch. I for one would be willing to live with some extra cpu load if
that means the unstoppable rx dma problem can be contained (all the
time).

Perhaps make it a configuration option?

/Björn

^ permalink raw reply

* Re: Kernel Panic wlc_mac80211.c Line 6093
From: Jamie Kitson @ 2011-01-09 11:14 UTC (permalink / raw)
  To: Brett Rudley; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTimkgrc19QCdeOhc+huTsrGCD_Y8cqHnz_dQjc5y@mail.gmail.com>

>> Hmm, haven't seen this type of crash before.  Any special setup you are using?
>
> Not that I can think of. I still have the Broadcom STA compiled wl

I do boot with the noapic kernel option if that would make any difference.

Jamie

^ permalink raw reply

* Re: [PATCH] mwifiex: remove linked list implementation
From: Johannes Berg @ 2011-01-09  9:47 UTC (permalink / raw)
  To: Bing Zhao
  Cc: linux-wireless, John W. Linville, Amitkumar Karwar, Kiran Divekar,
	Frank Huang
In-Reply-To: <1294449014-15078-1-git-send-email-bzhao@marvell.com>

On Fri, 2011-01-07 at 17:10 -0800, Bing Zhao wrote:

> +	tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
> +					priv->tx_ba_stream_tbl_ptr.next;

Don't do that. Always use list_first_entry() etc, because otherwise the
struct list_head must be the first member in the struct, which is very
non-ideomatic and everybody who is used to the kernel will get it wrong
when modifying your driver.

Treat struct list_head as completely opaque -- never look into it. There
are macros for any kind of manipulation with it.

Also, all your loops are open coded -- use list_for_each_entry() instead
of doing that (even the code I quoted above is from an open coded loop)

johannes


^ permalink raw reply

* Re: [ath9k-devel] [PATCH 1/3] ath9k: Decrease skb size to fit into one page.
From: Johannes Berg @ 2011-01-09  9:34 UTC (permalink / raw)
  To: Ben Greear
  Cc: Eric Dumazet, Luis R. Rodriguez, ath9k-devel@venema.h4ckr.net,
	linux-wireless@vger.kernel.org
In-Reply-To: <4D2797D2.6000002@candelatech.com>

On Fri, 2011-01-07 at 14:46 -0800, Ben Greear wrote:
> On 01/07/2011 02:26 PM, Eric Dumazet wrote:
> > Le vendredi 07 janvier 2011 à 14:20 -0800, Ben Greear a écrit :
> >> On 0
> >>> Using skb_copy() is wrong then, since it makes a copy (order-1
> >>> allocations)
> >>>
> >>> It should use :
> >>>    skb_alloc( actual_size_of_frame  not the 3840 thing ...)
> >>>    copy(data)
> >>
> >> We need the extra stuff copied too I think (like skb->cb).
> >>
> >> If you could provide a bit more complete example code, I'll be happy
> >> to test it...
> >
> > take a random drivers/net using copybreak ... say ... tg3.c
> >
> > lines 4785
> >
> > len = length_of_the_current_frame
> > copy_skb = netdev_alloc_skb(...,  len);
> > // allocates exact required size not a byte more....
> > ...
> > skb_copy_from_linear_data(skb, copy_skb->data, len);
> > ...
> > skb_put(skb, len);
> > ...
> 
> That seems fine for drivers, but I'm guessing something different
> would be needed in the mac80211/rx.c code:
> 
> I figure doing the fix here might be a nice quick fix,
> and would help with all funky drivers.  Later, can fix the
> ath9k to do the skb copying as soon as DMA is done?

This code in mac80211 that you point out will nearly never do a copy
unless you have a lot of multicast traffic. I really don't think it
makes sense to think about changing that now.

johannes


^ permalink raw reply

* Re: [ath9k-devel] [PATCH v2 3/3] ath9k: Keep track of stations for debugfs.
From: Johannes Berg @ 2011-01-09  9:33 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: greearb@candelatech.com, linux-wireless@vger.kernel.org,
	ath9k-devel@venema.h4ckr.net
In-Reply-To: <20110107201204.GG21588@tux>

On Fri, 2011-01-07 at 12:12 -0800, Luis R. Rodriguez wrote:
> On Thu, Jan 06, 2011 at 08:49:12PM -0800, greearb@candelatech.com wrote:
> > From: Ben Greear <greearb@candelatech.com>
> > 
> > The stations hold the ath_node, which holds the tid
> > and other xmit logic structures.  In order to debug
> > stuck xmit logic, we need a way to print out the tid
> > state for the stations.
> > 
> > Signed-off-by: Ben Greear <greearb@candelatech.com>
> > ---
> > 
> > v1 -> v2:  Use linked list instead of array.  Protect with spinlock.
> 
> Again, see my comments about the # STAs limit. I think this can go in
> as a cfg80211 driver limitation which can be exposed.

There's a todo list item that is more generic -- exposing the possible
interface combinations including their counts. So if anything, we should
start working on that, although I agree that if the limit is just due to
bugs, it shouldn't be advertised.

johannes


^ permalink raw reply

* Re: [PATCH] mac80211:  Fix skb-copy failure debug message.
From: Johannes Berg @ 2011-01-09  9:32 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless
In-Reply-To: <1294511454-29985-1-git-send-email-greearb@candelatech.com>

On Sat, 2011-01-08 at 10:30 -0800, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> This particular error isn't about multicast.

Actually, it is... only multicast frames should ever be processed by
multiple interfaces.

johannes



^ permalink raw reply

* Re: [PATCH] ath9k:  Implement rx copy-break.
From: Gabor Juhos @ 2011-01-09  8:00 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <1294500800-29191-1-git-send-email-greearb@candelatech.com>

Hi Ben,

> From: Ben Greear <greearb@candelatech.com>
> 
> This saves us constantly allocating large, multi-page
> skbs.  It should fix the order-1 allocation errors reported,
> and in a 60-vif scenario, this significantly decreases CPU
> utilization, and latency, and increases bandwidth.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 b2497b8... ea2f67c... M	drivers/net/wireless/ath/ath9k/recv.c
>  drivers/net/wireless/ath/ath9k/recv.c |   92 ++++++++++++++++++++++-----------
>  1 files changed, 61 insertions(+), 31 deletions(-)

<...>

> +		if (use_copybreak) {
> +			struct pci_dev *pdev = to_pci_dev(sc->dev);

This would cause undefined behaviour with ath9k devices sitting on an AHB bus.

> +			pci_dma_sync_single_for_cpu(pdev, bf->bf_buf_addr,
> +						    len, PCI_DMA_FROMDEVICE);
> +			skb_copy_from_linear_data(bf->bf_mpdu, skb->data, len);
> +			pci_dma_sync_single_for_device(pdev, bf->bf_buf_addr,
> +						       len, PCI_DMA_FROMDEVICE);

Please use the bus agnostic equivalents of these DMA functions.

- Gabor

^ permalink raw reply

* [PATCH] ath9k:  Restart xmit logic in xmit watchdog.
From: greearb @ 2011-01-09  7:46 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Ben Greear

From: Ben Greear <greearb@candelatech.com>

The system can get into a state where the xmit queue
is stopped, but there are no packets pending, so
the queue will not be restarted.

Add logic to the xmit watchdog to attempt to restart
the xmit logic if this situation is detected.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---

NOTE:  This is basically the same as a patch I posted
a day or two ago.  It doesn't address the concern of the
reviewer who NACK'd it, but my system will not properly
transmit packets without this patch applied.  I realize
this is a bit of a hack, but until we find and fix all
of the other bugs, I think this patch or something similar
should be applied.

Still, this patch should not be applied unless given positive
ACK by the ath9k developers.

:100644 100644 93209d6... ca9d0d3... M	drivers/net/wireless/ath/ath9k/ath9k.h
:100644 100644 9e009cc... b0cb792... M	drivers/net/wireless/ath/ath9k/debug.c
:100644 100644 d9a4144... 1b3a62c... M	drivers/net/wireless/ath/ath9k/xmit.c
 drivers/net/wireless/ath/ath9k/ath9k.h |    1 +
 drivers/net/wireless/ath/ath9k/debug.c |    4 ++-
 drivers/net/wireless/ath/ath9k/xmit.c  |   57 +++++++++++++++++++++++++++-----
 3 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 93209d6..ca9d0d3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -630,6 +630,7 @@ struct ath_softc {
 	struct ath9k_debug debug;
 	spinlock_t nodes_lock;
 	struct list_head nodes; /* basically, stations */
+	unsigned int tx_complete_poll_work_seen;
 #endif
 	struct ath_beacon_config cur_beacon_conf;
 	struct delayed_work tx_complete_work;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9e009cc..b0cb792 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -629,9 +629,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 	if (buf == NULL)
 		return -ENOMEM;
 
-	len += sprintf(buf, "Num-Tx-Queues: %i  tx-queues-setup: 0x%x\n"
+	len += sprintf(buf, "Num-Tx-Queues: %i  tx-queues-setup: 0x%x"
+		       " poll-work-seen: %u\n"
 		       "%30s %10s%10s%10s\n\n",
 		       ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup,
+		       sc->tx_complete_poll_work_seen,
 		       "BE", "BK", "VI", "VO");
 
 	PR("MPDUs Queued:    ", queued);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index d9a4144..1b3a62c 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1988,19 +1988,30 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
 	tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
 }
 
-static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum)
+/* Has no locking. */
+static void __ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
 {
-	struct ath_txq *txq;
-
-	txq = sc->tx.txq_map[qnum];
-	spin_lock_bh(&txq->axq_lock);
 	if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
-		if (ath_mac80211_start_queue(sc, qnum))
+		if (ath_mac80211_start_queue(sc, txq->axq_qnum))
 			txq->stopped = 0;
 	}
+}
+
+/* Has internal locking. */
+static void _ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+{
+	spin_lock_bh(&txq->axq_lock);
+	__ath_wake_mac80211_queue(sc, txq);
 	spin_unlock_bh(&txq->axq_lock);
 }
 
+/* Has internal locking. */
+static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum)
+{
+	_ath_wake_mac80211_queue(sc, sc->tx.txq_map[qnum]);
+}
+
+
 static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -2101,10 +2112,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 		else
 			ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
 
-		if (txq == sc->tx.txq_map[qnum])
-			ath_wake_mac80211_queue(sc, qnum);
-
 		spin_lock_bh(&txq->axq_lock);
+		__ath_wake_mac80211_queue(sc, txq);
+
 		if (sc->sc_flags & SC_OP_TXAGGR)
 			ath_txq_schedule(sc, txq);
 		spin_unlock_bh(&txq->axq_lock);
@@ -2119,6 +2129,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
 	int i;
 	bool needreset = false;
 	unsigned long timeout = msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT);
+#ifdef CONFIG_ATH9K_DEBUGFS
+	sc->tx_complete_poll_work_seen++;
+#endif
 
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
 		if (ATH_TXQ_SETUP(sc, i)) {
@@ -2137,6 +2150,32 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
 					txq->axq_tx_inprogress = true;
 					txq->start_tx_timer = jiffies;
 				}
+			} else {
+				/* If the queue has pending buffers, then it
+				 * should be doing tx work (and have axq_depth).
+				 * Shouldn't get to this state I think..but
+				 * we do.
+				 */
+				if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) &&
+				    (txq->pending_frames > 0 ||
+				     !list_empty(&txq->axq_acq) ||
+				     txq->stopped)) {
+					ath_err(ath9k_hw_common(sc->sc_ah),
+						"txq: %p axq_qnum: %i,"
+						" axq_link: %p"
+						" pending frames: %i"
+						" axq_acq empty: %i"
+						" stopped: %i"
+						" axq_depth: 0  Attempting to"
+						" Restarting tx logic.\n",
+						txq, txq->axq_qnum,
+						txq->axq_link,
+						txq->pending_frames,
+						list_empty(&txq->axq_acq),
+						txq->stopped);
+					__ath_wake_mac80211_queue(sc, txq);
+					ath_txq_schedule(sc, txq);
+				}
 			}
 			spin_unlock_bh(&txq->axq_lock);
 		}
-- 
1.7.2.3


^ permalink raw reply related

* Re: [PATCH] ath9k:  Implement rx copy-break.
From: Ben Greear @ 2011-01-09  1:06 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <4D290450.8070700@openwrt.org>

On 01/08/2011 04:41 PM, Felix Fietkau wrote:
> On 2011-01-08 5:36 PM, Ben Greear wrote:
>> On 01/08/2011 04:20 PM, Felix Fietkau wrote:
>>> I think this should be dependent on packet size, maybe even based on the architecture. Especially on embedded hardware, copying large frames is probably quite a
>>> bit more expensive than allocating large buffers. Cache sizes are small, memory access takes several cycles, especially during concurrent DMA.
>>> Once I'm back home, I could try a few packet size threshold to find a sweet spot for the typical MIPS hardware that I'm playing with. I expect a visible
>>> performance regression from this patch when applied as-is.
>>
>> I see a serious performance improvement with this patch. My current test is sending 1024 byte UDP
>> payloads to/from each of 60 stations at 128kbps. Please do try it out on your system and see how
>> it performs there. I'm guessing that any time you have more than 1 VIF this will be a good
>> improvement since mac80211 does skb_copy (and you would typically be copying a much smaller
>> packet with this patch).
>>
>> If we do see performance differences on different platforms, this could perhaps be
>> something we could tune at run-time.
> What kind of system are you testing on? If it's a PC, then the performance characteristics will be completely different compared to embedded hardware. I've had
> to remove a few copybreak-like implementations from various ethernet drivers on similar hardware, because even taking the hit of unaligned load/store exceptions
> (which are already *very* expensive on MIPS) was less than copying the full packet data, even with packet sizes less than what you're using.
>
> I don't have suitable test hardware with me right now, but I'll do some tests in a week or so.

I'm on a dual-core Atom processor.  I'm interested in your MIPs results when you get them...

Thanks,
Ben

>
> - Felix


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: [PATCH] ath9k:  Implement rx copy-break.
From: Felix Fietkau @ 2011-01-09  0:41 UTC (permalink / raw)
  To: Ben Greear; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <4D290307.4080807@candelatech.com>

On 2011-01-08 5:36 PM, Ben Greear wrote:
> On 01/08/2011 04:20 PM, Felix Fietkau wrote:
>>  I think this should be dependent on packet size, maybe even based on the architecture. Especially on embedded hardware, copying large frames is probably quite a
>>  bit more expensive than allocating large buffers. Cache sizes are small, memory access takes several cycles, especially during concurrent DMA.
>>  Once I'm back home, I could try a few packet size threshold to find a sweet spot for the typical MIPS hardware that I'm playing with. I expect a visible
>>  performance regression from this patch when applied as-is.
>
> I see a serious performance improvement with this patch.  My current test is sending 1024 byte UDP
> payloads to/from each of 60 stations at 128kbps.  Please do try it out on your system and see how
> it performs there.  I'm guessing that any time you have more than 1 VIF this will be a good
> improvement since mac80211 does skb_copy (and you would typically be copying a much smaller
> packet with this patch).
>
> If we do see performance differences on different platforms, this could perhaps be
> something we could tune at run-time.
What kind of system are you testing on? If it's a PC, then the 
performance characteristics will be completely different compared to 
embedded hardware. I've had to remove a few copybreak-like 
implementations from various ethernet drivers on similar hardware, 
because even taking the hit of unaligned load/store exceptions (which 
are already *very* expensive on MIPS) was less than copying the full 
packet data, even with packet sizes less than what you're using.

I don't have suitable test hardware with me right now, but I'll do some 
tests in a week or so.

- Felix

^ permalink raw reply

* Re: [PATCH] ath9k:  Implement rx copy-break.
From: Ben Greear @ 2011-01-09  0:36 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <4D28FF57.9040706@openwrt.org>

On 01/08/2011 04:20 PM, Felix Fietkau wrote:
> On 2011-01-08 8:33 AM, greearb@candelatech.com wrote:
>> From: Ben Greear<greearb@candelatech.com>
>>
>> This saves us constantly allocating large, multi-page
>> skbs. It should fix the order-1 allocation errors reported,
>> and in a 60-vif scenario, this significantly decreases CPU
>> utilization, and latency, and increases bandwidth.
>>
>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>> ---
>> :100644 100644 b2497b8... ea2f67c... M drivers/net/wireless/ath/ath9k/recv.c
>> drivers/net/wireless/ath/ath9k/recv.c | 92 ++++++++++++++++++++++-----------
>> 1 files changed, 61 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
>> index b2497b8..ea2f67c 100644
>> --- a/drivers/net/wireless/ath/ath9k/recv.c
>> +++ b/drivers/net/wireless/ath/ath9k/recv.c
>> @@ -1702,42 +1704,70 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
>> unlikely(tsf_lower - rs.rs_tstamp> 0x10000000))
>> rxs->mactime += 0x100000000ULL;
>>
>> - /* Ensure we always have an skb to requeue once we are done
>> - * processing the current buffer's skb */
>> - requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
>> -
>> - /* If there is no memory we ignore the current RX'd frame,
>> - * tell hardware it can give us a new frame using the old
>> - * skb and put it at the tail of the sc->rx.rxbuf list for
>> - * processing. */
>> - if (!requeue_skb)
>> - goto requeue;
>> -
>> - /* Unmap the frame */
>> - dma_unmap_single(sc->dev, bf->bf_buf_addr,
>> - common->rx_bufsize,
>> - dma_type);
>> + len = rs.rs_datalen + ah->caps.rx_status_len;
>> + if (use_copybreak) {
>> + skb = netdev_alloc_skb(NULL, len);
>> + if (!skb) {
>> + skb = bf->bf_mpdu;
>> + use_copybreak = false;
>> + goto non_copybreak;
>> + }
>> + } else {
> I think this should be dependent on packet size, maybe even based on the architecture. Especially on embedded hardware, copying large frames is probably quite a
> bit more expensive than allocating large buffers. Cache sizes are small, memory access takes several cycles, especially during concurrent DMA.
> Once I'm back home, I could try a few packet size threshold to find a sweet spot for the typical MIPS hardware that I'm playing with. I expect a visible
> performance regression from this patch when applied as-is.

I see a serious performance improvement with this patch.  My current test is sending 1024 byte UDP
payloads to/from each of 60 stations at 128kbps.  Please do try it out on your system and see how
it performs there.  I'm guessing that any time you have more than 1 VIF this will be a good
improvement since mac80211 does skb_copy (and you would typically be copying a much smaller
packet with this patch).

If we do see performance differences on different platforms, this could perhaps be
something we could tune at run-time.

Thanks,
Ben

>
> - Felix


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: [PATCH] ath9k:  Implement rx copy-break.
From: Felix Fietkau @ 2011-01-09  0:20 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, ath9k-devel
In-Reply-To: <1294500800-29191-1-git-send-email-greearb@candelatech.com>

On 2011-01-08 8:33 AM, greearb@candelatech.com wrote:
> From: Ben Greear<greearb@candelatech.com>
>
> This saves us constantly allocating large, multi-page
> skbs.  It should fix the order-1 allocation errors reported,
> and in a 60-vif scenario, this significantly decreases CPU
> utilization, and latency, and increases bandwidth.
>
> Signed-off-by: Ben Greear<greearb@candelatech.com>
> ---
> :100644 100644 b2497b8... ea2f67c... M	drivers/net/wireless/ath/ath9k/recv.c
>   drivers/net/wireless/ath/ath9k/recv.c |   92 ++++++++++++++++++++++-----------
>   1 files changed, 61 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> index b2497b8..ea2f67c 100644
> --- a/drivers/net/wireless/ath/ath9k/recv.c
> +++ b/drivers/net/wireless/ath/ath9k/recv.c
> @@ -1702,42 +1704,70 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
>   		    unlikely(tsf_lower - rs.rs_tstamp>  0x10000000))
>   			rxs->mactime += 0x100000000ULL;
>
> -		/* Ensure we always have an skb to requeue once we are done
> -		 * processing the current buffer's skb */
> -		requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
> -
> -		/* If there is no memory we ignore the current RX'd frame,
> -		 * tell hardware it can give us a new frame using the old
> -		 * skb and put it at the tail of the sc->rx.rxbuf list for
> -		 * processing. */
> -		if (!requeue_skb)
> -			goto requeue;
> -
> -		/* Unmap the frame */
> -		dma_unmap_single(sc->dev, bf->bf_buf_addr,
> -				 common->rx_bufsize,
> -				 dma_type);
> +		len = rs.rs_datalen + ah->caps.rx_status_len;
> +		if (use_copybreak) {
> +			skb = netdev_alloc_skb(NULL, len);
> +			if (!skb) {
> +				skb = bf->bf_mpdu;
> +				use_copybreak = false;
> +				goto non_copybreak;
> +			}
> +		} else {
I think this should be dependent on packet size, maybe even based on the 
architecture. Especially on embedded hardware, copying large frames is 
probably quite a bit more expensive than allocating large buffers. Cache 
sizes are small, memory access takes several cycles, especially during 
concurrent DMA.
Once I'm back home, I could try a few packet size threshold to find a 
sweet spot for the typical MIPS hardware that I'm playing with. I expect 
a visible performance regression from this patch when applied as-is.

- Felix

^ permalink raw reply

* compat-wireless-2.6.37-3-sn contains wrong files
From: Hauke Mehrtens @ 2011-01-08 22:46 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless@vger.kernel.org

plusquezero on IRC complained about compat-wireless-2.6.37-3-sn not
compiling on his system with kernel 2.6.32 (
http://pastebin.com/bKyZpKSr ). I tried to create such a release and had
no problems, but the released tar balls at
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/ are
containing some extra files. These files are available in
compat-wireless based on linux-next but not in the version based on
2.6.27. Something in the script creating this release went wrong.

Attached is the diffstat beetween compat-wireless-2.6.37-3-sn.tar.bz2
and the version I generated myself with "./scripts/admin-refresh.sh -s
-n" from the git branch remotes/origin/linux-2.6.37.y of
compat-wireless.git and compat.git.

Hauke

hauke@hauke:~/compat-wireless/compat-wireless-2.6.37-3-sn$ diff -Naurx
.git -x pending-stable -x tmp.patch -x build.sh -x compiletest.sh -x
scripts . ../compat-wireless-git |diffstat
 code-metrics.txt             |   12
 compat/compat-2.6.38.c       |   50 --
 compat/kfifo.c               |  608 ------------------------------
 compat_base_tree             |    2
 include/linux/average.h      |    5
 include/linux/kfifo.h        |  857
-------------------------------------------
 include/linux/rfkill.h       |   32 -
 include/net/bluetooth/mgmt.h |   87 ----
 net/bluetooth/mgmt.c         |  308 ---------------
 net/wireless/mesh.c          |  142 -------
 10 files changed, 7 insertions(+), 2096 deletions(-)

^ permalink raw reply

* Re: 5GHz 802.11n USB Adapter
From: Helmut Schaa @ 2011-01-08 20:32 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: linux-wireless
In-Reply-To: <AANLkTimj11OJRbjO2GBn=C36D7UDUURvguERS5XYoJ7W@mail.gmail.com>

Am Samstag, 8. Januar 2011 schrieb Jason Andryuk:
> Are there any limitations for rt2800usb devices?  The wiki is short on
> information as is rt2x00.serialmonkey.com.  Does rt2800usb support AP
> mode like rt2800pci?

rt2800usb does not support bc- and mc- buffering (rt2800pci does). Hence,
powersaving stations might experience problems when using rt2800usb in AP
mode.

Helmut

^ permalink raw reply

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

>From git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/compat-wireless-2.6
   919757f..f236b99  linux-2.6.37.y -> origin/linux-2.6.37.y
 * [new tag]         compat-wireless-v2.6.37-3 -> compat-wireless-v2.6.37-3
>From git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/compat
   11316a5..7010ed0  linux-2.6.37.y -> origin/linux-2.6.37.y

compat-wireless code metrics

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

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

^ permalink raw reply

* 5GHz 802.11n USB Adapter
From: Jason Andryuk @ 2011-01-08 19:21 UTC (permalink / raw)
  To: linux-wireless

I am looking for a linux-supported dual band 802.11n USB Adapter that
can operate at both 2.4GHz and 5GHz.

According to wireless.kernel.org, it seems like the possibilities are:
carl9170/ar9170, rt2800usb and maybe ath9k_htc.

Atheros involvement with linux development is appealing, so I would
prefer an adapter based on their chips.  I also have the feeling their
drivers are more mature than the Ralink ones.

The carl9170 wiki page mentions "It's worth mentioning that the chip
was designed, produced and sold in the early 802.11n-draft period.
Compatibility will always be an issue."  So a product based on the
finalized 802.11n standard is more desirable.

For ath9k_htc, ar7010 devices with the ar9280 radio should support
dual bands.  However, the wiki does not list any devices with that
chip aside from the generic Atheros VID/PID.  Are dual band ar7010 USB
devices commercially available in the US?

Are there any limitations for rt2800usb devices?  The wiki is short on
information as is rt2x00.serialmonkey.com.  Does rt2800usb support AP
mode like rt2800pci?

Are their any other drivers/devices I have overlooked and should consider?

Recommendations of specific devices are appreciated.

Thanks,

Jason

^ permalink raw reply

* [PATCH] mac80211:  Fix skb-copy failure debug message.
From: greearb @ 2011-01-08 18:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This particular error isn't about multicast.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 a6701ed... 6d2c59b... M	net/mac80211/rx.c
 net/mac80211/rx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a6701ed..6d2c59b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2692,7 +2692,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
 		if (!skb) {
 			if (net_ratelimit())
 				wiphy_debug(local->hw.wiphy,
-					"failed to copy multicast frame for %s\n",
+					"failed to copy skb for %s\n",
 					sdata->name);
 			return true;
 		}
-- 
1.7.2.3


^ permalink raw reply related

* Re: [PATCH] compat: fix a typo in pm_qos_update_request for 2.6.35
From: Jason Andryuk @ 2011-01-08 18:25 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Luis Rodriguez, Felix Fietkau, linux-wireless, Tim Gardner
In-Reply-To: <20110107213411.GN21588@tux>

On Fri, Jan 7, 2011 at 4:34 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Fri, Jan 07, 2011 at 12:42:05PM -0800, Jason Andryuk wrote:
>> On Fri, Nov 12, 2010 at 2:16 PM, Luis R. Rodriguez
>> <lrodriguez@atheros.com> wrote:
>> > On Fri, Nov 12, 2010 at 10:47 AM, Felix Fietkau <nbd@openwrt.org> wrote:
>> >> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>> >
>> > Applied and pushed, thanks!
>> >
>> >  Luis
>>
>> This patch is to compile compat-wireless-2.6.37-2-sn.tar.bz2 on Ubuntu
>> 10.10 2.6.35-24-generic.
>
> I just sucked these two:
>
> commit 7010ed051959df86a772dd730b8ea5921cc350d8
> Author: Felix Fietkau <nbd@openwrt.org>
> Date:   Fri Nov 12 11:15:28 2010 -0800
>
>    compat: fix a typo in pm_qos_update_request for 2.6.35
>
>    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>
> commit e8f244e7399eb4eb0ef6930bbcefe6fea74b4a73
> Author: Felix Fietkau <nbd@openwrt.org>
> Date:   Fri Nov 12 11:14:44 2010 -0800
>
>    compat: fix pm_qos_params compile error on 2.6.35
>
>    Linux 2.6.35 pm_qos_params.h is missing a #ifndef/define/endif around
>    its header file contents, causing a compile error when its functions
>    are overwritten by macros in the compat header files.
>    Fix this by adding these to the compat version of this header file.
>
>    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>
> into these releases:
>
> http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-3.tar.bz2
> http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-3-sn.tar.bz2
>
> Please test and let me know if that fixes your woes.
>
>  Luis

compat-wireless-2.6.37-3-sn.tar.bz2 successfully compiled and installed for me.

Thanks,

Jason

^ permalink raw reply

* [PATCH] ath9k:  Implement rx copy-break.
From: greearb @ 2011-01-08 15:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This saves us constantly allocating large, multi-page
skbs.  It should fix the order-1 allocation errors reported,
and in a 60-vif scenario, this significantly decreases CPU
utilization, and latency, and increases bandwidth.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 b2497b8... ea2f67c... M	drivers/net/wireless/ath/ath9k/recv.c
 drivers/net/wireless/ath/ath9k/recv.c |   92 ++++++++++++++++++++++-----------
 1 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b2497b8..ea2f67c 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -16,6 +16,7 @@
 
 #include "ath9k.h"
 #include "ar9003_mac.h"
+#include <linux/pci.h>
 
 #define SKB_CB_ATHBUF(__skb)	(*((struct ath_buf **)__skb->cb))
 
@@ -1623,7 +1624,7 @@ div_comb_done:
 int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 {
 	struct ath_buf *bf;
-	struct sk_buff *skb = NULL, *requeue_skb;
+	struct sk_buff *skb = NULL, *requeue_skb = NULL;
 	struct ieee80211_rx_status *rxs;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
@@ -1634,7 +1635,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 	 */
 	struct ieee80211_hw *hw = NULL;
 	struct ieee80211_hdr *hdr;
-	int retval;
+	int retval, len;
+	bool use_copybreak = true;
 	bool decrypt_error = false;
 	struct ath_rx_status rs;
 	enum ath9k_rx_qtype qtype;
@@ -1702,42 +1704,70 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		    unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
 			rxs->mactime += 0x100000000ULL;
 
-		/* Ensure we always have an skb to requeue once we are done
-		 * processing the current buffer's skb */
-		requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
-
-		/* If there is no memory we ignore the current RX'd frame,
-		 * tell hardware it can give us a new frame using the old
-		 * skb and put it at the tail of the sc->rx.rxbuf list for
-		 * processing. */
-		if (!requeue_skb)
-			goto requeue;
-
-		/* Unmap the frame */
-		dma_unmap_single(sc->dev, bf->bf_buf_addr,
-				 common->rx_bufsize,
-				 dma_type);
+		len = rs.rs_datalen + ah->caps.rx_status_len;
+		if (use_copybreak) {
+			skb = netdev_alloc_skb(NULL, len);
+			if (!skb) {
+				skb = bf->bf_mpdu;
+				use_copybreak = false;
+				goto non_copybreak;
+			}
+		} else {
+non_copybreak:
+			/* Ensure we always have an skb to requeue once we are
+			 * done processing the current buffer's skb */
+			requeue_skb = ath_rxbuf_alloc(common,
+						      common->rx_bufsize,
+						      GFP_ATOMIC);
+
+			/* If there is no memory we ignore the current RX'd
+			 * frame, tell hardware it can give us a new frame
+			 * using the old skb and put it at the tail of the
+			 * sc->rx.rxbuf list for processing. */
+			if (!requeue_skb)
+				goto requeue;
+
+			/* Unmap the frame */
+			dma_unmap_single(sc->dev, bf->bf_buf_addr,
+					 common->rx_bufsize,
+					 dma_type);
+		}
 
-		skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
+		skb_put(skb, len);
 		if (ah->caps.rx_status_len)
 			skb_pull(skb, ah->caps.rx_status_len);
 
+		if (use_copybreak) {
+			struct pci_dev *pdev = to_pci_dev(sc->dev);
+			pci_dma_sync_single_for_cpu(pdev, bf->bf_buf_addr,
+						    len, PCI_DMA_FROMDEVICE);
+			skb_copy_from_linear_data(bf->bf_mpdu, skb->data, len);
+			pci_dma_sync_single_for_device(pdev, bf->bf_buf_addr,
+						       len, PCI_DMA_FROMDEVICE);
+			memcpy(skb->cb, bf->bf_mpdu->cb, sizeof(skb->cb));
+			rxs =  IEEE80211_SKB_RXCB(skb);
+		}
+
 		ath9k_rx_skb_postprocess(common, skb, &rs,
 					 rxs, decrypt_error);
 
-		/* We will now give hardware our shiny new allocated skb */
-		bf->bf_mpdu = requeue_skb;
-		bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
-						 common->rx_bufsize,
-						 dma_type);
-		if (unlikely(dma_mapping_error(sc->dev,
-			  bf->bf_buf_addr))) {
-			dev_kfree_skb_any(requeue_skb);
-			bf->bf_mpdu = NULL;
-			bf->bf_buf_addr = 0;
-			ath_err(common, "dma_mapping_error() on RX\n");
-			ath_rx_send_to_mac80211(hw, sc, skb);
-			break;
+		if (!use_copybreak) {
+			/* We will now give hardware our shiny new allocated
+			 * skb */
+			bf->bf_mpdu = requeue_skb;
+			bf->bf_buf_addr = dma_map_single(sc->dev,
+							 requeue_skb->data,
+							 common->rx_bufsize,
+							 dma_type);
+			if (unlikely(dma_mapping_error(sc->dev,
+						       bf->bf_buf_addr))) {
+				dev_kfree_skb_any(requeue_skb);
+				bf->bf_mpdu = NULL;
+				bf->bf_buf_addr = 0;
+				ath_err(common, "dma_mapping_error() on RX\n");
+				ath_rx_send_to_mac80211(hw, sc, skb);
+				break;
+			}
 		}
 
 		/*
-- 
1.7.2.3


^ permalink raw reply related

* Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j
From: Brian Prodoehl @ 2011-01-08 13:08 UTC (permalink / raw)
  To: Bruno Randolf; +Cc: johannes, linville, linux-wireless
In-Reply-To: <201101081243.56629.br1@einfach.org>

On Fri, Jan 7, 2011 at 10:43 PM, Bruno Randolf <br1@einfach.org> wrote:
> On Friday 07 January 2011 21:53:25 Brian Prodoehl wrote:
>> > Do all drivers still build with this patch?  I applied the previous
>> > RFC version of this patch to a late-December cut of compat-wireless,
>> > and had to touch the receive-handling code in a half-dozen or so
>> > drivers due to the API changes.
>
> I have to confess, I didn't check the drivers. Just tested with ath5k. Before
> this gets merged we have to fix all drivers which use these functions, true. I
> will try to do that next week...
>
>> Ah, I see.  All the driver changes I needed were because
>> ieee80211_channel_to_frequency() changed with the RFC patch, and this
>> patch keeps ieee80211_channel_to_frequency() the same.  Good stuff.
>
> Uh? This patch also changes ieee80211_channel_to_frequency(). Bad stuff. ;)
>
> bruno

I guess I saw what I wanted to see when I took a second look at the
re-posted patch.  Here are compile-fixes to all the affected drivers.
The following drivers are affected: mwl8k, iwlwifi, iwmc3200wifi,
libertas, rt2x00, wl1251 and wl12xx.  So I guess these driver fixes
need to be split into seven patches.  I don't use any of these
drivers, so I can't really vouch for if I'm pulling the band the
correct way for each.  I'm happy to split and submit, but I wouldn't
mind another set of eyes on these changes.


Index: compat-wireless-2011-01-07/drivers/net/wireless/mwl8k.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/mwl8k.c	2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/mwl8k.c	2011-01-08
07:51:23.843290770 -0500
@@ -834,7 +834,7 @@
 	} else {
 		status->band = IEEE80211_BAND_2GHZ;
 	}
-	status->freq = ieee80211_channel_to_frequency(rxd->channel);
+	status->freq = ieee80211_channel_to_frequency(rxd->channel, status->band);

 	*qos = rxd->qos_control;

@@ -931,7 +931,7 @@
 	} else {
 		status->band = IEEE80211_BAND_2GHZ;
 	}
-	status->freq = ieee80211_channel_to_frequency(rxd->channel);
+	status->freq = ieee80211_channel_to_frequency(rxd->channel, status->band);

 	*qos = rxd->qos_control;

Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-3945.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-3945.c	2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-3945.c	2011-01-08
07:51:23.867290769 -0500
@@ -594,10 +594,10 @@

 	rx_status.flag = 0;
 	rx_status.mactime = le64_to_cpu(rx_end->timestamp);
-	rx_status.freq =
-		ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
 	rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+	rx_status.freq =
+		ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), rx_status.band);

 	rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
 	if (rx_status.band == IEEE80211_BAND_5GHZ)
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-agn-lib.c	2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-agn-lib.c	2011-01-08
07:51:23.883290769 -0500
@@ -1157,10 +1157,10 @@

 	/* rx_status carries information about the packet to mac80211 */
 	rx_status.mactime = le64_to_cpu(phy_res->timestamp);
-	rx_status.freq =
-		ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
 	rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+	rx_status.freq =
+		ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
rx_status.band);
 	rx_status.rate_idx =
 		iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
 	rx_status.flag = 0;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-core.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-core.c	2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-core.c	2011-01-08
07:51:23.903290769 -0500
@@ -227,7 +227,10 @@
 		geo_ch = &sband->channels[sband->n_channels++];

 		geo_ch->center_freq =
-				ieee80211_channel_to_frequency(ch->channel);
+				ieee80211_channel_to_frequency(ch->channel,
+				                               is_channel_a_band(ch) ?
+				                            		   IEEE80211_BAND_5GHZ :
+				                                       IEEE80211_BAND_2GHZ);
 		geo_ch->max_power = ch->max_power_avg;
 		geo_ch->max_antenna_gain = 0xff;
 		geo_ch->hw_value = ch->channel;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwmc3200wifi/rx.c	2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/rx.c	2011-01-08
07:51:23.919290769 -0500
@@ -536,6 +536,7 @@
 	struct ieee80211_channel *chan;
 	struct iwm_umac_notif_assoc_complete *complete =
 		(struct iwm_umac_notif_assoc_complete *)buf;
+	u8 band = complete->band;

 	IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
 		     complete->bssid, complete->status);
@@ -543,7 +544,9 @@
 	switch (le32_to_cpu(complete->status)) {
 	case UMAC_ASSOC_COMPLETE_SUCCESS:
 		chan = ieee80211_get_channel(wiphy,
-			ieee80211_channel_to_frequency(complete->channel));
+			ieee80211_channel_to_frequency(complete->channel,
+			(band == UMAC_BAND_2GHZ) ?
+					IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));
 		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
 			/* Associated to a unallowed channel, disassociate. */
 			__iwm_invalidate_mlme_profile(iwm);
@@ -841,7 +844,9 @@
 		goto err;
 	}

-	freq = ieee80211_channel_to_frequency(umac_bss->channel);
+	freq = ieee80211_channel_to_frequency(umac_bss->channel,
+			umac_bss->band == UMAC_BAND_2GHZ ?
+					IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
 	channel = ieee80211_get_channel(wiphy, freq);
 	signal = umac_bss->rssi * 100;

Index: compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/cfg80211.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2011-01-08
07:51:23.927290769 -0500
@@ -287,7 +287,9 @@
 			return -EINVAL;
 		}

-		freq = ieee80211_channel_to_frequency(umac_bss->channel);
+		freq = ieee80211_channel_to_frequency(umac_bss->channel,
+			umac_bss->band == UMAC_BAND_2GHZ ?
+			                  IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
 		channel = ieee80211_get_channel(wiphy, freq);
 		signal = umac_bss->rssi * 100;

Index: compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c	2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c	2011-01-08
07:51:23.947290769 -0500
@@ -607,7 +607,8 @@
 		/* No channel, no luck */
 		if (chan_no != -1) {
 			struct wiphy *wiphy = priv->wdev->wiphy;
-			int freq = ieee80211_channel_to_frequency(chan_no);
+			int freq = ieee80211_channel_to_frequency(chan_no,
+					chan_no <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
 			struct ieee80211_channel *channel =
 				ieee80211_get_channel(wiphy, freq);

@@ -1597,7 +1598,8 @@
 	lbs_deb_enter(LBS_DEB_CFG80211);

 	survey->channel = ieee80211_get_channel(wiphy,
-		ieee80211_channel_to_frequency(priv->channel));
+		ieee80211_channel_to_frequency(priv->channel,
+			priv->channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));

 	ret = lbs_get_rssi(priv, &signal, &noise);
 	if (ret == 0) {
Index: compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/rt2x00/rt2x00dev.c	2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c	2011-01-08
07:51:23.971290769 -0500
@@ -649,7 +649,8 @@
 			      const int channel, const int tx_power,
 			      const int value)
 {
-	entry->center_freq = ieee80211_channel_to_frequency(channel);
+	entry->center_freq = ieee80211_channel_to_frequency(channel,
+			channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
 	entry->hw_value = value;
 	entry->max_power = tx_power;
 	entry->max_antenna_gain = 0xff;
Index: compat-wireless-2011-01-07/drivers/net/wireless/wl1251/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/wl1251/rx.c	2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/wl1251/rx.c	2011-01-08
07:51:23.987290769 -0500
@@ -78,7 +78,7 @@
 	 */
 	wl->noise = desc->rssi - desc->snr / 2;

-	status->freq = ieee80211_channel_to_frequency(desc->channel);
+	status->freq = ieee80211_channel_to_frequency(desc->channel, status->band);

 	status->flag |= RX_FLAG_TSFT;

Index: compat-wireless-2011-01-07/drivers/net/wireless/wl12xx/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/wl12xx/rx.c	2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/wl12xx/rx.c	2011-01-08
07:51:24.003290769 -0500
@@ -76,7 +76,7 @@
 	 */
 	wl->noise = desc->rssi - (desc->snr >> 1);

-	status->freq = ieee80211_channel_to_frequency(desc->channel);
+	status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band);

 	if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
 		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;

^ 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