mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 08:21:14 +00:00
mac80211: merge a few pending upstream fixes
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 43208
This commit is contained in:
parent
89f74722b7
commit
82e2aeb599
@ -0,0 +1,61 @@
|
|||||||
|
From: Miaoqing Pan <miaoqing@qca.qualcomm.com>
|
||||||
|
Date: Thu, 6 Nov 2014 10:52:23 +0530
|
||||||
|
Subject: [PATCH] ath9k: Fix RTC_DERIVED_CLK usage
|
||||||
|
|
||||||
|
Based on the reference clock, which could be 25MHz or 40MHz,
|
||||||
|
AR_RTC_DERIVED_CLK is programmed differently for AR9340 and AR9550.
|
||||||
|
But, when a chip reset is done, processing the initvals
|
||||||
|
sets the register back to the default value.
|
||||||
|
|
||||||
|
Fix this by moving the code in ath9k_hw_init_pll() to
|
||||||
|
ar9003_hw_override_ini(). Also, do this override for AR9531.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Miaoqing Pan <miaoqing@qca.qualcomm.com>
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||||
|
@@ -664,6 +664,19 @@ static void ar9003_hw_override_ini(struc
|
||||||
|
ah->enabled_cals |= TX_CL_CAL;
|
||||||
|
else
|
||||||
|
ah->enabled_cals &= ~TX_CL_CAL;
|
||||||
|
+
|
||||||
|
+ if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
|
||||||
|
+ if (ah->is_clk_25mhz) {
|
||||||
|
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
|
||||||
|
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
|
||||||
|
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
|
||||||
|
+ } else {
|
||||||
|
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
|
||||||
|
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
|
||||||
|
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
|
||||||
|
+ }
|
||||||
|
+ udelay(100);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar9003_hw_prog_ini(struct ath_hw *ah,
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||||
|
@@ -870,19 +870,6 @@ static void ath9k_hw_init_pll(struct ath
|
||||||
|
udelay(RTC_PLL_SETTLE_DELAY);
|
||||||
|
|
||||||
|
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
|
||||||
|
-
|
||||||
|
- if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
|
||||||
|
- if (ah->is_clk_25mhz) {
|
||||||
|
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
|
||||||
|
- REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
|
||||||
|
- REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
|
||||||
|
- } else {
|
||||||
|
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
|
||||||
|
- REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
|
||||||
|
- REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
|
||||||
|
- }
|
||||||
|
- udelay(100);
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
@ -0,0 +1,38 @@
|
|||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Wed, 5 Nov 2014 23:31:07 +0100
|
||||||
|
Subject: [PATCH] b43: fix NULL pointer dereference in b43_phy_copy()
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
phy_read and phy_write are not set for every phy any more sine this:
|
||||||
|
commit d342b95dd735014a590f9051b1ba227eb54ca8f6
|
||||||
|
Author: Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
Date: Thu Jul 31 21:59:43 2014 +0200
|
||||||
|
|
||||||
|
b43: don't duplicate common PHY read/write ops
|
||||||
|
|
||||||
|
b43_phy_copy() accesses phy_read and phy_write directly and will fail
|
||||||
|
with some phys. This patch fixes the regression by using the
|
||||||
|
b43_phy_read() and b43_phy_write() functions which should be used for
|
||||||
|
read and write access.
|
||||||
|
|
||||||
|
This should fix this bug report:
|
||||||
|
https://bugzilla.kernel.org/show_bug.cgi?id=87731
|
||||||
|
|
||||||
|
Reported-by: Volker Kempter <v.kempter@pe.tu-clausthal.de>
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/b43/phy_common.c
|
||||||
|
+++ b/drivers/net/wireless/b43/phy_common.c
|
||||||
|
@@ -301,8 +301,7 @@ void b43_phy_write(struct b43_wldev *dev
|
||||||
|
void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
|
||||||
|
{
|
||||||
|
assert_mac_suspended(dev);
|
||||||
|
- dev->phy.ops->phy_write(dev, destreg,
|
||||||
|
- dev->phy.ops->phy_read(dev, srcreg));
|
||||||
|
+ b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
|
@ -0,0 +1,33 @@
|
|||||||
|
From: Ben Greear <greearb@candelatech.com>
|
||||||
|
Date: Tue, 4 Nov 2014 15:22:49 -0800
|
||||||
|
Subject: [PATCH] ath9k: fix misc debugfs when not using chan context
|
||||||
|
|
||||||
|
When channel-context is not enabled, all vifs belong to
|
||||||
|
the first context, but it is not configured as 'assigned'.
|
||||||
|
|
||||||
|
Fix misc debugfs file to print out info for non-assigned
|
||||||
|
contexts, and also print whether ctx is assigned or not.
|
||||||
|
|
||||||
|
Signed-off-by: Ben Greear <greearb@candelatech.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
|
@@ -828,13 +828,14 @@ static ssize_t read_file_misc(struct fil
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
ath_for_each_chanctx(sc, ctx) {
|
||||||
|
- if (!ctx->assigned || list_empty(&ctx->vifs))
|
||||||
|
+ if (list_empty(&ctx->vifs))
|
||||||
|
continue;
|
||||||
|
ath9k_calculate_iter_data(sc, ctx, &iter_data);
|
||||||
|
|
||||||
|
len += scnprintf(buf + len, sizeof(buf) - len,
|
||||||
|
- "VIF-COUNTS: CTX %i AP: %i STA: %i MESH: %i WDS: %i",
|
||||||
|
- i++, iter_data.naps, iter_data.nstations,
|
||||||
|
+ "VIFS: CTX %i(%i) AP: %i STA: %i MESH: %i WDS: %i",
|
||||||
|
+ i++, (int)(ctx->assigned), iter_data.naps,
|
||||||
|
+ iter_data.nstations,
|
||||||
|
iter_data.nmeshes, iter_data.nwds);
|
||||||
|
len += scnprintf(buf + len, sizeof(buf) - len,
|
||||||
|
" ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
|
@ -0,0 +1,70 @@
|
|||||||
|
From: Ben Greear <greearb@candelatech.com>
|
||||||
|
Date: Tue, 4 Nov 2014 15:22:50 -0800
|
||||||
|
Subject: [PATCH] ath9k: fix regression in bssidmask calculation
|
||||||
|
|
||||||
|
The commit that went into 3.17:
|
||||||
|
|
||||||
|
ath9k: Summarize hw state per channel context
|
||||||
|
|
||||||
|
Group and set hw state (opmode, primary_sta, beacon conf) per
|
||||||
|
channel context instead of whole list of vifs. This would allow
|
||||||
|
each channel context to run in different mode (STA/AP).
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||||
|
Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
broke multi-vif configuration due to not properly calculating
|
||||||
|
the bssid mask.
|
||||||
|
|
||||||
|
The test case that caught this was:
|
||||||
|
|
||||||
|
create wlan0 and sta0-4 (6 total), not sure how much that matters.
|
||||||
|
associate all 6 (works fine)
|
||||||
|
disconnect 5 of them, leaving sta0 up
|
||||||
|
Start trying to bring up the other 5 one at a time. It will
|
||||||
|
fail, with iw events looking like this (in these logs, several
|
||||||
|
sta are trying to come up, but symptom is the same with just one)
|
||||||
|
|
||||||
|
The patch causing the regression made quite a few changes, but
|
||||||
|
the part I think caused this particular problem was not
|
||||||
|
recalculating the bssid mask when adding and removing interfaces.
|
||||||
|
|
||||||
|
Re-adding those calls fixes my test case. Fix bad comment
|
||||||
|
as well.
|
||||||
|
|
||||||
|
Signed-off-by: Ben Greear <greearb@candelatech.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||||
|
@@ -994,9 +994,8 @@ void ath9k_calculate_iter_data(struct at
|
||||||
|
struct ath_vif *avp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Pick the MAC address of the first interface as the new hardware
|
||||||
|
- * MAC address. The hardware will use it together with the BSSID mask
|
||||||
|
- * when matching addresses.
|
||||||
|
+ * The hardware will use primary station addr together with the
|
||||||
|
+ * BSSID mask when matching addresses.
|
||||||
|
*/
|
||||||
|
memset(iter_data, 0, sizeof(*iter_data));
|
||||||
|
memset(&iter_data->mask, 0xff, ETH_ALEN);
|
||||||
|
@@ -1225,6 +1224,8 @@ static int ath9k_add_interface(struct ie
|
||||||
|
list_add_tail(&avp->list, &avp->chanctx->vifs);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ath9k_calculate_summary_state(sc, avp->chanctx);
|
||||||
|
+
|
||||||
|
ath9k_assign_hw_queues(hw, vif);
|
||||||
|
|
||||||
|
an->sc = sc;
|
||||||
|
@@ -1294,6 +1295,8 @@ static void ath9k_remove_interface(struc
|
||||||
|
|
||||||
|
ath_tx_node_cleanup(sc, &avp->mcast_node);
|
||||||
|
|
||||||
|
+ ath9k_calculate_summary_state(sc, avp->chanctx);
|
||||||
|
+
|
||||||
|
mutex_unlock(&sc->mutex);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
Date: Mon, 3 Nov 2014 14:29:09 +0100
|
||||||
|
Subject: [PATCH] mac80211: fix use-after-free in defragmentation
|
||||||
|
|
||||||
|
Upon receiving the last fragment, all but the first fragment
|
||||||
|
are freed, but the multicast check for statistics at the end
|
||||||
|
of the function refers to the current skb (the last fragment)
|
||||||
|
causing a use-after-free bug.
|
||||||
|
|
||||||
|
Since multicast frames cannot be fragmented and we check for
|
||||||
|
this early in the function, just modify that check to also
|
||||||
|
do the accounting to fix the issue.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Reported-by: Yosef Khyal <yosefx.khyal@intel.com>
|
||||||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/mac80211/rx.c
|
||||||
|
+++ b/net/mac80211/rx.c
|
||||||
|
@@ -1678,11 +1678,14 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||||
|
frag = sc & IEEE80211_SCTL_FRAG;
|
||||||
|
|
||||||
|
- if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
|
||||||
|
- is_multicast_ether_addr(hdr->addr1))) {
|
||||||
|
- /* not fragmented */
|
||||||
|
+ if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (is_multicast_ether_addr(hdr->addr1)) {
|
||||||
|
+ rx->local->dot11MulticastReceivedFrameCount++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
I802_DEBUG_INC(rx->local->rx_handlers_fragments);
|
||||||
|
|
||||||
|
if (skb_linearize(rx->skb))
|
||||||
|
@@ -1775,10 +1778,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||||
|
out:
|
||||||
|
if (rx->sta)
|
||||||
|
rx->sta->rx_packets++;
|
||||||
|
- if (is_multicast_ether_addr(hdr->addr1))
|
||||||
|
- rx->local->dot11MulticastReceivedFrameCount++;
|
||||||
|
- else
|
||||||
|
- ieee80211_led_rx(rx->local);
|
||||||
|
+ ieee80211_led_rx(rx->local);
|
||||||
|
return RX_CONTINUE;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
|||||||
|
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||||
|
Date: Sun, 2 Nov 2014 13:38:47 +0100
|
||||||
|
Subject: [PATCH] rt2x00: do not align payload on modern H/W
|
||||||
|
|
||||||
|
RT2800 and newer hardware require padding between header and payload if
|
||||||
|
header length is not multiple of 4.
|
||||||
|
|
||||||
|
For historical reasons we also align payload to to 4 bytes boundary, but
|
||||||
|
such alignment is not needed on modern H/W.
|
||||||
|
|
||||||
|
Patch improve performance on embedded CPUs and _possibly_ fixes
|
||||||
|
skb_under_panic problems reported from time to time:
|
||||||
|
|
||||||
|
https://bugzilla.kernel.org/show_bug.cgi?id=84911
|
||||||
|
https://bugzilla.kernel.org/show_bug.cgi?id=72471
|
||||||
|
http://marc.info/?l=linux-wireless&m=139108549530402&w=2
|
||||||
|
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1087591
|
||||||
|
|
||||||
|
But we can not explain or otherwise confirm the patch fixes this panic
|
||||||
|
issue for sure.
|
||||||
|
|
||||||
|
Originally-From: Helmut Schaa <helmut.schaa@googlemail.com>
|
||||||
|
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
|
||||||
|
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
|
||||||
|
@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_b
|
||||||
|
skb_trim(skb, frame_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
|
||||||
|
+/*
|
||||||
|
+ * H/W needs L2 padding between the header and the paylod if header size
|
||||||
|
+ * is not 4 bytes aligned.
|
||||||
|
+ */
|
||||||
|
+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len)
|
||||||
|
{
|
||||||
|
- unsigned int payload_length = skb->len - header_length;
|
||||||
|
- unsigned int header_align = ALIGN_SIZE(skb, 0);
|
||||||
|
- unsigned int payload_align = ALIGN_SIZE(skb, header_length);
|
||||||
|
- unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
|
||||||
|
+ unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Adjust the header alignment if the payload needs to be moved more
|
||||||
|
- * than the header.
|
||||||
|
- */
|
||||||
|
- if (payload_align > header_align)
|
||||||
|
- header_align += 4;
|
||||||
|
-
|
||||||
|
- /* There is nothing to do if no alignment is needed */
|
||||||
|
- if (!header_align)
|
||||||
|
+ if (!l2pad)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- /* Reserve the amount of space needed in front of the frame */
|
||||||
|
- skb_push(skb, header_align);
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Move the header.
|
||||||
|
- */
|
||||||
|
- memmove(skb->data, skb->data + header_align, header_length);
|
||||||
|
-
|
||||||
|
- /* Move the payload, if present and if required */
|
||||||
|
- if (payload_length && payload_align)
|
||||||
|
- memmove(skb->data + header_length + l2pad,
|
||||||
|
- skb->data + header_length + l2pad + payload_align,
|
||||||
|
- payload_length);
|
||||||
|
-
|
||||||
|
- /* Trim the skb to the correct size */
|
||||||
|
- skb_trim(skb, header_length + l2pad + payload_length);
|
||||||
|
+ skb_push(skb, l2pad);
|
||||||
|
+ memmove(skb->data, skb->data + l2pad, hdr_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
|
||||||
|
+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len)
|
||||||
|
{
|
||||||
|
- /*
|
||||||
|
- * L2 padding is only present if the skb contains more than just the
|
||||||
|
- * IEEE 802.11 header.
|
||||||
|
- */
|
||||||
|
- unsigned int l2pad = (skb->len > header_length) ?
|
||||||
|
- L2PAD_SIZE(header_length) : 0;
|
||||||
|
+ unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
|
||||||
|
|
||||||
|
if (!l2pad)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- memmove(skb->data + l2pad, skb->data, header_length);
|
||||||
|
+ memmove(skb->data + l2pad, skb->data, hdr_len);
|
||||||
|
skb_pull(skb, l2pad);
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
@@ -1313,6 +1313,53 @@ void ath9k_deinit_debug(struct ath_softc
|
@@ -1314,6 +1314,53 @@ void ath9k_deinit_debug(struct ath_softc
|
||||||
ath9k_spectral_deinit_debug(sc);
|
ath9k_spectral_deinit_debug(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@
|
|||||||
int ath9k_init_debug(struct ath_hw *ah)
|
int ath9k_init_debug(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
@@ -1332,6 +1379,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
@@ -1333,6 +1380,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||||
ath9k_tx99_init_debug(sc);
|
ath9k_tx99_init_debug(sc);
|
||||||
ath9k_spectral_init_debug(sc);
|
ath9k_spectral_init_debug(sc);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
@@ -1360,6 +1360,52 @@ static const struct file_operations fops
|
@@ -1361,6 +1361,52 @@ static const struct file_operations fops
|
||||||
.owner = THIS_MODULE
|
.owner = THIS_MODULE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +53,7 @@
|
|||||||
int ath9k_init_debug(struct ath_hw *ah)
|
int ath9k_init_debug(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
@@ -1381,6 +1427,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
@@ -1382,6 +1428,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||||
|
|
||||||
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
|
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||||
&fops_eeprom);
|
&fops_eeprom);
|
||||||
|
@ -173,7 +173,7 @@
|
|||||||
#endif
|
#endif
|
||||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
@@ -1405,6 +1405,61 @@ static const struct file_operations fops
|
@@ -1406,6 +1406,61 @@ static const struct file_operations fops
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,7 +235,7 @@
|
|||||||
|
|
||||||
int ath9k_init_debug(struct ath_hw *ah)
|
int ath9k_init_debug(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
@@ -1429,6 +1484,10 @@ int ath9k_init_debug(struct ath_hw *ah)
|
@@ -1430,6 +1485,10 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||||
&fops_eeprom);
|
&fops_eeprom);
|
||||||
debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||||
sc, &fops_chanbw);
|
sc, &fops_chanbw);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||||
@@ -1461,6 +1461,50 @@ static const struct file_operations fops
|
@@ -1462,6 +1462,50 @@ static const struct file_operations fops
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -51,7 +51,7 @@
|
|||||||
int ath9k_init_debug(struct ath_hw *ah)
|
int ath9k_init_debug(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
@@ -1488,6 +1532,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
@@ -1489,6 +1533,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||||
debugfs_create_file("gpio_led", S_IWUSR,
|
debugfs_create_file("gpio_led", S_IWUSR,
|
||||||
sc->debug.debugfs_phy, sc, &fops_gpio_led);
|
sc->debug.debugfs_phy, sc, &fops_gpio_led);
|
||||||
#endif
|
#endif
|
||||||
@ -94,7 +94,7 @@
|
|||||||
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
|
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
|
||||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||||
@@ -1766,6 +1766,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
|
@@ -1753,6 +1753,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
|
EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
|
||||||
|
|
||||||
@ -115,7 +115,7 @@
|
|||||||
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||||
{
|
{
|
||||||
@@ -1970,6 +1984,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
@@ -1957,6 +1971,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||||
ar9003_hw_disable_phy_restart(ah);
|
ar9003_hw_disable_phy_restart(ah);
|
||||||
|
|
||||||
ath9k_hw_apply_gpio_override(ah);
|
ath9k_hw_apply_gpio_override(ah);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
void (*spectral_scan_trigger)(struct ath_hw *ah);
|
void (*spectral_scan_trigger)(struct ath_hw *ah);
|
||||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||||
@@ -1783,6 +1783,26 @@ static void ar9003_hw_tx99_set_txpower(s
|
@@ -1796,6 +1796,26 @@ static void ar9003_hw_tx99_set_txpower(s
|
||||||
ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0));
|
ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +45,7 @@
|
|||||||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||||
@@ -1818,6 +1838,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
@@ -1831,6 +1851,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||||
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
||||||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
/******************/
|
/******************/
|
||||||
/* Chip Revisions */
|
/* Chip Revisions */
|
||||||
/******************/
|
/******************/
|
||||||
@@ -1351,6 +1364,9 @@ static bool ath9k_hw_set_reset(struct at
|
@@ -1338,6 +1351,9 @@ static bool ath9k_hw_set_reset(struct at
|
||||||
if (AR_SREV_9100(ah))
|
if (AR_SREV_9100(ah))
|
||||||
udelay(50);
|
udelay(50);
|
||||||
|
|
||||||
@ -30,7 +30,7 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1450,6 +1466,9 @@ static bool ath9k_hw_chip_reset(struct a
|
@@ -1437,6 +1453,9 @@ static bool ath9k_hw_chip_reset(struct a
|
||||||
ar9003_hw_internal_regulator_apply(ah);
|
ar9003_hw_internal_regulator_apply(ah);
|
||||||
ath9k_hw_init_pll(ah, chan);
|
ath9k_hw_init_pll(ah, chan);
|
||||||
|
|
||||||
@ -40,7 +40,7 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1744,8 +1763,14 @@ static int ath9k_hw_do_fastcc(struct ath
|
@@ -1731,8 +1750,14 @@ static int ath9k_hw_do_fastcc(struct ath
|
||||||
if (AR_SREV_9271(ah))
|
if (AR_SREV_9271(ah))
|
||||||
ar9002_hw_load_ani_reg(ah, chan);
|
ar9002_hw_load_ani_reg(ah, chan);
|
||||||
|
|
||||||
@ -55,7 +55,7 @@
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1995,6 +2020,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
@@ -1982,6 +2007,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||||
ath9k_hw_set_radar_params(ah);
|
ath9k_hw_set_radar_params(ah);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
/**
|
/**
|
||||||
* ar9003_hw_set_channel - set channel on single-chip device
|
* ar9003_hw_set_channel - set channel on single-chip device
|
||||||
* @ah: atheros hardware structure
|
* @ah: atheros hardware structure
|
||||||
@@ -971,11 +957,6 @@ static bool ar9003_hw_ani_control(struct
|
@@ -984,11 +970,6 @@ static bool ar9003_hw_ani_control(struct
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
struct ath9k_channel *chan = ah->curchan;
|
struct ath9k_channel *chan = ah->curchan;
|
||||||
struct ar5416AniState *aniState = &ah->ani;
|
struct ar5416AniState *aniState = &ah->ani;
|
||||||
@ -91,7 +91,7 @@
|
|||||||
s32 value, value2;
|
s32 value, value2;
|
||||||
|
|
||||||
switch (cmd & ah->ani_function) {
|
switch (cmd & ah->ani_function) {
|
||||||
@@ -989,61 +970,6 @@ static bool ar9003_hw_ani_control(struct
|
@@ -1002,61 +983,6 @@ static bool ar9003_hw_ani_control(struct
|
||||||
*/
|
*/
|
||||||
u32 on = param ? 1 : 0;
|
u32 on = param ? 1 : 0;
|
||||||
|
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
[RFC] rt2x00: For drivers that only need L2 padding don't realign frames
|
|
||||||
|
|
||||||
Signed-off-by: Helmut Schaa <helmut.schaa@...>
|
|
||||||
---
|
|
||||||
|
|
||||||
Ivo, Gertjan, do you remeber by any chance why this alignment stuff was added
|
|
||||||
in the first place? Was it because of DMA restrictions?
|
|
||||||
|
|
||||||
While doing some profiling on the rt3052 SoC I noticed that 30-40% time was
|
|
||||||
spent in memmove calls. And the culprit is the memmove aligning the payload
|
|
||||||
to a 4byte boundary since that has to move a whole bunch of data.
|
|
||||||
|
|
||||||
Interesstingly the legacy drivers insert an l2pad between the header and the
|
|
||||||
payload but doesn't realign the payload itself to a 4-byte boundary. Hence,
|
|
||||||
I came up with this patch and indeed CPU usage improves impressively.
|
|
||||||
|
|
||||||
Only tested on rt2800pci!
|
|
||||||
|
|
||||||
Thanks,
|
|
||||||
Helmut
|
|
||||||
|
|
||||||
drivers/net/wireless/rt2x00/rt2x00queue.c | 30 +++-------------------------
|
|
||||||
1 files changed, 4 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
|
|
||||||
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
|
|
||||||
@@ -161,36 +161,14 @@ void rt2x00queue_align_frame(struct sk_b
|
|
||||||
void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
|
|
||||||
{
|
|
||||||
unsigned int payload_length = skb->len - header_length;
|
|
||||||
- unsigned int header_align = ALIGN_SIZE(skb, 0);
|
|
||||||
- unsigned int payload_align = ALIGN_SIZE(skb, header_length);
|
|
||||||
unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Adjust the header alignment if the payload needs to be moved more
|
|
||||||
- * than the header.
|
|
||||||
- */
|
|
||||||
- if (payload_align > header_align)
|
|
||||||
- header_align += 4;
|
|
||||||
-
|
|
||||||
- /* There is nothing to do if no alignment is needed */
|
|
||||||
- if (!header_align)
|
|
||||||
+ if (!l2pad)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- /* Reserve the amount of space needed in front of the frame */
|
|
||||||
- skb_push(skb, header_align);
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Move the header.
|
|
||||||
- */
|
|
||||||
- memmove(skb->data, skb->data + header_align, header_length);
|
|
||||||
-
|
|
||||||
- /* Move the payload, if present and if required */
|
|
||||||
- if (payload_length && payload_align)
|
|
||||||
- memmove(skb->data + header_length + l2pad,
|
|
||||||
- skb->data + header_length + l2pad + payload_align,
|
|
||||||
- payload_length);
|
|
||||||
-
|
|
||||||
- /* Trim the skb to the correct size */
|
|
||||||
+ /* insert l2pad -> Move header */
|
|
||||||
+ skb_push(skb, l2pad);
|
|
||||||
+ memmove(skb->data, skb->data + l2pad, header_length);
|
|
||||||
skb_trim(skb, header_length + l2pad + payload_length);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user