2012-11-15 14:08:17

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Arend,

As promised, here's the updated patch series for brcmsmac to remove the
tx packet queue, add flow control, and add enhanced debug trace support.
I've broken up the tx rework into multiple patches as you requested.
Most notably I've split out the AMPDU session support into a separate
patch, which should make it easier to review that change. I've done
basic testing of each of the new commits to try and verify that no
obvious regressions are introduced by any of them.

Patch 6 contains the real meat of the tx changes and is still fairly
large. It's going to be difficult to break up this patch any further
though. The most obvious thing to break out at this point would be the
flow control support. However, doing this before removing the tx queue
basically results in throw-away code, and removing it after means that
the commit that removes the tx queue may not work well, potentially
making bisects more difficult. The flow control changes really aren't
that big anyway.

Otherwise the changes are pretty trivial, and functionally the end
result should be identical to v1. I've found that I am still receiving
frames occasionally after stopping a queue so I've kept the headroom in
the tx fifos for now.

Changes since v1:

* Break up the tx path rework as much as possible
* BRCMDBG no longer selects BRCMS_TRACING
* Macro for checking for enabled debug levels has been removed in favor
of open coding the checks
* brcms_debug.[ch] renamed to debug.[ch]
* Debug macros changed to lower-case
* Removed some additional dead code
* A few trivial clean-ups

Thanks,
Seth


Seth Forshee (22):
brcmsmac: Introduce AMPDU sessions for assembling AMPDUs
brcmsmac: Don't weight AMPDU packets in txfifo
brcmsmac: Add helper function for updating txavail count
brcmsmac: Remove unimplemented flow control functions
brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels
brcmsmac: Remove internal tx queue
brcmsmac: Use correct descriptor count when calculating next rx
descriptor
brcmsmac: Reduce number of entries in tx DMA rings
brcm80211: Allow trace support to be enabled separately from debug
brcm80211: Convert log message levels to debug levels
brcmsmac: Add module parameter for setting the debug level
brcmsmac: Add support for writing debug messages to the trace buffer
brcmsmac: Use debug macros for general error and debug statements
brcmsmac: Add brcms_dbg_mac80211() debug macro
brcmsmac: Add rx and tx debug macros
brcmsmac: Add brcms_dbg_int() debug macro
brcmsmac: Add brcms_dbg_dma() debug macro
brcmsmac: Add brcms_dbg_ht() debug macro
brcmsmac: Improve tx trace and debug support
brcmsmac: Add tracepoint for macintstatus
brcmsmac: Add tracepoint for AMPDU session information
brcmsmac: Remove some noisy and uninformative debug messages

drivers/net/wireless/brcm80211/Kconfig | 11 +
drivers/net/wireless/brcm80211/brcmsmac/Makefile | 3 +-
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 723 ++++++------
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 29 +-
drivers/net/wireless/brcm80211/brcmsmac/antsel.c | 4 +-
.../brcm80211/brcmsmac/brcms_trace_events.h | 175 ++-
drivers/net/wireless/brcm80211/brcmsmac/channel.c | 10 +-
drivers/net/wireless/brcm80211/brcmsmac/debug.c | 44 +
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 46 +
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 343 ++++--
drivers/net/wireless/brcm80211/brcmsmac/dma.h | 11 +-
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 123 ++-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 1166 ++++++--------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 48 +-
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 37 -
drivers/net/wireless/brcm80211/brcmsmac/stf.c | 8 +-
drivers/net/wireless/brcm80211/brcmsmac/types.h | 3 +-
drivers/net/wireless/brcm80211/include/defs.h | 11 +-
18 files changed, 1298 insertions(+), 1497 deletions(-)
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.c
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.h



2012-11-16 15:19:03

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 01/22] brcmsmac: Introduce AMPDU sessions for assembling AMPDUs

On Fri, Nov 16, 2012 at 04:02:30PM +0100, Arend van Spriel wrote:
> On 11/16/2012 03:12 PM, Seth Forshee wrote:
> >What does strike me as problematic is the locking in brcms_ops_flush().
> >It holds wl->lock, and the interrupt handling tries to acquire the same
> >lock. Doesn't this prevent both the txpktpend counts from getting
> >updated and any more packets being transmitted from the packet queue?
> >
> >Seth
> >
>
> Actually, in the brcms_c_wait_for_tx_completion() the while loop
> does a brcms_msleep() which releases the wl->lock, does an msleep()
> and acquires the lock. At least that is what is currently in
> wireless-testing. I changed it internally to wait_for_event()
> mechanism, but it was not accepted as people still were seeing
> issues.

Ah, I failed to look at what brcms_msleep() is doing so I didn't notice
that. Nevermind then.

Seth

2012-11-22 18:48:42

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 12/22] brcmsmac: Add support for writing debug messages to the trace buffer

On 11/19/2012 09:35 PM, Arend van Spriel wrote:
> On 11/15/2012 03:08 PM, Seth Forshee wrote:
>> Add a new brcmsmac_msg trace system to enable writing of debug messages
>> to the trace buffer, and add brcms_* macros for storing device debug
>> messages in the trace buffer in addition to the printk log buffer.
>
> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
> Reviewed-by: Arend van Spriel <[email protected]>
>> Signed-off-by: Seth Forshee <[email protected]>
>> ---
>> drivers/net/wireless/brcm80211/brcmsmac/Makefile | 3 +-
>> .../brcm80211/brcmsmac/brcms_trace_events.h | 68
>> +++++++++++++++++++-
>> drivers/net/wireless/brcm80211/brcmsmac/debug.c | 44 +++++++++++++
>> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 40 ++++++++++++
>> 4 files changed, 151 insertions(+), 4 deletions(-)
>> create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.c
>> create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.h

Hi Seth,

Internally, we already had a debug.[ch] as we added some debugfs
functionality. I am merging your changes into it, but that means your
code will be put under the same permissive license as the other source
code, ie. Dual BSD/GPL. So I feel obliged to ask: Are you ok with me
doing that and do you want me to add your name in the copyright notice?

Gr. AvS



2012-11-19 21:19:55

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 09/22] brcm80211: Allow trace support to be enabled separately from debug

On 11/19/2012 10:15 PM, Seth Forshee wrote:
> On Mon, Nov 19, 2012 at 09:33:13PM +0100, Arend van Spriel wrote:
>> On 11/15/2012 03:07 PM, Seth Forshee wrote:
>>> Since the runtime overhead of trace support is small when tracing is
>>> disabled, users may be interested in turning on trace support while
>>> leaving other debug features off. Add a new config option named
>>> CONFIG_BRCM_TRACING for this purpose.
>>
>> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
>> Reviewed-by: Arend van Spriel
>>> Signed-off-by: Seth Forshee <[email protected]>
>>> ---
>>> drivers/net/wireless/brcm80211/Kconfig | 11 +++++++++++
>>> .../brcm80211/brcmsmac/brcms_trace_events.h | 6 +++---
>>> 2 files changed, 14 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
>>> index c9d811e..3735c27 100644
>>> --- a/drivers/net/wireless/brcm80211/Kconfig
>>> +++ b/drivers/net/wireless/brcm80211/Kconfig
>>> @@ -63,6 +63,17 @@ config BRCMISCAN
>>> new E-Scan method which uses less memory in firmware and gives no
>>> limitation on the number of scan results.
>>>
>>> +config BRCM_TRACING
>>> + bool "Broadcom device tracing"
>>> + depends on BRCMSMAC || BRCMFMAC
>>> + ---help---
>>> + If you say Y here, the Broadcom wireless drivers will register
>>> + with ftrace to dump event information into the trace ringbuffer.
>>> + Tracing can be enabled at runtime to aid in debugging wireless
>>> + issues. This option adds a small amount of overhead when tracing
>>> + is disabled. If unsure, say Y to allow developers to better help
>>> + you when wireless problems occur.
>>> +
>>
>> I regard this as a debugging feature. Did you consider making it
>> depend on BRCMDBG instead? Or do you think that BRCMDBG code would
>> affect run-time behavior during tracing.
>
> It is a debugging feature, but making it depend on BRCMDBG prevents my
> intended use case. I'm planning to enable BRCM_TRACING in Ubuntu and to
> leave BRCMDBG disabled. This will make it easy for us to ask users for
> detailed debug information when needed with minimal overhead during
> normal use.

That seems reasonable. Have you any significant impact in throughput
with tracing enabled?

Gr. AvS



2012-11-15 14:08:47

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 15/22] brcmsmac: Add rx and tx debug macros

Also convert relevant messages over to use thses macros.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 2 ++
drivers/net/wireless/brcm80211/brcmsmac/main.c | 18 ++++++++----------
drivers/net/wireless/brcm80211/include/defs.h | 2 ++
3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
index f4f5090..b979128 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -37,5 +37,7 @@ static inline void __brcms_dbg(struct device *dev, u32 level,

#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a)
#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a)
+#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a)
+#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a)

#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 9c976b2..d6df923 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -882,7 +882,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
*/
if (!(txs->status & TX_STATUS_AMPDU)
&& (txs->status & TX_STATUS_INTERMEDIATE)) {
- BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
+ brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n");
fatal = false;
goto out;
}
@@ -925,9 +925,9 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)

supr_status = txs->status & TX_STATUS_SUPR_MASK;
if (supr_status == TX_STATUS_SUPR_BADCH)
- BCMMSG(wlc->wiphy,
- "%s: Pkt tx suppressed, possibly channel %d\n",
- __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+ brcms_dbg_tx(wlc->hw->d11core,
+ "Pkt tx suppressed, possibly channel %d\n",
+ CHSPEC_CHANNEL(wlc->default_bss->chanspec));

tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
tx_frame_count =
@@ -1039,7 +1039,6 @@ static bool
brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
{
bool morepending = false;
- struct brcms_c_info *wlc = wlc_hw->wlc;
struct bcma_device *core;
struct tx_status txstatus, *txs;
u32 s1, s2;
@@ -1050,7 +1049,7 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
*/
uint max_tx_num = bound ? TXSBND : -1;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_tx(core, "wl%d\n", wlc_hw->unit);

txs = &txstatus;
core = wlc_hw->d11core;
@@ -1528,8 +1527,7 @@ brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
u16 mac_m;
u16 mac_h;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
- wlc_hw->unit);
+ brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit);

mac_l = addr[0] | (addr[1] << 8);
mac_m = addr[2] | (addr[3] << 8);
@@ -7831,7 +7829,7 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
uint len;
bool is_amsdu;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ brcms_dbg_rx(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);

/* frame starts with rxhdr */
rxh = (struct d11rxhdr *) (p->data);
@@ -7889,7 +7887,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
uint n = 0;
uint bound_limit = bound ? RXBND : -1;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_rx(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
skb_queue_head_init(&recv_frames);

/* gather received frames */
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index 4d6906f..9206d2c 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -81,6 +81,8 @@
/* Debug levels */
#define BRCM_DL_INFO 0x00000001
#define BRCM_DL_MAC80211 0x00000002
+#define BRCM_DL_RX 0x00000004
+#define BRCM_DL_TX 0x00000008

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-11-15 14:08:43

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 13/22] brcmsmac: Use debug macros for general error and debug statements

Convert most uses of wiphy_* and pr_* for general error and debug
messages to use the internal debug macros instead. Most code used only
for initialization still use wiphy_err(), as well as some locations
which are executed too early to use the debug macros. Some debug
messages which are redundant or not useful are removed.

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 20 +-
drivers/net/wireless/brcm80211/brcmsmac/antsel.c | 4 +-
drivers/net/wireless/brcm80211/brcmsmac/channel.c | 10 +-
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 107 +++----
drivers/net/wireless/brcm80211/brcmsmac/main.c | 292 ++++++++++----------
5 files changed, 221 insertions(+), 212 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 93d4ecd..2916ddf 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -21,6 +21,7 @@
#include "antsel.h"
#include "main.h"
#include "ampdu.h"
+#include "debug.h"

/* max number of mpdus in an ampdu */
#define AMPDU_MAX_MPDU 32
@@ -179,18 +180,19 @@ static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
{
struct brcms_c_info *wlc = ampdu->wlc;
+ struct bcma_device *core = wlc->hw->d11core;

wlc->pub->_ampdu = false;

if (on) {
if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
- wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
- "nmode enabled\n", wlc->pub->unit);
+ brcms_err(core, "wl%d: driver not nmode enabled\n",
+ wlc->pub->unit);
return -ENOTSUPP;
}
if (!brcms_c_ampdu_cap(ampdu)) {
- wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
- "ampdu capable\n", wlc->pub->unit);
+ brcms_err(core, "wl%d: device not ampdu capable\n",
+ wlc->pub->unit);
return -ENOTSUPP;
}
wlc->pub->_ampdu = on;
@@ -481,7 +483,7 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
scb_ampdu = &scb->scb_ampdu;

if (!ampdu->ini_enable[tid]) {
- wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
+ brcms_err(wlc->hw->d11core, "%s: Rejecting tid %d\n",
__func__, tid);
return;
}
@@ -896,13 +898,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
if (supr_status) {
update_rate = false;
if (supr_status == TX_STATUS_SUPR_BADCH) {
- wiphy_err(wiphy,
+ brcms_err(wlc->hw->d11core,
"%s: Pkt tx suppressed, illegal channel possibly %d\n",
__func__, CHSPEC_CHANNEL(
wlc->default_bss->chanspec));
} else {
if (supr_status != TX_STATUS_SUPR_FRAG)
- wiphy_err(wiphy, "%s: supr_status 0x%x\n",
+ brcms_err(wlc->hw->d11core,
+ "%s: supr_status 0x%x\n",
__func__, supr_status);
}
/* no need to retry for badch; will fail again */
@@ -923,7 +926,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
}
} else if (txs->phyerr) {
update_rate = false;
- wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
+ brcms_err(wlc->hw->d11core,
+ "%s: ampdu tx phy error (0x%x)\n",
__func__, txs->phyerr);

if (brcm_msg_level & BRCM_DL_INFO) {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
index 55e12c3..54c6169 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
@@ -21,6 +21,7 @@
#include "main.h"
#include "phy_shim.h"
#include "antsel.h"
+#include "debug.h"

#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
@@ -137,7 +138,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
asi->antsel_avail = false;
} else {
asi->antsel_avail = false;
- wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
+ brcms_err(wlc->hw->d11core,
+ "antsel_attach: 2o3 "
"board cfg invalid\n");
}

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index 64a48f0..a90b722 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -26,6 +26,7 @@
#include "stf.h"
#include "channel.h"
#include "mac80211_if.h"
+#include "debug.h"

/* QDB() macro takes a dB value and converts to a quarter dB value */
#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
@@ -336,8 +337,6 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
const char *ccode = sprom->alpha2;
int ccode_len = sizeof(sprom->alpha2);

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
-
wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
if (wlc_cm == NULL)
return NULL;
@@ -615,8 +614,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec)

/* check the chanspec */
if (brcms_c_chspec_malformed(chspec)) {
- wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
- wlc->pub->unit, chspec);
+ brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n",
+ wlc->pub->unit, chspec);
return false;
}

@@ -738,7 +737,8 @@ static int brcms_reg_notifier(struct wiphy *wiphy,
mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
} else {
mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
- wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n",
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: no valid channel for \"%s\"\n",
wlc->pub->unit, __func__, request->alpha2);
}

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 37b9966..8c835cd 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -33,6 +33,7 @@
#include "ucode_loader.h"
#include "mac80211_if.h"
#include "main.h"
+#include "debug.h"

#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */

@@ -280,7 +281,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw,

spin_lock_bh(&wl->lock);
if (!wl->pub->up) {
- wiphy_err(wl->wiphy, "ops->tx called while down\n");
+ brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n");
kfree_skb(skb);
goto done;
}
@@ -317,8 +318,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
spin_unlock_bh(&wl->lock);

if (err != 0)
- wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
- err);
+ brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n",
+ __func__, err);
return err;
}

@@ -336,7 +337,7 @@ static void brcms_ops_stop(struct ieee80211_hw *hw)
status = brcms_c_chipmatch(wl->wlc->hw->d11core);
spin_unlock_bh(&wl->lock);
if (!status) {
- wiphy_err(wl->wiphy,
+ brcms_err(wl->wlc->hw->d11core,
"wl: brcms_ops_stop: chipmatch failed\n");
return;
}
@@ -354,8 +355,9 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)

/* Just STA for now */
if (vif->type != NL80211_IFTYPE_STATION) {
- wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
- " STA for now\n", __func__, vif->type);
+ brcms_err(wl->wlc->hw->d11core,
+ "%s: Attempt to add type %d, only STA for now\n",
+ __func__, vif->type);
return -EOPNOTSUPP;
}

@@ -374,9 +376,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
{
struct ieee80211_conf *conf = &hw->conf;
struct brcms_info *wl = hw->priv;
+ struct bcma_device *core = wl->wlc->hw->d11core;
int err = 0;
int new_int;
- struct wiphy *wiphy = hw->wiphy;

spin_lock_bh(&wl->lock);
if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
@@ -384,25 +386,26 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
conf->listen_interval);
}
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
- wiphy_dbg(wiphy, "%s: change monitor mode: %s\n",
- __func__, conf->flags & IEEE80211_CONF_MONITOR ?
- "true" : "false");
+ brcms_dbg_info(core, "%s: change monitor mode: %s\n",
+ __func__, conf->flags & IEEE80211_CONF_MONITOR ?
+ "true" : "false");
if (changed & IEEE80211_CONF_CHANGE_PS)
- wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
+ brcms_err(core, "%s: change power-save mode: %s (implement)\n",
__func__, conf->flags & IEEE80211_CONF_PS ?
"true" : "false");

if (changed & IEEE80211_CONF_CHANGE_POWER) {
err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
if (err < 0) {
- wiphy_err(wiphy, "%s: Error setting power_level\n",
+ brcms_err(core, "%s: Error setting power_level\n",
__func__);
goto config_out;
}
new_int = brcms_c_get_tx_power(wl->wlc);
if (new_int != conf->power_level)
- wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
- "\n", __func__, conf->power_level,
+ brcms_err(core,
+ "%s: Power level req != actual, %d %d\n",
+ __func__, conf->power_level,
new_int);
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -429,13 +432,13 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *info, u32 changed)
{
struct brcms_info *wl = hw->priv;
- struct wiphy *wiphy = hw->wiphy;
+ struct bcma_device *core = wl->wlc->hw->d11core;

if (changed & BSS_CHANGED_ASSOC) {
/* association status changed (associated/disassociated)
* also implies a change in the AID.
*/
- wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
+ brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME,
__func__, info->assoc ? "" : "dis");
spin_lock_bh(&wl->lock);
brcms_c_associate_upd(wl->wlc, info->assoc);
@@ -495,7 +498,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
error = brcms_c_set_rateset(wl->wlc, &rs);
spin_unlock_bh(&wl->lock);
if (error)
- wiphy_err(wiphy, "changing basic rates failed: %d\n",
+ brcms_err(core, "changing basic rates failed: %d\n",
error);
}
if (changed & BSS_CHANGED_BEACON_INT) {
@@ -512,30 +515,30 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_BEACON)
/* Beacon data changed, retrieve new beacon (beaconing modes) */
- wiphy_err(wiphy, "%s: beacon changed\n", __func__);
+ brcms_err(core, "%s: beacon changed\n", __func__);

if (changed & BSS_CHANGED_BEACON_ENABLED) {
/* Beaconing should be enabled/disabled (beaconing modes) */
- wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
+ brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
info->enable_beacon ? "true" : "false");
}

if (changed & BSS_CHANGED_CQM) {
/* Connection quality monitor config changed */
- wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
+ brcms_err(core, "%s: cqm change: threshold %d, hys %d "
" (implement)\n", __func__, info->cqm_rssi_thold,
info->cqm_rssi_hyst);
}

if (changed & BSS_CHANGED_IBSS) {
/* IBSS join status changed */
- wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
- info->ibss_joined ? "true" : "false");
+ brcms_err(core, "%s: IBSS joined: %s (implement)\n",
+ __func__, info->ibss_joined ? "true" : "false");
}

if (changed & BSS_CHANGED_ARP_FILTER) {
/* Hardware ARP filter address list or state changed */
- wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
+ brcms_err(core, "%s: arp filtering: enabled %s, count %d"
" (implement)\n", __func__, info->arp_filter_enabled ?
"true" : "false", info->arp_addr_cnt);
}
@@ -545,8 +548,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
* QoS for this association was enabled/disabled.
* Note that it is only ever disabled for station mode.
*/
- wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
- info->qos ? "true" : "false");
+ brcms_err(core, "%s: qos enabled: %s (implement)\n",
+ __func__, info->qos ? "true" : "false");
}
return;
}
@@ -557,25 +560,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags, u64 multicast)
{
struct brcms_info *wl = hw->priv;
- struct wiphy *wiphy = hw->wiphy;
+ struct bcma_device *core = wl->wlc->hw->d11core;

changed_flags &= MAC_FILTERS;
*total_flags &= MAC_FILTERS;

if (changed_flags & FIF_PROMISC_IN_BSS)
- wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n");
+ brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n");
if (changed_flags & FIF_ALLMULTI)
- wiphy_dbg(wiphy, "FIF_ALLMULTI\n");
+ brcms_dbg_info(core, "FIF_ALLMULTI\n");
if (changed_flags & FIF_FCSFAIL)
- wiphy_dbg(wiphy, "FIF_FCSFAIL\n");
+ brcms_dbg_info(core, 0, "FIF_FCSFAIL\n");
if (changed_flags & FIF_CONTROL)
- wiphy_dbg(wiphy, "FIF_CONTROL\n");
+ brcms_dbg_info(core, "FIF_CONTROL\n");
if (changed_flags & FIF_OTHER_BSS)
- wiphy_dbg(wiphy, "FIF_OTHER_BSS\n");
+ brcms_dbg_info(core, "FIF_OTHER_BSS\n");
if (changed_flags & FIF_PSPOLL)
- wiphy_dbg(wiphy, "FIF_PSPOLL\n");
+ brcms_dbg_info(core, "FIF_PSPOLL\n");
if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
- wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n");
+ brcms_dbg_info(core, "FIF_BCN_PRBRESP_PROMISC\n");

spin_lock_bh(&wl->lock);
brcms_c_mac_promisc(wl->wlc, *total_flags);
@@ -657,8 +660,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
status = brcms_c_aggregatable(wl->wlc, tid);
spin_unlock_bh(&wl->lock);
if (!status) {
- wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
- tid);
+ brcms_err(wl->wlc->hw->d11core,
+ "START: tid %d is not agg\'able\n", tid);
return -EINVAL;
}
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -685,8 +688,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
/* Power save wakeup */
break;
default:
- wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
- __func__);
+ brcms_err(wl->wlc->hw->d11core,
+ "%s: Invalid command, ignoring\n", __func__);
}

return 0;
@@ -1148,14 +1151,13 @@ static int brcms_suspend(struct bcma_device *pdev)
wl->pub->hw_up = false;
spin_unlock_bh(&wl->lock);

- pr_debug("brcms_suspend ok\n");
+ brcms_dbg_info(wl->wlc->hw->d11core, "brcms_suspend ok\n");

return 0;
}

static int brcms_resume(struct bcma_device *pdev)
{
- pr_debug("brcms_resume ok\n");
return 0;
}

@@ -1216,7 +1218,7 @@ module_exit(brcms_module_exit);
void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
bool state, int prio)
{
- wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
+ brcms_err(wl->wlc->hw->d11core, "Shouldn't be here %s\n", __func__);
}

/*
@@ -1224,7 +1226,8 @@ void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
*/
void brcms_init(struct brcms_info *wl)
{
- BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
+ brcms_dbg_info(wl->wlc->hw->d11core, "Initializing wl%d\n",
+ wl->pub->unit);
brcms_reset(wl);
brcms_c_init(wl->wlc, wl->mute_tx);
}
@@ -1234,7 +1237,7 @@ void brcms_init(struct brcms_info *wl)
*/
uint brcms_reset(struct brcms_info *wl)
{
- BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
+ brcms_dbg_info(wl->wlc->hw->d11core, "Resetting wl%d\n", wl->pub->unit);
brcms_c_reset(wl->wlc);

/* dpc will not be rescheduled */
@@ -1248,7 +1251,7 @@ uint brcms_reset(struct brcms_info *wl)

void brcms_fatal_error(struct brcms_info *wl)
{
- wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n",
+ brcms_err(wl->wlc->hw->d11core, "wl%d: fatal error, reinitializing\n",
wl->wlc->pub->unit);
brcms_reset(wl);
ieee80211_restart_hw(wl->pub->ieee_hw);
@@ -1396,8 +1399,9 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)

#ifdef DEBUG
if (t->set)
- wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
- __func__, t->name, periodic);
+ brcms_dbg_info(t->wl->wlc->hw->d11core,
+ "%s: Already set. Name: %s, per %d\n",
+ __func__, t->name, periodic);
#endif
t->ms = ms;
t->periodic = (bool) periodic;
@@ -1486,8 +1490,8 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
}
}
}
- wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
- idx);
+ brcms_err(wl->wlc->hw->d11core,
+ "ERROR: ucode buf tag:%d can not be found!\n", idx);
*pbuf = NULL;
fail:
return -ENODATA;
@@ -1510,7 +1514,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
pdata = wl->fw.fw_bin[i]->data +
le32_to_cpu(hdr->offset);
if (le32_to_cpu(hdr->len) != 4) {
- wiphy_err(wl->wiphy,
+ brcms_err(wl->wlc->hw->d11core,
"ERROR: fw hdr len\n");
return -ENOMSG;
}
@@ -1519,7 +1523,8 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
}
}
}
- wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
+ brcms_err(wl->wlc->hw->d11core,
+ "ERROR: ucode tag:%d can not be found!\n", idx);
return -ENOMSG;
}

@@ -1560,8 +1565,8 @@ int brcms_check_firmwares(struct brcms_info *wl)
sizeof(struct firmware_hdr));
rc = -EBADF;
} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
- wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
- "%zu\n", __func__, fw->size);
+ wiphy_err(wl->wiphy, "%s: out of bounds fw file size %zu\n",
+ __func__, fw->size);
rc = -EBADF;
} else {
/* check if ucode section overruns firmware image */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index bde36e5..87db750 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -35,6 +35,7 @@
#include "main.h"
#include "soc.h"
#include "dma.h"
+#include "debug.h"

/* watchdog timer, in unit of ms */
#define TIMER_INTERVAL_WATCHDOG 1000
@@ -640,7 +641,7 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
uint rate = rspec2rate(ratespec);

if (rate == 0) {
- wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
+ brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n",
wlc->pub->unit);
rate = BRCM_RATE_1M;
}
@@ -710,7 +711,7 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
u16 size;
u32 value;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);

for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
size = le16_to_cpu(inits[i].size);
@@ -739,7 +740,6 @@ static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)

static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
{
- struct wiphy *wiphy = wlc_hw->wlc->wiphy;
struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;

/* init microcode host flags */
@@ -750,8 +750,9 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
if (BRCMS_ISNPHY(wlc_hw->band))
brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
else
- wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
- " %d\n", __func__, wlc_hw->unit,
+ brcms_err(wlc_hw->d11core,
+ "%s: wl%d: unsupported phy in corerev %d\n",
+ __func__, wlc_hw->unit,
wlc_hw->corerev);
} else {
if (D11REV_IS(wlc_hw->corerev, 24)) {
@@ -759,12 +760,14 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
brcms_c_write_inits(wlc_hw,
ucode->d11lcn0bsinitvals24);
else
- wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
- " core rev %d\n", __func__,
- wlc_hw->unit, wlc_hw->corerev);
+ brcms_err(wlc_hw->d11core,
+ "%s: wl%d: unsupported phy in core rev %d\n",
+ __func__, wlc_hw->unit,
+ wlc_hw->corerev);
} else {
- wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
- __func__, wlc_hw->unit, wlc_hw->corerev);
+ brcms_err(wlc_hw->d11core,
+ "%s: wl%d: unsupported corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev);
}
}
}
@@ -779,7 +782,7 @@ static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)

static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk);

wlc_hw->phyclk = clk;

@@ -898,7 +901,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)

if (txs->phyerr) {
if (brcm_msg_level & BRCM_DL_INFO) {
- wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
+ brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
txs->phyerr, txh->MainRates);
brcms_c_print_txdesc(txh);
}
@@ -934,7 +937,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
lastframe = !ieee80211_has_morefrags(h->frame_control);

if (!lastframe) {
- wiphy_err(wlc->wiphy, "Not last frame!\n");
+ brcms_err(wlc->hw->d11core, "Not last frame!\n");
} else {
/*
* Set information to be consumed by Minstrel ht.
@@ -1006,8 +1009,9 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
skb_pull(p, D11_TXH_LEN);
ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
} else {
- wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
- "tx_status\n", __func__);
+ brcms_err(wlc->hw->d11core,
+ "%s: Not last frame => not calling tx_status\n",
+ __func__);
}

fatal = false;
@@ -1055,8 +1059,8 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
&& (s1 & TXS_V)) {

if (s1 == 0xffffffff) {
- wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
- wlc_hw->unit, __func__);
+ brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ __func__);
return morepending;
}
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
@@ -1132,7 +1136,6 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
u16 pio_mhf2 = 0;
struct brcms_hardware *wlc_hw = wlc->hw;
uint unit = wlc_hw->unit;
- struct wiphy *wiphy = wlc->wiphy;

/* name and offsets for dma_attach */
snprintf(name, sizeof(name), "wl%d", unit);
@@ -1188,8 +1191,9 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
/* Cleaner to leave this as if with AP defined */

if (dma_attach_err) {
- wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
- "\n", unit);
+ brcms_err(wlc_hw->d11core,
+ "wl%d: wlc_attach: dma_attach failed\n",
+ unit);
return false;
}

@@ -1547,7 +1551,7 @@ brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
__le32 word_le;
__be32 word_be;
bool be_bit;
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(core, "wl%d\n", wlc_hw->unit);

bcma_write32(core, D11REGOFFS(tplatewrptr), offset);

@@ -1756,8 +1760,6 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
/* Perform a soft reset of the PHY PLL */
void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr),
~0, 0);
udelay(1);
@@ -1802,7 +1804,7 @@ void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
u32 phy_bw_clkbits;
bool phy_in_reset = false;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit);

if (pih == NULL)
return;
@@ -1936,7 +1938,7 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_
/* power both the pll and external oscillator on/off */
static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want);

/*
* dont power down if plldown is false or
@@ -2025,7 +2027,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
if (flags == BRCMS_USE_COREFLAGS)
flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit);

/* request FAST clock if not on */
fastclk = wlc_hw->forcefastclk;
@@ -2036,13 +2038,13 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
if (bcma_core_is_enabled(wlc_hw->d11core)) {
for (i = 0; i < NFIFO; i++)
if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
- wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
+ brcms_err(wlc_hw->d11core, "wl%d: %s: "
"dma_txreset[%d]: cannot stop dma\n",
wlc_hw->unit, __func__, i);

if ((wlc_hw->di[RX_FIFO])
&& (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
- wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
+ brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset"
"[%d]: cannot stop dma\n",
wlc_hw->unit, __func__, RX_FIFO);
}
@@ -2255,7 +2257,7 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
uint i;
uint count;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);

count = (nbytes / sizeof(u32));

@@ -2283,8 +2285,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
ucode->bcm43xx_16_mimosz);
wlc_hw->ucode_loaded = true;
} else
- wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
- "corerev %d\n",
+ brcms_err(wlc_hw->d11core,
+ "%s: wl%d: unsupported phy in corerev %d\n",
__func__, wlc_hw->unit, wlc_hw->corerev);
} else if (D11REV_IS(wlc_hw->corerev, 24)) {
if (BRCMS_ISLCNPHY(wlc_hw->band)) {
@@ -2292,8 +2294,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
ucode->bcm43xx_24_lcnsz);
wlc_hw->ucode_loaded = true;
} else {
- wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
- "corerev %d\n",
+ brcms_err(wlc_hw->d11core,
+ "%s: wl%d: unsupported phy in corerev %d\n",
__func__, wlc_hw->unit, wlc_hw->corerev);
}
}
@@ -2330,7 +2332,6 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
uint unit;
uint intstatus, idx;
struct bcma_device *core = wlc_hw->d11core;
- struct wiphy *wiphy = wlc_hw->wlc->wiphy;

unit = wlc_hw->unit;

@@ -2347,35 +2348,35 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
unit, idx, intstatus);

if (intstatus & I_RO) {
- wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
+ brcms_err(core, "wl%d: fifo %d: receive fifo "
"overflow\n", unit, idx);
fatal = true;
}

if (intstatus & I_PC) {
- wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
- unit, idx);
+ brcms_err(core, "wl%d: fifo %d: descriptor error\n",
+ unit, idx);
fatal = true;
}

if (intstatus & I_PD) {
- wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
+ brcms_err(core, "wl%d: fifo %d: data error\n", unit,
idx);
fatal = true;
}

if (intstatus & I_DE) {
- wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
+ brcms_err(core, "wl%d: fifo %d: descriptor protocol "
"error\n", unit, idx);
fatal = true;
}

if (intstatus & I_RU)
- wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
+ brcms_err(core, "wl%d: fifo %d: receive descriptor "
"underflow\n", idx, unit);

if (intstatus & I_XU) {
- wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
+ brcms_err(core, "wl%d: fifo %d: transmit fifo "
"underflow\n", idx, unit);
fatal = true;
}
@@ -2625,8 +2626,8 @@ bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
macintstatus = wlc_intstatus(wlc, true);

if (macintstatus == 0xffffffff)
- wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
- " path\n");
+ brcms_err(wlc_hw->d11core,
+ "DEVICEREMOVED detected in the ISR code path\n");

/* it is not for us */
if (macintstatus == 0)
@@ -2646,7 +2647,6 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
struct brcms_hardware *wlc_hw = wlc->hw;
struct bcma_device *core = wlc_hw->d11core;
u32 mc, mi;
- struct wiphy *wiphy = wlc->wiphy;

BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
wlc_hw->band->bandunit);
@@ -2664,7 +2664,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
mc = bcma_read32(core, D11REGOFFS(maccontrol));

if (mc == 0xffffffff) {
- wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__);
brcms_down(wlc->wl);
return;
@@ -2675,7 +2675,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)

mi = bcma_read32(core, D11REGOFFS(macintstatus));
if (mi == 0xffffffff) {
- wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__);
brcms_down(wlc->wl);
return;
@@ -2688,10 +2688,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
BRCMS_MAX_MAC_SUSPEND);

if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) {
- wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
+ brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
" and MI_MACSSPNDD is still not on.\n",
wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
- wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
+ brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
"psm_brc 0x%04x\n", wlc_hw->unit,
bcma_read32(core, D11REGOFFS(psmdebug)),
bcma_read32(core, D11REGOFFS(phydebug)),
@@ -2700,7 +2700,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)

mc = bcma_read32(core, D11REGOFFS(maccontrol));
if (mc == 0xffffffff) {
- wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__);
brcms_down(wlc->wl);
return;
@@ -2760,8 +2760,6 @@ static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
u32 w, val;
struct wiphy *wiphy = wlc_hw->wlc->wiphy;

- BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
-
/* Validate dchip register access */

bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
@@ -2822,7 +2820,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
struct bcma_device *core = wlc_hw->d11core;
u32 tmp;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(core, "wl%d\n", wlc_hw->unit);

tmp = 0;

@@ -2838,8 +2836,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)

tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT)
- wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
- " PLL failed\n", __func__);
+ brcms_err(core, "%s: turn on PHY PLL failed\n",
+ __func__);
} else {
bcma_set32(core, D11REGOFFS(clk_ctl_st),
tmp | CCS_ERSRC_REQ_D11PLL |
@@ -2855,8 +2853,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
(CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
!=
(CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
- wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
- "PHY PLL failed\n", __func__);
+ brcms_err(core, "%s: turn on PHY PLL failed\n",
+ __func__);
}
} else {
/*
@@ -2874,7 +2872,7 @@ static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
{
bool dev_gone;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit);

dev_gone = brcms_deviceremoved(wlc_hw->wlc);

@@ -3131,7 +3129,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
/* check for rx fifo 0 overflow */
delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
if (delta)
- wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
+ brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n",
wlc->pub->unit, delta);

/* check for tx fifo underflows */
@@ -3140,8 +3138,9 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
(u16) (wlc->core->macstat_snapshot->txfunfl[i] -
txfunfl[i]);
if (delta)
- wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
- "\n", wlc->pub->unit, delta, i);
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %u tx fifo %d underflows!\n",
+ wlc->pub->unit, delta, i);
}
#endif /* DEBUG */

@@ -3154,8 +3153,6 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)

static void brcms_b_reset(struct brcms_hardware *wlc_hw)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
/* reset the core */
if (!brcms_deviceremoved(wlc_hw->wlc))
brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
@@ -3166,7 +3163,7 @@ static void brcms_b_reset(struct brcms_hardware *wlc_hw)

void brcms_c_reset(struct brcms_c_info *wlc)
{
- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);

/* slurp up hw mac counters before core reset */
brcms_c_statsupd(wlc);
@@ -3211,10 +3208,9 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
bool fifosz_fixup = false;
int err = 0;
u16 buf[NFIFO];
- struct wiphy *wiphy = wlc->wiphy;
struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit);

/* reset PSM */
brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
@@ -3234,7 +3230,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) &
MI_MACSSPNDD) == 0), 1000 * 1000);
if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0)
- wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
+ brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-"
"suspend!\n", wlc_hw->unit);

brcms_c_gpio_init(wlc);
@@ -3245,18 +3241,18 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
if (BRCMS_ISNPHY(wlc_hw->band))
brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
else
- wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+ brcms_err(core, "%s: wl%d: unsupported phy in corerev"
" %d\n", __func__, wlc_hw->unit,
wlc_hw->corerev);
} else if (D11REV_IS(wlc_hw->corerev, 24)) {
if (BRCMS_ISLCNPHY(wlc_hw->band))
brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
else
- wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+ brcms_err(core, "%s: wl%d: unsupported phy in corerev"
" %d\n", __func__, wlc_hw->unit,
wlc_hw->corerev);
} else {
- wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+ brcms_err(core, "%s: wl%d: unsupported corerev %d\n",
__func__, wlc_hw->unit, wlc_hw->corerev);
}

@@ -3298,7 +3294,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
err = -1;
}
if (err != 0)
- wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
+ brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d"
" driver size %d index %d\n", buf[i],
wlc_hw->xmtfifo_sz[i], i);

@@ -3381,8 +3377,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
bool fastclk;
struct brcms_c_info *wlc = wlc_hw->wlc;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
/* request FAST clock if not on */
fastclk = wlc_hw->forcefastclk;
if (!fastclk)
@@ -3475,7 +3469,7 @@ static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
rate = (rateset->rates[i] & BRCMS_RATE_MASK);

if (rate > BRCM_MAXRATE) {
- wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
+ brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: "
"invalid rate 0x%X in rate set\n",
rateset->rates[i]);
continue;
@@ -3551,7 +3545,6 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
uint parkband;
uint i, band_order[2];

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
/*
* We might have been bandlocked during down and the chip
* power-cycled (hibernate). Figure out the right band to park on
@@ -3732,8 +3725,8 @@ static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
/* band-specific init */
static void brcms_c_bsinit(struct brcms_c_info *wlc)
{
- BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
- wlc->pub->unit, wlc->band->bandunit);
+ brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n",
+ wlc->pub->unit, wlc->band->bandunit);

/* write ucode ACK/CTS rate table */
brcms_c_set_ratetable(wlc);
@@ -3756,7 +3749,8 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
M_TX_IDLE_BUSY_RATIO_X_16_CCK;
if (duty_cycle > 100 || duty_cycle < 0) {
- wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n",
+ brcms_err(wlc->hw->d11core,
+ "wl%d: duty cycle value off limit\n",
wlc->pub->unit);
return -EINVAL;
}
@@ -3930,7 +3924,7 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
u16 old_chanspec = wlc->chanspec;

if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
+ brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n",
wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
return;
}
@@ -3941,8 +3935,8 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
switchband = true;
if (wlc->bandlocked) {
- wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
- "band is locked!\n",
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: chspec %d band is locked!\n",
wlc->pub->unit, __func__,
CHSPEC_CHANNEL(chanspec));
return;
@@ -4006,6 +4000,10 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
*/
void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
{
+ /*
+ * Cannot use brcms_dbg_* here because this function is called
+ * before wlc is sufficiently initialized.
+ */
BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);

switch (idx) {
@@ -4078,8 +4076,8 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,

/* Only apply params if the core is out of reset and has clocks */
if (!wlc->clk) {
- wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
- __func__);
+ brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n",
+ wlc->pub->unit, __func__);
return;
}

@@ -4097,7 +4095,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,

if (acp_shm.aifs < EDCF_AIFSN_MIN
|| acp_shm.aifs > EDCF_AIFSN_MAX) {
- wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
+ brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad "
"aifs %d\n", wlc->pub->unit, acp_shm.aifs);
} else {
acp_shm.cwmin = params->cw_min;
@@ -4212,8 +4210,8 @@ static void brcms_c_radio_timer(void *arg)
struct brcms_c_info *wlc = (struct brcms_c_info *) arg;

if (brcms_deviceremoved(wlc)) {
- wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
- __func__);
+ brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n",
+ wlc->pub->unit, __func__);
brcms_down(wlc->wl);
return;
}
@@ -4226,8 +4224,6 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc)
{
struct brcms_hardware *wlc_hw = wlc->hw;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
if (!wlc_hw->up)
return;

@@ -4246,14 +4242,14 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc)
/* common watchdog code */
static void brcms_c_watchdog(struct brcms_c_info *wlc)
{
- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);

if (!wlc->pub->up)
return;

if (brcms_deviceremoved(wlc)) {
- wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
- __func__);
+ brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n",
+ wlc->pub->unit, __func__);
brcms_down(wlc->wl);
return;
}
@@ -4425,13 +4421,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
struct ssb_sprom *sprom = &core->bus->sprom;

if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
- BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
- pcidev->vendor,
- pcidev->device);
+ brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit,
+ pcidev->vendor,
+ pcidev->device);
else
- BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
- core->bus->boardinfo.vendor,
- core->bus->boardinfo.type);
+ brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit,
+ core->bus->boardinfo.vendor,
+ core->bus->boardinfo.type);

wme = true;

@@ -4703,8 +4699,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
goto fail;
}

- BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n",
- wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih));
+ brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n",
+ wlc_hw->deviceid, wlc_hw->_nbands,
+ ai_get_boardtype(wlc_hw->sih));

return err;

@@ -4960,7 +4957,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
if (wlc_hw->wlc->pub->hw_up)
return;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);

/*
* Enable pll and xtal, initialize the power control registers,
@@ -4997,7 +4994,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)

static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);

/*
* Enable pll and xtal, initialize the power control registers,
@@ -5036,8 +5033,6 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)

static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
wlc_hw->up = true;
wlc_phy_hw_state_upd(wlc_hw->band->pi, true);

@@ -5069,7 +5064,7 @@ int brcms_c_up(struct brcms_c_info *wlc)
{
struct ieee80211_channel *ch;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);

/* HW is turned off so don't try to access it */
if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
@@ -5110,8 +5105,8 @@ int brcms_c_up(struct brcms_c_info *wlc)
WL_RADIO_HW_DISABLE);

if (bsscfg->enable && bsscfg->BSS)
- wiphy_err(wlc->wiphy, "wl%d: up"
- ": rfdisable -> "
+ brcms_err(wlc->hw->d11core,
+ "wl%d: up: rfdisable -> "
"bsscfg_disable()\n",
wlc->pub->unit);
}
@@ -5171,8 +5166,6 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
bool dev_gone;
uint callbacks = 0;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
if (!wlc_hw->up)
return callbacks;

@@ -5199,8 +5192,6 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
uint callbacks = 0;
bool dev_gone;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
-
if (!wlc_hw->up)
return callbacks;

@@ -5249,12 +5240,13 @@ uint brcms_c_down(struct brcms_c_info *wlc)
int i;
bool dev_gone = false;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);

/* check if we are already in the going down path */
if (wlc->going_down) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
- "\n", wlc->pub->unit, __func__);
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: Driver going down so return\n",
+ wlc->pub->unit, __func__);
return 0;
}
if (!wlc->pub->up)
@@ -5367,7 +5359,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)

default:
/* Error */
- wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
+ brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n",
wlc->pub->unit, __func__, gmode);
return -ENOTSUPP;
}
@@ -6015,7 +6007,7 @@ brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
u8 preamble_type)
{
BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
- "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
+ "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -6138,7 +6130,7 @@ static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
return true;
error:
if (verbose)
- wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
+ brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x "
"not in hw_rateset\n", wlc->pub->unit, rspec);

return false;
@@ -6148,6 +6140,7 @@ static u32
mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
u32 int_val)
{
+ struct bcma_device *core = wlc->hw->d11core;
u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
u8 rate = int_val & NRATE_RATE_MASK;
u32 rspec;
@@ -6164,7 +6157,7 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
/* mcs only allowed when nmode */
if (stf > PHY_TXC1_MODE_SDM) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
+ brcms_err(core, "wl%d: %s: Invalid stf\n",
wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
@@ -6175,8 +6168,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
if (!CHSPEC_IS40(wlc->home_chanspec) ||
((stf != PHY_TXC1_MODE_SISO)
&& (stf != PHY_TXC1_MODE_CDD))) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
- "32\n", wlc->pub->unit, __func__);
+ brcms_err(core, "wl%d: %s: Invalid mcs 32\n",
+ wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
}
@@ -6197,15 +6190,15 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
if ((stf > PHY_TXC1_MODE_STBC) ||
(!BRCMS_STBC_CAP_PHY(wlc)
&& (stf == PHY_TXC1_MODE_STBC))) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
- "\n", wlc->pub->unit, __func__);
+ brcms_err(core, "wl%d: %s: Invalid STBC\n",
+ wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
}
}
} else if (is_ofdm_rate(rate)) {
if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
+ brcms_err(core, "wl%d: %s: Invalid OFDM\n",
wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
@@ -6213,20 +6206,20 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
} else if (is_cck_rate(rate)) {
if ((cur_band->bandtype != BRCM_BAND_2G)
|| (stf != PHY_TXC1_MODE_SISO)) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
+ brcms_err(core, "wl%d: %s: Invalid CCK\n",
wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
}
} else {
- wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
+ brcms_err(core, "wl%d: %s: Unknown rate type\n",
wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
}
/* make sure multiple antennae are available for non-siso rates */
if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
- wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
+ brcms_err(core, "wl%d: %s: SISO antenna but !SISO "
"request\n", wlc->pub->unit, __func__);
bcmerror = -EINVAL;
goto done;
@@ -6295,7 +6288,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
break;

default:
- wiphy_err(wlc->wiphy,
+ brcms_err(wlc->hw->d11core,
"brcms_c_cck_plcp_set: unsupported rate %d\n",
rate_500);
rate_500 = BRCM_RATE_1M;
@@ -6428,7 +6421,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
bw = rspec_get_bw(rspec);
/* 10Mhz is not supported yet */
if (bw < PHY_TXC1_BW_20MHZ) {
- wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
+ brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is "
"not supported yet, set to 20L\n", bw);
bw = PHY_TXC1_BW_20MHZ;
}
@@ -6455,7 +6448,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
/* get the phyctl byte from rate phycfg table */
phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
if (phycfg == -1) {
- wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
+ brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong "
"legacy OFDM/CCK rate\n");
phycfg = 0;
}
@@ -6535,8 +6528,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
/* non-AP STA should never use BCMC queue */
if (queue == TX_BCMC_FIFO) {
- wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
- "TX_BCMC!\n", wlc->pub->unit, __func__);
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: ASSERT queue == TX_BCMC!\n",
+ wlc->pub->unit, __func__);
frameid = bcmc_fid_generate(wlc, NULL, txh);
} else {
/* Increment the counter for first fragment */
@@ -6706,7 +6700,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,

if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
&& (!is_mcs_rate(rspec[k]))) {
- wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: IEEE80211_TX_"
"RC_MCS != is_mcs_rate(rspec)\n",
wlc->pub->unit, __func__);
}
@@ -7100,14 +7095,16 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
wlc->fragthresh[queue] =
(u16) newfragthresh;
} else {
- wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s txop invalid "
"for rate %d\n",
wlc->pub->unit, fifo_names[queue],
rspec2rate(rspec[0]));
}

if (dur > wlc->edcf_txop[ac])
- wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: %s txop "
"exceeded phylen %d/%d dur %d/%d\n",
wlc->pub->unit, __func__,
fifo_names[queue],
@@ -7140,7 +7137,7 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
* in the tx ring and the tx queue isn't stopped then
* we've really got a bug; warn loudly if that happens.
*/
- wiphy_warn(wlc->wiphy,
+ brcms_warn(wlc->hw->d11core,
"Received frame for tx with no space in DMA ring\n");
WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw,
skb_get_queue_mapping(skb)));
@@ -7392,7 +7389,8 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
rx_status->rate_idx = 11;
break;
default:
- wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
+ brcms_err(wlc->hw->d11core,
+ "%s: Unknown rate\n", __func__);
}

/*
@@ -7411,7 +7409,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
} else if (is_ofdm_rate(rspec)) {
rx_status->flag |= RX_FLAG_SHORTPRE;
} else {
- wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
+ brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n",
__func__);
}
}
@@ -7421,12 +7419,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,

if (rxh->RxStatus1 & RXS_DECERR) {
rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
- wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n",
+ brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n",
__func__);
}
if (rxh->RxStatus1 & RXS_FCSERR) {
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
- wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n",
+ brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n",
__func__);
}
}
@@ -7837,8 +7835,9 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
if (rxh->RxStatus1 & RXS_PBPRES) {
if (p->len < 2) {
- wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
- "len %d\n", wlc->pub->unit, p->len);
+ brcms_err(wlc->hw->d11core,
+ "wl%d: recv: rcvd runt of len %d\n",
+ wlc->pub->unit, p->len);
goto toss;
}
skb_pull(p, 2);
@@ -7934,10 +7933,9 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
u32 macintstatus;
struct brcms_hardware *wlc_hw = wlc->hw;
struct bcma_device *core = wlc_hw->d11core;
- struct wiphy *wiphy = wlc->wiphy;

if (brcms_deviceremoved(wlc)) {
- wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__);
brcms_down(wlc->wl);
return false;
@@ -7958,7 +7956,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
wlc->macintstatus |= MI_TFS;
if (fatal) {
- wiphy_err(wiphy, "MI_TFS: fatal\n");
+ brcms_err(core, "MI_TFS: fatal\n");
goto fatal;
}
}
@@ -7968,7 +7966,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)

/* ATIM window end */
if (macintstatus & MI_ATIMWINEND) {
- BCMMSG(wlc->wiphy, "end of ATIM window\n");
+ brcms_dbg_info(core, "end of ATIM window\n");
bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid);
wlc->qvalid = 0;
}
@@ -7986,7 +7984,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
wlc_phy_noise_sample_intr(wlc_hw->band->pi);

if (macintstatus & MI_GP0) {
- wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
+ brcms_err(core, "wl%d: PSM microcode watchdog fired at %d "
"(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);

printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
@@ -8000,8 +7998,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
bcma_write32(core, D11REGOFFS(gptimer), 0);

if (macintstatus & MI_RFDISABLE) {
- BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
- " RF Disable Input\n", wlc_hw->unit);
+ brcms_dbg_info(core, "wl%d: BMAC Detected a change on the"
+ " RF Disable Input\n", wlc_hw->unit);
brcms_rfkill_set_hw_state(wlc->wl);
}

@@ -8019,7 +8017,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
u16 chanspec;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ brcms_dbg_info(core, "wl%d\n", wlc->pub->unit);

chanspec = ch20mhz_chspec(ch->hw_value);

--
1.7.9.5


2012-11-16 14:13:02

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 01/22] brcmsmac: Introduce AMPDU sessions for assembling AMPDUs

On Fri, Nov 16, 2012 at 09:36:21AM +0100, Arend van Spriel wrote:
> On 11/15/2012 03:07 PM, Seth Forshee wrote:
> >AMPDU session allows MPDUs to be temporarily queued until either a full
> >AMPDU has been collected or circumstances dictate that transmission
> >should start with a partial AMPDU. Packets are added to the session by
>
> I started reviewing this and reading this commit message got me
> wondering about the .flush() problems. I realized the flush would be
> a "circumstance" to start transmission of a partial AMPDU, but I am
> pretty sure it currently is not treated as such.

I hope my terminology here isn't confusing; I wasn't sure how else to
express this. By "full" I mean an AMPDU that is transmitted because it
can accommodate no more packets. A "partial" AMPDU is any that is
transmitted without being full.

One of the things I added when removing the tx queue was a DMA flush
operation to force any queued AMPDU packets into the DMA ring. But in
the current code brcms_c_sendampdu() will transmit the AMPDU with
whatever it's got when it runs out of packets in the pktq, so I don't
see a partial AMPDU problem.

What does strike me as problematic is the locking in brcms_ops_flush().
It holds wl->lock, and the interrupt handling tries to acquire the same
lock. Doesn't this prevent both the txpktpend counts from getting
updated and any more packets being transmitted from the packet queue?

Seth

2012-11-16 15:02:46

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 01/22] brcmsmac: Introduce AMPDU sessions for assembling AMPDUs

On 11/16/2012 03:12 PM, Seth Forshee wrote:
> What does strike me as problematic is the locking in brcms_ops_flush().
> It holds wl->lock, and the interrupt handling tries to acquire the same
> lock. Doesn't this prevent both the txpktpend counts from getting
> updated and any more packets being transmitted from the packet queue?
>
> Seth
>

Actually, in the brcms_c_wait_for_tx_completion() the while loop does a
brcms_msleep() which releases the wl->lock, does an msleep() and
acquires the lock. At least that is what is currently in
wireless-testing. I changed it internally to wait_for_event() mechanism,
but it was not accepted as people still were seeing issues.

Gr. AvS


2012-11-15 14:09:00

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 21/22] brcmsmac: Add tracepoint for AMPDU session information

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
.../brcm80211/brcmsmac/brcms_trace_events.h | 28 ++++++++++++++++++++
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 8 ++++++
2 files changed, 36 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index 2ef7580..871781e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -156,6 +156,34 @@ TRACE_EVENT(brcms_txstatus,
__entry->ackphyrxsh)
);

+TRACE_EVENT(brcms_ampdu_session,
+ TP_PROTO(const struct device *dev, unsigned max_ampdu_len,
+ u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames,
+ u16 dma_len),
+ TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames,
+ dma_len),
+ TP_STRUCT__entry(
+ __string(dev, dev_name(dev))
+ __field(unsigned, max_ampdu_len)
+ __field(u16, max_ampdu_frames)
+ __field(u16, ampdu_len)
+ __field(u16, ampdu_frames)
+ __field(u16, dma_len)
+ ),
+ TP_fast_assign(
+ __assign_str(dev, dev_name(dev));
+ __entry->max_ampdu_len = max_ampdu_len;
+ __entry->max_ampdu_frames = max_ampdu_frames;
+ __entry->ampdu_len = ampdu_len;
+ __entry->ampdu_frames = ampdu_frames;
+ __entry->dma_len = dma_len;
+ ),
+ TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u",
+ __get_str(dev), __entry->max_ampdu_len,
+ __entry->max_ampdu_frames, __entry->ampdu_len,
+ __entry->ampdu_frames, __entry->dma_len)
+);
+
#undef TRACE_SYSTEM
#define TRACE_SYSTEM brcmsmac_msg

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index ba33443..0f44bd9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -29,6 +29,7 @@
#include "scb.h"
#include "ampdu.h"
#include "debug.h"
+#include "brcms_trace_events.h"

/*
* dma register field offset calculation
@@ -1311,6 +1312,13 @@ static void ampdu_finalize(struct dma_info *di)
struct brcms_ampdu_session *session = &di->ampdu_session;
struct sk_buff *p;

+ trace_brcms_ampdu_session(&session->wlc->hw->d11core->dev,
+ session->max_ampdu_len,
+ session->max_ampdu_frames,
+ session->ampdu_len,
+ skb_queue_len(&session->skb_list),
+ session->dma_len);
+
if (WARN_ON(skb_queue_empty(&session->skb_list)))
return;

--
1.7.9.5


2012-11-26 19:37:03

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Wed, Nov 21, 2012 at 08:35:28AM -0600, Seth Forshee wrote:
> > My 'test' setup is following: I downloaded a larger file and let a youtube
> > video play. With tracing enabled the download and the playback did work nicely.
> >
> > Without tracing enabled playing back only a youtube video was 'triggering'
> > the problem. It downloads a few seconds of content in a burst and then the playback
> > starts. Under normal conditions, the app will continue downloading the video at a
> > lower rate. But this normally doesn't happen right now. Often it will just stop
> > working and often the connection is completely blocked, e.g. pinging a host
> > wont work.
>
> I'll see if I can reproduce, but if it's specific to the AP then I may
> not have any luck. Don't expect to hear much from me until next week
> though; I'm on holiday starting today and will be visiting family.

It seems I'm unable to reproduce the problem with any of the APs
available to me, unfortunately.

Seth


2012-11-19 18:47:29

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 06/22] brcmsmac: Remove internal tx queue

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> The brcmsmac internal tx buffering is problematic. The amount of
> buffering is excessive (228 packets in addition to the 256 slots in each
> DMA ring), and frames may be dropped due to a lack of flow control.
>
> This patch reworks the transmit code path to remove the internal
> buffering. Frames are immediately handed off to the DMA support rather
> than passing through an intermediate queue. Non-aggregate frames are
> queued immediately into the tx rings, and aggregate frames are queued
> temporarily in an AMPDU session until ready for transmit.
>
> Transmit flow control is also added to avoid dropping packets when the
> tx rings are full. Conceptually this is a separate change, but it's
> included in this commit because removing the tx queue without adding
> flow control could cause significant problems.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 167 +--------
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 3 -
> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 189 ++++++++--
> drivers/net/wireless/brcm80211/brcmsmac/dma.h | 9 +-
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 459 ++++++++---------------
> drivers/net/wireless/brcm80211/brcmsmac/main.h | 33 +-
> drivers/net/wireless/brcm80211/brcmsmac/pub.h | 13 -
> drivers/net/wireless/brcm80211/brcmsmac/types.h | 1 -
> 8 files changed, 316 insertions(+), 558 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> index 8abf39d..2b8987c 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> @@ -303,6 +304,18 @@ static const u8 wme_ac2fifo[] = {
> TX_AC_BK_FIFO
> };
>
> +/* 802.1D Priority to precedence queue mapping */
> +const u8 wlc_prio2prec_map[] = {
> + _BRCMS_PREC_BE, /* 0 BE - Best-effort */
> + _BRCMS_PREC_BK, /* 1 BK - Background */
> + _BRCMS_PREC_NONE, /* 2 None = - */
> + _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
> + _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
> + _BRCMS_PREC_VI, /* 5 Vi - Video */
> + _BRCMS_PREC_VO, /* 6 Vo - Voice */
> + _BRCMS_PREC_NC, /* 7 NC - Network Control */
> +};
> +

The wlc_prio2prec_map was removed in patch 06/22. Some reordering of
commits gone wrong here?

> static const u16 xmtfifo_sz[][NFIFO] = {
> /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
> {20, 192, 192, 21, 17, 5},



2012-11-15 14:08:45

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 14/22] brcmsmac: Add brcms_dbg_mac80211() debug macro

This macro is used for messages related to the 802.11 MAC layer.
Relevant messages are also converted to use this macro.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 3 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 59 +++++++++++++----------
drivers/net/wireless/brcm80211/include/defs.h | 1 +
3 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
index 6f2fe3b..f4f5090 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -35,6 +35,7 @@ static inline void __brcms_dbg(struct device *dev, u32 level,
#define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a)
#define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a)

-#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a)
+#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a)
+#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a)

#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 87db750..9c976b2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -646,8 +646,9 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
rate = BRCM_RATE_1M;
}

- BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
- wlc->pub->unit, ratespec, preamble_type, mac_len);
+ brcms_dbg_mac80211(wlc->hw->d11core,
+ "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
+ wlc->pub->unit, ratespec, preamble_type, mac_len);

if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
@@ -807,8 +808,8 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
/* low-level band switch utility routine */
static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
- bandunit);
+ brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit,
+ bandunit);

wlc_hw->band = wlc_hw->bandstate[bandunit];

@@ -836,7 +837,7 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
u32 macintmask;
u32 macctrl;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
macctrl = bcma_read32(wlc_hw->d11core,
D11REGOFFS(maccontrol));
WARN_ON((macctrl & MCTL_EN_MAC) != 0);
@@ -1724,8 +1725,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
{
struct brcms_hardware *wlc_hw = wlc->hw;

- BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
- wlc_hw->band->bandunit);
+ brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit,
+ wlc_hw->band->bandunit);

brcms_c_ucode_bsinit(wlc_hw);

@@ -2648,8 +2649,8 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
struct bcma_device *core = wlc_hw->d11core;
u32 mc, mi;

- BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
- wlc_hw->band->bandunit);
+ brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
+ wlc_hw->band->bandunit);

/*
* Track overlapping suspend requests
@@ -2716,8 +2717,8 @@ void brcms_c_enable_mac(struct brcms_c_info *wlc)
struct bcma_device *core = wlc_hw->d11core;
u32 mc, mi;

- BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
- wlc->band->bandunit);
+ brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
+ wlc->band->bandunit);

/*
* Track overlapping suspend requests
@@ -3777,7 +3778,8 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)

hps = brcms_c_ps_allowed(wlc);

- BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
+ brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit,
+ hps);

v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
v2 = MCTL_WAKE;
@@ -3863,7 +3865,8 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
{
uint bandunit;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
+ brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit,
+ chanspec);

wlc_hw->chanspec = chanspec;

@@ -5978,8 +5981,9 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
{
uint dur = 0;

- BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
- wlc->pub->unit, rspec, preamble_type);
+ brcms_dbg_mac80211(wlc->hw->d11core,
+ "wl%d: rspec 0x%x, preamble_type %d\n",
+ wlc->pub->unit, rspec, preamble_type);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -5997,8 +6001,9 @@ static uint
brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
u8 preamble_type)
{
- BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
- wlc->pub->unit, rspec, preamble_type);
+ brcms_dbg_mac80211(wlc->hw->d11core,
+ "wl%d: ratespec 0x%x, preamble_type %d\n",
+ wlc->pub->unit, rspec, preamble_type);
return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
}

@@ -6006,8 +6011,9 @@ static uint
brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
u8 preamble_type)
{
- BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
- "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
+ brcms_dbg_mac80211(wlc->hw->d11core,
+ "wl%d: rspec 0x%x, preamble_type %d\n",
+ wlc->pub->unit, rspec, preamble_type);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -6061,8 +6067,9 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
uint nsyms, mac_len, Ndps, kNdps;
uint rate = rspec2rate(ratespec);

- BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
- wlc->pub->unit, ratespec, preamble_type, dur);
+ brcms_dbg_mac80211(wlc->hw->d11core,
+ "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
+ wlc->pub->unit, ratespec, preamble_type, dur);

if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
@@ -6177,9 +6184,9 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
/* mcs > 7 must use stf SDM */
if (stf != PHY_TXC1_MODE_SDM) {
- BCMMSG(wlc->wiphy, "wl%d: enabling "
- "SDM mode for mcs %d\n",
- wlc->pub->unit, rate);
+ brcms_dbg_mac80211(core, "wl%d: enabling "
+ "SDM mode for mcs %d\n",
+ wlc->pub->unit, rate);
stf = PHY_TXC1_MODE_SDM;
}
} else {
@@ -7468,8 +7475,8 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
{
uint nsyms, len = 0, kNdps;

- BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
- wlc->pub->unit, rspec2rate(ratespec), mac_len);
+ brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: rate %d, len%d\n",
+ wlc->pub->unit, rspec2rate(ratespec), mac_len);

if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index 223eb2b..4d6906f 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -80,6 +80,7 @@

/* Debug levels */
#define BRCM_DL_INFO 0x00000001
+#define BRCM_DL_MAC80211 0x00000002

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-11-15 14:09:02

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 22/22] brcmsmac: Remove some noisy and uninformative debug messages

These messages clutter up the trace buffer without adding any useful
information.

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 2 --
drivers/net/wireless/brcm80211/brcmsmac/main.c | 25 ------------------------
2 files changed, 27 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 0f44bd9..511e457 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -1377,8 +1377,6 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
struct ieee80211_tx_info *tx_info;
bool is_ampdu;

- brcms_dbg_dma(di->core, "%s:\n", di->name);
-
/* no use to transmit a zero length packet */
if (p->len == 0)
return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index f7da9b3..f2c05d5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -647,10 +647,6 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
rate = BRCM_RATE_1M;
}

- brcms_dbg_mac80211(wlc->hw->d11core,
- "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
- wlc->pub->unit, ratespec, preamble_type, mac_len);
-
if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
@@ -4943,8 +4939,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc)
if (wlc == NULL)
return 0;

- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
-
callbacks += brcms_b_detach(wlc);

/* delete software timers */
@@ -5778,9 +5772,6 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
{
uint dur = 0;

- brcms_dbg_mac80211(wlc->hw->d11core,
- "wl%d: rspec 0x%x, preamble_type %d\n",
- wlc->pub->unit, rspec, preamble_type);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -5798,9 +5789,6 @@ static uint
brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
u8 preamble_type)
{
- brcms_dbg_mac80211(wlc->hw->d11core,
- "wl%d: ratespec 0x%x, preamble_type %d\n",
- wlc->pub->unit, rspec, preamble_type);
return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
}

@@ -5808,9 +5796,6 @@ static uint
brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
u8 preamble_type)
{
- brcms_dbg_mac80211(wlc->hw->d11core,
- "wl%d: rspec 0x%x, preamble_type %d\n",
- wlc->pub->unit, rspec, preamble_type);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -5864,10 +5849,6 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
uint nsyms, mac_len, Ndps, kNdps;
uint rate = rspec2rate(ratespec);

- brcms_dbg_mac80211(wlc->hw->d11core,
- "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
- wlc->pub->unit, ratespec, preamble_type, dur);
-
if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
@@ -7272,9 +7253,6 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
{
uint nsyms, len = 0, kNdps;

- brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: rate %d, len%d\n",
- wlc->pub->unit, rspec2rate(ratespec), mac_len);
-
if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
int tot_streams = (mcs_2_txstreams(mcs) + 1) +
@@ -7628,8 +7606,6 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
uint len;
bool is_amsdu;

- brcms_dbg_rx(wlc->hw->d11core, "wl%d\n", wlc->pub->unit);
-
/* frame starts with rxhdr */
rxh = (struct d11rxhdr *) (p->data);

@@ -7686,7 +7662,6 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
uint n = 0;
uint bound_limit = bound ? RXBND : -1;

- brcms_dbg_rx(wlc_hw->d11core, "wl%d\n", wlc_hw->unit);
skb_queue_head_init(&recv_frames);

/* gather received frames */
--
1.7.9.5


2012-11-20 21:09:25

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 11/20/2012 06:44 PM, Daniel Wagner wrote:
> Hi Seth,
>
> On 20.11.2012 15:28, Seth Forshee wrote:
>> On Tue, Nov 20, 2012 at 08:30:10AM +0100, Daniel Wagner wrote:
>>> Hi Seth,
>>>
>>> On 19.11.2012 20:11, Daniel Wagner wrote:
>>>> Works perfectly fine on my machine.
>>>
>>> Well, not really true. Though I am not sure if this what I am seeing
>>> related to your changes. I see following log only when I am using my
>>> home AP. The pattern is that when the connection stop working I see
>>> something like this in the log:
>>>
>>> [ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
>>> [ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
>>> [ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68
>>> tid 0
>>> [ 8735.573701] wlan0: activated addBA response timer on tid 0
>>> [ 8735.578826] wlan0: switched off addBA timer for tid 0
>>> [ 8735.578834] wlan0: Aggregation is on for tid 0
>>> [ 8749.687530] wlan0: tx session timer expired on tid 0
>>> [ 8749.687558] wlan0: Tx BA session stop requested for
>>> 1c:c6:3c:1f:50:68 tid 0
>>> [ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0
>>>
>>>
>>> This is what I do: First establishing a connection, then after a
>>> while any
>>> traffic seems stops for a period and sometimes it recovers from that
>>> point. If
>>> not a disconnect/connect (using ConnMan) dance fixes the problem.
>>
>> The tx session timer expiring is a result of not having any aggregate
>> transfers in a while. In my testing with iperf I see periods where the
>> transfer seems to stall, but it always recovers. These are less frequent
>> after my patches, but they still happen, and I haven't been able to work
>> out the cause yet. I'm not sure whether these are related to what you're
>> seeing or not.
>>
>> Luckily I've added a bunch of new debug code. Could you make sure you
>> have MAC80211_MESSAGE_TRACING and BRCM_TRACING enabled in your config
>> and collect a trace when this is happening by running:
>>
>> trace-cmd record -e mac80211 -e mac80211_msg -e brcmsmac \
>> -e brcmsmac_tx -e brcmsmac_msg
>>
>> This going to collect a lot of data, and you should bump up the trace
>> buffer size to avoid overruns. Once you've got a trace please compress
>> trace.dat and put it along with your dmesg somewhere where I can get at
>> them.
>
> I hope I got it right. Here are the requested logs:
>
> http://www.monom.org/misc/brcmsmac/traces/

What channel is you AP on?

Gr. AvS



2012-11-21 09:56:49

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 21.11.2012 10:44, Arend van Spriel wrote:
> On 11/20/2012 11:45 PM, Daniel Wagner wrote:
>>>
>>> I am currently not able to reproduce a complete loss of connectivity.
>>
>> I fear it is a heisenbug. After turning the tracing off I was able to
>> reproduce it very easily.
>
> That is too bad. I always wondered about the tracing overhead affecting
> reproducibility. So the trace that you uploaded was not showing the
> issue of connection loss you are having?

The trace does only show that the throughput goes considerable down and the
download might even stop shortly but overall the system recovers again.

Well, to add some random observation here, I think I see the same pattern
when using MacOS (yeah, sorry, dual boot). With MacOS the link is usable but
the throughput sometimes really goes down and recovers then. Obviously, this
could also be something else, I tried it with an pretty old AP which only
support 11g. Using the 11g AP didn't show this behavior.

My 'test' setup is following: I downloaded a larger file and let a youtube
video play. With tracing enabled the download and the playback did work nicely.

Without tracing enabled playing back only a youtube video was 'triggering'
the problem. It downloads a few seconds of content in a burst and then the playback
starts. Under normal conditions, the app will continue downloading the video at a
lower rate. But this normally doesn't happen right now. Often it will just stop
working and often the connection is completely blocked, e.g. pinging a host
wont work.



2012-11-15 14:08:38

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 11/22] brcmsmac: Add module parameter for setting the debug level

The debug level can be set by passing debug=... to brcmsmac whenever
CONFIG_BRCMDBG is enabled.

Signed-off-by: Seth Forshee <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 16 ++++++++--------
drivers/net/wireless/brcm80211/brcmsmac/main.c | 7 +------
2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index a744ea5..37b9966 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -98,10 +98,14 @@ static struct bcma_device_id brcms_coreid_table[] = {
};
MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);

-#ifdef DEBUG
-static int msglevel = 0xdeadbeef;
-module_param(msglevel, int, 0);
-#endif /* DEBUG */
+#if defined(CONFIG_BRCMDBG)
+/*
+ * Module parameter for setting the debug message level. Available
+ * flags are specified by the BRCM_DL_* macros in
+ * drivers/net/wireless/brcm80211/include/defs.h.
+ */
+module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR);
+#endif

static struct ieee80211_channel brcms_2ghz_chantable[] = {
CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
@@ -1184,10 +1188,6 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init);

static int __init brcms_module_init(void)
{
-#ifdef DEBUG
- if (msglevel != 0xdeadbeef)
- brcm_msg_level = msglevel;
-#endif
if (!schedule_work(&brcms_driver_work))
return -EBUSY;

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index a5bf3b6..bde36e5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -279,12 +279,7 @@ struct edcf_acparam {
} __packed;

/* debug/trace */
-uint brcm_msg_level =
-#if defined(DEBUG)
- BRCM_DL_INFO;
-#else
- 0;
-#endif /* DEBUG */
+uint brcm_msg_level;

/* TX FIFO number to WME/802.1E Access Category */
static const u8 wme_fifo2ac[] = {
--
1.7.9.5


2012-11-19 21:33:05

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 09/22] brcm80211: Allow trace support to be enabled separately from debug

On Mon, Nov 19, 2012 at 10:19:49PM +0100, Arend van Spriel wrote:
> On 11/19/2012 10:15 PM, Seth Forshee wrote:
> >On Mon, Nov 19, 2012 at 09:33:13PM +0100, Arend van Spriel wrote:
> >>On 11/15/2012 03:07 PM, Seth Forshee wrote:
> >>>Since the runtime overhead of trace support is small when tracing is
> >>>disabled, users may be interested in turning on trace support while
> >>>leaving other debug features off. Add a new config option named
> >>>CONFIG_BRCM_TRACING for this purpose.
> >>
> >>Reviewed-by: Pieter-Paul Giesberts <[email protected]>
> >>Reviewed-by: Arend van Spriel
> >>>Signed-off-by: Seth Forshee <[email protected]>
> >>>---
> >>> drivers/net/wireless/brcm80211/Kconfig | 11 +++++++++++
> >>> .../brcm80211/brcmsmac/brcms_trace_events.h | 6 +++---
> >>> 2 files changed, 14 insertions(+), 3 deletions(-)
> >>>
> >>>diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
> >>>index c9d811e..3735c27 100644
> >>>--- a/drivers/net/wireless/brcm80211/Kconfig
> >>>+++ b/drivers/net/wireless/brcm80211/Kconfig
> >>>@@ -63,6 +63,17 @@ config BRCMISCAN
> >>> new E-Scan method which uses less memory in firmware and gives no
> >>> limitation on the number of scan results.
> >>>
> >>>+config BRCM_TRACING
> >>>+ bool "Broadcom device tracing"
> >>>+ depends on BRCMSMAC || BRCMFMAC
> >>>+ ---help---
> >>>+ If you say Y here, the Broadcom wireless drivers will register
> >>>+ with ftrace to dump event information into the trace ringbuffer.
> >>>+ Tracing can be enabled at runtime to aid in debugging wireless
> >>>+ issues. This option adds a small amount of overhead when tracing
> >>>+ is disabled. If unsure, say Y to allow developers to better help
> >>>+ you when wireless problems occur.
> >>>+
> >>
> >>I regard this as a debugging feature. Did you consider making it
> >>depend on BRCMDBG instead? Or do you think that BRCMDBG code would
> >>affect run-time behavior during tracing.
> >
> >It is a debugging feature, but making it depend on BRCMDBG prevents my
> >intended use case. I'm planning to enable BRCM_TRACING in Ubuntu and to
> >leave BRCMDBG disabled. This will make it easy for us to ask users for
> >detailed debug information when needed with minimal overhead during
> >normal use.
>
> That seems reasonable. Have you any significant impact in throughput
> with tracing enabled?

I've really only tested with tracing enabled. Compared to before this
patch series the peak performance (as measured with iperf using a TCP
connection) is close enough that any differences would be lost in the
noise, and average performance is better due to the transfer rate being
more stable. I'll run some tests with and without tracing enabled to
compare the results. I may not get to it before next week though due to
the Thanksgiving holiday here in the US.

Seth


2012-11-20 22:36:16

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Tue, Nov 20, 2012 at 10:51:43PM +0100, Arend van Spriel wrote:
> On 11/20/2012 10:16 PM, Seth Forshee wrote:
> >On Tue, Nov 20, 2012 at 10:09:14PM +0100, Arend van Spriel wrote:
> >>>I hope I got it right. Here are the requested logs:
> >>>
> >>>http://www.monom.org/misc/brcmsmac/traces/
> >>
> >>What channel is you AP on?
> >
> >Based on the trace it looks like channel 13.
>
> Think so too.
>
> >If you want to take a look at the decoded trace data I've uploaded it to
> >http://people.canonical.com/~sforshee/brcms-trace/trace.log. I've got a
> >trace-cmd plugin for the tracepoints I added that makes it easier to
> >decipher.
> >
> >Seth
> >
>
> Nice :-D Are you sharing it?

Yes, I plan to submit it for trace-cmd after the tracepoints get to
Linus's tree. I just uploaded it to
http://people.canonical.com/~sforshee/brcms-trace/brcmsmac.py if you'd
like to use it now though.


2012-11-19 19:11:26

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Seth,

On 15.11.2012 15:07, Seth Forshee wrote:
> Hi Arend,
>
> As promised, here's the updated patch series for brcmsmac to remove the
> tx packet queue, add flow control, and add enhanced debug trace support.
> I've broken up the tx rework into multiple patches as you requested.
> Most notably I've split out the AMPDU session support into a separate
> patch, which should make it easier to review that change. I've done
> basic testing of each of the new commits to try and verify that no
> obvious regressions are introduced by any of them.
>
> Patch 6 contains the real meat of the tx changes and is still fairly
> large. It's going to be difficult to break up this patch any further
> though. The most obvious thing to break out at this point would be the
> flow control support. However, doing this before removing the tx queue
> basically results in throw-away code, and removing it after means that
> the commit that removes the tx queue may not work well, potentially
> making bisects more difficult. The flow control changes really aren't
> that big anyway.
>
> Otherwise the changes are pretty trivial, and functionally the end
> result should be identical to v1. I've found that I am still receiving
> frames occasionally after stopping a queue so I've kept the headroom in
> the tx fifos for now.
>
> Changes since v1:
>
> * Break up the tx path rework as much as possible
> * BRCMDBG no longer selects BRCMS_TRACING
> * Macro for checking for enabled debug levels has been removed in favor
> of open coding the checks
> * brcms_debug.[ch] renamed to debug.[ch]
> * Debug macros changed to lower-case
> * Removed some additional dead code
> * A few trivial clean-ups
>
> Thanks,
> Seth
>
>
> Seth Forshee (22):
> brcmsmac: Introduce AMPDU sessions for assembling AMPDUs
> brcmsmac: Don't weight AMPDU packets in txfifo
> brcmsmac: Add helper function for updating txavail count
> brcmsmac: Remove unimplemented flow control functions
> brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels
> brcmsmac: Remove internal tx queue
> brcmsmac: Use correct descriptor count when calculating next rx
> descriptor
> brcmsmac: Reduce number of entries in tx DMA rings
> brcm80211: Allow trace support to be enabled separately from debug
> brcm80211: Convert log message levels to debug levels
> brcmsmac: Add module parameter for setting the debug level
> brcmsmac: Add support for writing debug messages to the trace buffer
> brcmsmac: Use debug macros for general error and debug statements
> brcmsmac: Add brcms_dbg_mac80211() debug macro
> brcmsmac: Add rx and tx debug macros
> brcmsmac: Add brcms_dbg_int() debug macro
> brcmsmac: Add brcms_dbg_dma() debug macro
> brcmsmac: Add brcms_dbg_ht() debug macro
> brcmsmac: Improve tx trace and debug support
> brcmsmac: Add tracepoint for macintstatus
> brcmsmac: Add tracepoint for AMPDU session information
> brcmsmac: Remove some noisy and uninformative debug messages

Works perfectly fine on my machine.

02:00.0 Network controller: Broadcom Corporation BCM43224 802.11a/b/g/n
(rev 01)

Tested-by: Daniel Wagner <[email protected]>

thanks,
daniel

2012-11-15 14:08:18

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 01/22] brcmsmac: Introduce AMPDU sessions for assembling AMPDUs

AMPDU session allows MPDUs to be temporarily queued until either a full
AMPDU has been collected or circumstances dictate that transmission
should start with a partial AMPDU. Packets are added to the session by
calling brcms_c_ampdu_add_frame(). brcms_c_ampdu_finalize() should be
called to fix up the tx headers in the first and last packet before
adding the packets to the DMA ring. brmcs_c_sendampdu() is converted to
using AMPDU sessions.

This patch has no real value on it's own, but is needed in preparation
for elimination of the tx packet queue from brcmsmac.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 625 +++++++++++++----------
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 26 +
2 files changed, 377 insertions(+), 274 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index be5bcfb..5739534 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -498,38 +498,341 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
}

+void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
+ struct brcms_c_info *wlc)
+{
+ session->wlc = wlc;
+ skb_queue_head_init(&session->skb_list);
+ session->max_ampdu_len = 0; /* determined from first MPDU */
+ session->max_ampdu_frames = 0; /* determined from first MPDU */
+ session->ampdu_len = 0;
+ session->dma_len = 0;
+}
+
+/*
+ * Preps the given packet for AMPDU based on the session data. If the
+ * frame cannot be accomodated in the current session, -ENOSPC is
+ * returned.
+ */
+int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
+ struct sk_buff *p)
+{
+ struct brcms_c_info *wlc = session->wlc;
+ struct ampdu_info *ampdu = wlc->ampdu;
+ struct scb *scb = &wlc->pri_scb;
+ struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
+ struct ieee80211_tx_rate *txrate = tx_info->status.rates;
+ struct d11txh *txh = (struct d11txh *)p->data;
+ unsigned ampdu_frames;
+ u8 ndelim, tid;
+ u8 *plcp;
+ uint len;
+ u16 mcl;
+ bool fbr_iscck;
+ bool rr;
+
+ ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+ plcp = (u8 *)(txh + 1);
+ fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
+ len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
+ BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+ len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN;
+
+ ampdu_frames = skb_queue_len(&session->skb_list);
+ if (ampdu_frames != 0) {
+ struct sk_buff *first;
+
+ if (ampdu_frames + 1 > session->max_ampdu_frames ||
+ session->ampdu_len + len > session->max_ampdu_len)
+ return -ENOSPC;
+
+ /*
+ * We aren't really out of space if the new frame is of
+ * a different priority, but we want the same behaviour
+ * so return -ENOSPC anyway.
+ *
+ * XXX: The old AMPDU code did this, but is it really
+ * necessary?
+ */
+ first = skb_peek(&session->skb_list);
+ if (p->priority != first->priority)
+ return -ENOSPC;
+ }
+
+ /*
+ * Now that we're sure this frame can be accomodated, update the
+ * session information.
+ */
+ session->ampdu_len += len;
+ session->dma_len += p->len;
+
+ tid = (u8)p->priority;
+
+ /* Handle retry limits */
+ if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) {
+ txrate[0].count++;
+ rr = true;
+ } else {
+ txrate[1].count++;
+ rr = false;
+ }
+
+ if (ampdu_frames == 0) {
+ u8 plcp0, plcp3, is40, sgi, mcs;
+ uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
+ struct brcms_fifo_info *f = &ampdu->fifo_tb[fifo];
+
+ if (rr) {
+ plcp0 = plcp[0];
+ plcp3 = plcp[3];
+ } else {
+ plcp0 = txh->FragPLCPFallback[0];
+ plcp3 = txh->FragPLCPFallback[3];
+
+ }
+
+ /* Limit AMPDU size based on MCS */
+ is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
+ sgi = plcp3_issgi(plcp3) ? 1 : 0;
+ mcs = plcp0 & ~MIMO_PLCP_40MHZ;
+ session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes,
+ ampdu->max_txlen[mcs][is40][sgi]);
+
+ session->max_ampdu_frames = scb_ampdu->max_pdu;
+ if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
+ session->max_ampdu_frames =
+ min_t(u16, f->mcs2ampdu_table[mcs],
+ session->max_ampdu_frames);
+ }
+ }
+
+ /*
+ * Treat all frames as "middle" frames of AMPDU here. First and
+ * last frames must be fixed up after all MPDUs have been prepped.
+ */
+ mcl = le16_to_cpu(txh->MacTxControlLow);
+ mcl &= ~TXC_AMPDU_MASK;
+ mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
+ mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
+ txh->MacTxControlLow = cpu_to_le16(mcl);
+ txh->PreloadSize = 0; /* always default to 0 */
+
+ skb_queue_tail(&session->skb_list, p);
+
+ return 0;
+}
+
+void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session)
+{
+ struct brcms_c_info *wlc = session->wlc;
+ struct ampdu_info *ampdu = wlc->ampdu;
+ struct sk_buff *first, *last;
+ struct d11txh *txh;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_tx_rate *txrate;
+ u8 ndelim;
+ u8 *plcp;
+ uint len;
+ uint fifo;
+ struct brcms_fifo_info *f;
+ u16 mcl;
+ bool fbr;
+ bool fbr_iscck;
+ struct ieee80211_rts *rts;
+ bool use_rts = false, use_cts = false;
+ u16 dma_len = session->dma_len;
+ u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+ u32 rspec = 0, rspec_fallback = 0;
+ u32 rts_rspec = 0, rts_rspec_fallback = 0;
+ u8 plcp0, plcp3, is40, sgi, mcs;
+ u16 mch;
+ u8 preamble_type = BRCMS_GF_PREAMBLE;
+ u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
+ u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
+ u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
+
+ if (skb_queue_empty(&session->skb_list))
+ return;
+
+ first = skb_peek(&session->skb_list);
+ last = skb_peek_tail(&session->skb_list);
+
+ /* Need to fix up last MPDU first to adjust AMPDU length */
+ txh = (struct d11txh *)last->data;
+ fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
+ f = &ampdu->fifo_tb[fifo];
+
+ mcl = le16_to_cpu(txh->MacTxControlLow);
+ mcl &= ~TXC_AMPDU_MASK;
+ mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
+ txh->MacTxControlLow = cpu_to_le16(mcl);
+
+ /* remove the null delimiter after last mpdu */
+ ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+ txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
+ session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
+
+ /* remove the pad len from last mpdu */
+ fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
+ len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
+ BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+ session->ampdu_len -= roundup(len, 4) - len;
+
+ /* Now fix up the first MPDU */
+ tx_info = IEEE80211_SKB_CB(first);
+ txrate = tx_info->status.rates;
+ txh = (struct d11txh *)first->data;
+ plcp = (u8 *)(txh + 1);
+ rts = (struct ieee80211_rts *)&txh->rts_frame;
+
+ mcl = le16_to_cpu(txh->MacTxControlLow);
+ /* If only one MPDU leave it marked as last */
+ if (first != last) {
+ mcl &= ~TXC_AMPDU_MASK;
+ mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
+ }
+ mcl |= TXC_STARTMSDU;
+ if (ieee80211_is_rts(rts->frame_control)) {
+ mcl |= TXC_SENDRTS;
+ use_rts = true;
+ }
+ if (ieee80211_is_cts(rts->frame_control)) {
+ mcl |= TXC_SENDCTS;
+ use_cts = true;
+ }
+ txh->MacTxControlLow = cpu_to_le16(mcl);
+
+ fbr = txrate[1].count > 0;
+ if (!fbr) {
+ plcp0 = plcp[0];
+ plcp3 = plcp[3];
+ } else {
+ plcp0 = txh->FragPLCPFallback[0];
+ plcp3 = txh->FragPLCPFallback[3];
+ }
+ is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
+ sgi = plcp3_issgi(plcp3) ? 1 : 0;
+ mcs = plcp0 & ~MIMO_PLCP_40MHZ;
+
+ if (is40) {
+ if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi)))
+ mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP;
+ else
+ mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+ }
+
+ /* rebuild the rspec and rspec_fallback */
+ rspec = RSPEC_MIMORATE;
+ rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
+ if (plcp[0] & MIMO_PLCP_40MHZ)
+ rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+
+ fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
+ if (fbr_iscck) {
+ rspec_fallback =
+ cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0]));
+ } else {
+ rspec_fallback = RSPEC_MIMORATE;
+ rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
+ if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
+ rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT;
+ }
+
+ if (use_rts || use_cts) {
+ rts_rspec =
+ brcms_c_rspec_to_rts_rspec(wlc, rspec,
+ false, mimo_ctlchbw);
+ rts_rspec_fallback =
+ brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback,
+ false, mimo_ctlchbw);
+ }
+
+ BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len);
+ /* mark plcp to indicate ampdu */
+ BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
+
+ /* reset the mixed mode header durations */
+ if (txh->MModeLen) {
+ u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec,
+ session->ampdu_len);
+ txh->MModeLen = cpu_to_le16(mmodelen);
+ preamble_type = BRCMS_MM_PREAMBLE;
+ }
+ if (txh->MModeFbrLen) {
+ u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback,
+ session->ampdu_len);
+ txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
+ fbr_preamble_type = BRCMS_MM_PREAMBLE;
+ }
+
+ /* set the preload length */
+ if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
+ dma_len = min(dma_len, f->ampdu_pld_size);
+ txh->PreloadSize = cpu_to_le16(dma_len);
+ } else {
+ txh->PreloadSize = 0;
+ }
+
+ mch = le16_to_cpu(txh->MacTxControlHigh);
+
+ /* update RTS dur fields */
+ if (use_rts || use_cts) {
+ u16 durid;
+ if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
+ TXC_PREAMBLE_RTS_MAIN_SHORT)
+ rts_preamble_type = BRCMS_SHORT_PREAMBLE;
+
+ if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
+ TXC_PREAMBLE_RTS_FB_SHORT)
+ rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
+
+ durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
+ rspec, rts_preamble_type,
+ preamble_type,
+ session->ampdu_len, true);
+ rts->duration = cpu_to_le16(durid);
+ durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
+ rts_rspec_fallback,
+ rspec_fallback,
+ rts_fbr_preamble_type,
+ fbr_preamble_type,
+ session->ampdu_len, true);
+ txh->RTSDurFallback = cpu_to_le16(durid);
+ /* set TxFesTimeNormal */
+ txh->TxFesTimeNormal = rts->duration;
+ /* set fallback rate version of TxFesTimeNormal */
+ txh->TxFesTimeFallback = txh->RTSDurFallback;
+ }
+
+ /* set flag and plcp for fallback rate */
+ if (fbr) {
+ mch |= TXC_AMPDU_FBR;
+ txh->MacTxControlHigh = cpu_to_le16(mch);
+ BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
+ BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
+ }
+
+ BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
+ wlc->pub->unit, skb_queue_len(&session->skb_list),
+ session->ampdu_len);
+}
+
int
brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
struct sk_buff **pdu, int prec)
{
struct brcms_c_info *wlc;
- struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
- u8 tid, ndelim;
+ struct sk_buff *p;
+ struct brcms_ampdu_session session;
int err = 0;
- u8 preamble_type = BRCMS_GF_PREAMBLE;
- u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
- u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
- u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
+ u8 tid;

- bool rr = true, fbr = false;
- uint i, count = 0, fifo, seg_cnt = 0;
- u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
- u32 ampdu_len, max_ampdu_bytes = 0;
- struct d11txh *txh = NULL;
- u8 *plcp;
- struct ieee80211_hdr *h;
+ uint count, fifo, seg_cnt = 0;
struct scb *scb;
struct scb_ampdu *scb_ampdu;
struct scb_ampdu_tid_ini *ini;
- u8 mcs = 0;
- bool use_rts = false, use_cts = false;
- u32 rspec = 0, rspec_fallback = 0;
- u32 rts_rspec = 0, rts_rspec_fallback = 0;
- u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
- struct ieee80211_rts *rts;
- u8 rr_retry_limit;
struct brcms_fifo_info *f;
- bool fbr_iscck;
struct ieee80211_tx_info *tx_info;
u16 qlen;
struct wiphy *wiphy;
@@ -554,9 +857,8 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
return -EBUSY;

/* at this point we intend to transmit an AMPDU */
- rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
- ampdu_len = 0;
- dma_len = 0;
+ brcms_c_ampdu_reset_session(&session, wlc);
+
while (p) {
struct ieee80211_tx_rate *txrate;

@@ -575,157 +877,35 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
if (err) {
if (err == -EBUSY) {
wiphy_err(wiphy, "wl%d: sendampdu: "
- "prep_xdu retry; seq 0x%x\n",
- wlc->pub->unit, seq);
+ "prep_xdu retry\n", wlc->pub->unit);
*pdu = p;
break;
}

/* error in the packet; reject it */
wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
- "rejected; seq 0x%x\n", wlc->pub->unit, seq);
+ "rejected\n", wlc->pub->unit);
*pdu = NULL;
break;
}

- /* pkt is good to be aggregated */
- txh = (struct d11txh *) p->data;
- plcp = (u8 *) (txh + 1);
- h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
- seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
- index = TX_SEQ_TO_INDEX(seq);
-
- /* check mcl fields and test whether it can be agg'd */
- mcl = le16_to_cpu(txh->MacTxControlLow);
- mcl &= ~TXC_AMPDU_MASK;
- fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
- txh->PreloadSize = 0; /* always default to 0 */
-
- /* Handle retry limits */
- if (txrate[0].count <= rr_retry_limit) {
- txrate[0].count++;
- rr = true;
- fbr = false;
- } else {
- fbr = true;
- rr = false;
- txrate[1].count++;
- }
-
- /* extract the length info */
- len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
- : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
-
- /* retrieve null delimiter count */
- ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
- seg_cnt += 1;
-
- BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
- wlc->pub->unit, count, len);
-
- /*
- * aggregateable mpdu. For ucode/hw agg,
- * test whether need to break or change the epoch
- */
- if (count == 0) {
- mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
- /* refill the bits since might be a retx mpdu */
- mcl |= TXC_STARTMSDU;
- rts = (struct ieee80211_rts *)&txh->rts_frame;
-
- if (ieee80211_is_rts(rts->frame_control)) {
- mcl |= TXC_SENDRTS;
- use_rts = true;
- }
- if (ieee80211_is_cts(rts->frame_control)) {
- mcl |= TXC_SENDCTS;
- use_cts = true;
- }
- } else {
- mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
- mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
- }
-
- len = roundup(len, 4);
- ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
-
- dma_len += (u16) p->len;
-
- BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
- " seg_cnt %d null delim %d\n",
- wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
-
- txh->MacTxControlLow = cpu_to_le16(mcl);
-
- /* this packet is added */
- pkt[count++] = p;
-
- /* patch the first MPDU */
- if (count == 1) {
- u8 plcp0, plcp3, is40, sgi;
-
- if (rr) {
- plcp0 = plcp[0];
- plcp3 = plcp[3];
- } else {
- plcp0 = txh->FragPLCPFallback[0];
- plcp3 = txh->FragPLCPFallback[3];
-
- }
- is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
- sgi = plcp3_issgi(plcp3) ? 1 : 0;
- mcs = plcp0 & ~MIMO_PLCP_40MHZ;
- max_ampdu_bytes =
- min(scb_ampdu->max_rx_ampdu_bytes,
- ampdu->max_txlen[mcs][is40][sgi]);
-
- if (is40)
- mimo_ctlchbw =
- CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
- wlc->band->pi))
- ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
-
- /* rebuild the rspec and rspec_fallback */
- rspec = RSPEC_MIMORATE;
- rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
- if (plcp[0] & MIMO_PLCP_40MHZ)
- rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
-
- if (fbr_iscck) /* CCK */
- rspec_fallback = cck_rspec(cck_phy2mac_rate
- (txh->FragPLCPFallback[0]));
- else { /* MIMO */
- rspec_fallback = RSPEC_MIMORATE;
- rspec_fallback |=
- txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
- if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
- rspec_fallback |=
- (PHY_TXC1_BW_40MHZ <<
- RSPEC_BW_SHIFT);
- }
-
- if (use_rts || use_cts) {
- rts_rspec =
- brcms_c_rspec_to_rts_rspec(wlc,
- rspec, false, mimo_ctlchbw);
- rts_rspec_fallback =
- brcms_c_rspec_to_rts_rspec(wlc,
- rspec_fallback, false, mimo_ctlchbw);
- }
- }
-
- /* if (first mpdu for host agg) */
- /* test whether to add more */
- if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) &&
- (count == f->mcs2ampdu_table[mcs])) {
- BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
- " ampdu at %d for mcs %d\n",
- wlc->pub->unit, count, mcs);
+ err = brcms_c_ampdu_add_frame(&session, p);
+ if (err == -ENOSPC) {
+ /*
+ * No space for this packet in the AMPDU.
+ * Requeue packet and proceed;
+ */
+ *pdu = p;
+ break;
+ } else if (err) {
+ /* Unexpected error; reject packet */
+ wiphy_err(wiphy, "wl%d: sendampdu: add_frame rejected",
+ wlc->pub->unit);
+ *pdu = NULL;
break;
}

- if (count == scb_ampdu->max_pdu)
- break;
+ seg_cnt += 1;

/*
* check to see if the next pkt is
@@ -734,22 +914,13 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
p = pktq_ppeek(&qi->q, prec);
if (p) {
tx_info = IEEE80211_SKB_CB(p);
- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
- ((u8) (p->priority) == tid)) {
- plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
- plen = max(scb_ampdu->min_len, plen);
-
- if ((plen + ampdu_len) > max_ampdu_bytes) {
- p = NULL;
- continue;
- }
-
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
/*
* check if there are enough
* descriptors available
*/
if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
- wiphy_err(wiphy, "%s: No fifo space "
+ wiphy_err(wiphy, "%s: No fifo space "
"!!\n", __func__);
p = NULL;
continue;
@@ -762,111 +933,17 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
}
} /* end while(p) */

+ count = skb_queue_len(&session.skb_list);
ini->tx_in_transit += count;

if (count) {
- /* patch up the last txh */
- txh = (struct d11txh *) pkt[count - 1]->data;
- mcl = le16_to_cpu(txh->MacTxControlLow);
- mcl &= ~TXC_AMPDU_MASK;
- mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
- txh->MacTxControlLow = cpu_to_le16(mcl);
-
- /* remove the null delimiter after last mpdu */
- ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
- txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
- ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
-
- /* remove the pad len from last mpdu */
- fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
- len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
- : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
- ampdu_len -= roundup(len, 4) - len;
-
- /* patch up the first txh & plcp */
- txh = (struct d11txh *) pkt[0]->data;
- plcp = (u8 *) (txh + 1);
-
- BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
- /* mark plcp to indicate ampdu */
- BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
-
- /* reset the mixed mode header durations */
- if (txh->MModeLen) {
- u16 mmodelen =
- brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
- txh->MModeLen = cpu_to_le16(mmodelen);
- preamble_type = BRCMS_MM_PREAMBLE;
- }
- if (txh->MModeFbrLen) {
- u16 mmfbrlen =
- brcms_c_calc_lsig_len(wlc, rspec_fallback,
- ampdu_len);
- txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
- fbr_preamble_type = BRCMS_MM_PREAMBLE;
- }
-
- /* set the preload length */
- if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
- dma_len = min(dma_len, f->ampdu_pld_size);
- txh->PreloadSize = cpu_to_le16(dma_len);
- } else
- txh->PreloadSize = 0;
-
- mch = le16_to_cpu(txh->MacTxControlHigh);
-
- /* update RTS dur fields */
- if (use_rts || use_cts) {
- u16 durid;
- rts = (struct ieee80211_rts *)&txh->rts_frame;
- if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
- TXC_PREAMBLE_RTS_MAIN_SHORT)
- rts_preamble_type = BRCMS_SHORT_PREAMBLE;
-
- if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
- TXC_PREAMBLE_RTS_FB_SHORT)
- rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
-
- durid =
- brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
- rspec, rts_preamble_type,
- preamble_type, ampdu_len,
- true);
- rts->duration = cpu_to_le16(durid);
- durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
- rts_rspec_fallback,
- rspec_fallback,
- rts_fbr_preamble_type,
- fbr_preamble_type,
- ampdu_len, true);
- txh->RTSDurFallback = cpu_to_le16(durid);
- /* set TxFesTimeNormal */
- txh->TxFesTimeNormal = rts->duration;
- /* set fallback rate version of TxFesTimeNormal */
- txh->TxFesTimeFallback = txh->RTSDurFallback;
- }
-
- /* set flag and plcp for fallback rate */
- if (fbr) {
- mch |= TXC_AMPDU_FBR;
- txh->MacTxControlHigh = cpu_to_le16(mch);
- BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
- BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
- }
-
- BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
- wlc->pub->unit, count, ampdu_len);
-
- /* inform rate_sel if it this is a rate probe pkt */
- frameid = le16_to_cpu(txh->TxFrameID);
- if (frameid & TXFID_RATE_PROBE_MASK)
- wiphy_err(wiphy, "%s: XXX what to do with "
- "TXFID_RATE_PROBE_MASK!?\n", __func__);
-
- for (i = 0; i < count; i++)
- brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
- ampdu->txpkt_weight);
+ /* patch up first and last txh's */
+ brcms_c_ampdu_finalize(&session);

+ while ((p = skb_dequeue(&session.skb_list)) != NULL)
+ brcms_c_txfifo(wlc, fifo, p,
+ skb_queue_empty(&session.skb_list),
+ ampdu->txpkt_weight);
}
/* endif (count) */
return err;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
index 421f4ba..9a94923 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
@@ -17,6 +17,32 @@
#ifndef _BRCM_AMPDU_H_
#define _BRCM_AMPDU_H_

+/*
+ * Data structure representing an in-progress session for accumulating
+ * frames for AMPDU.
+ *
+ * wlc: pointer to common driver data
+ * skb_list: queue of skb's for AMPDU
+ * max_ampdu_len: maximum length for this AMPDU
+ * max_ampdu_frames: maximum number of frames for this AMPDU
+ * ampdu_len: total number of bytes accumulated for this AMPDU
+ * dma_len: DMA length of this AMPDU
+ */
+struct brcms_ampdu_session {
+ struct brcms_c_info *wlc;
+ struct sk_buff_head skb_list;
+ unsigned max_ampdu_len;
+ u16 max_ampdu_frames;
+ u16 ampdu_len;
+ u16 dma_len;
+};
+
+extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
+ struct brcms_c_info *wlc);
+extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
+ struct sk_buff *p);
+extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session);
+
extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
--
1.7.9.5


2012-11-19 19:16:31

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 05/22] brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels

On Mon, Nov 19, 2012 at 07:42:04PM +0100, Arend van Spriel wrote:
> On 11/15/2012 03:07 PM, Seth Forshee wrote:
> >The mac80211 tx queues and brcmsmac DMA fifos both map directly to AC
> >levels. Therefore it's much more straightforward to queue tx frames and
> >choose the tx fifo based on the mac80211 queue instead of mapping 802.1D
> >priority tags to precedence levels then back to AC levels. mac80211
> >already maps the 802.1D levels to the appropriate AC levels and queues
> >management frames at the maximum priority, so the results should be
> >identical.
> >
> >One functional change resulting from this patch is that AMPDU retries no
> >longer get a priority boost to queue them ahead of packets with the same
>
> True. I believe the statement actually applies to any retry include
> non-AMPDU.

I don't see that non-AMPDU frames are ever requeued after failed tx. Am
I overlooking soemthing?

Seth


2012-11-23 07:32:05

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Seth,

On 21.11.2012 15:35, Seth Forshee wrote:
> On Wed, Nov 21, 2012 at 10:56:47AM +0100, Daniel Wagner wrote:
>> On 21.11.2012 10:44, Arend van Spriel wrote:
>>> On 11/20/2012 11:45 PM, Daniel Wagner wrote:
>>>>>
>>>>> I am currently not able to reproduce a complete loss of connectivity.
>>>>
>>>> I fear it is a heisenbug. After turning the tracing off I was able to
>>>> reproduce it very easily.
>
> Just to clarify, you see the issue using the same kernel but without
> trace-cmd running?

Yes, exactly.

> If so you might try disabling the brcmsmac_tx
> tracepoing, which probably adds the most overhead, and see if you can
> reproduce the problem. It obviously won't give as much information but
> maybe it will still provide some clues.

Will do. To clarify what I mean with 'connectivity' loss, is that
ConnMan/wpa_s still think everything is fine but nothing works anymore.
So it could be a combination of issues which sums up to this behavior.
I'll spend some more time to gather better information.

>>> That is too bad. I always wondered about the tracing overhead affecting
>>> reproducibility. So the trace that you uploaded was not showing the
>>> issue of connection loss you are having?
>>
>> The trace does only show that the throughput goes considerable down and the
>> download might even stop shortly but overall the system recovers again.
>>
>> Well, to add some random observation here, I think I see the same pattern
>> when using MacOS (yeah, sorry, dual boot). With MacOS the link is usable but
>> the throughput sometimes really goes down and recovers then. Obviously, this
>> could also be something else, I tried it with an pretty old AP which only
>> support 11g. Using the 11g AP didn't show this behavior.
>>
>> My 'test' setup is following: I downloaded a larger file and let a youtube
>> video play. With tracing enabled the download and the playback did work nicely.
>>
>> Without tracing enabled playing back only a youtube video was 'triggering'
>> the problem. It downloads a few seconds of content in a burst and then the playback
>> starts. Under normal conditions, the app will continue downloading the video at a
>> lower rate. But this normally doesn't happen right now. Often it will just stop
>> working and often the connection is completely blocked, e.g. pinging a host
>> wont work.
>
> I'll see if I can reproduce, but if it's specific to the AP then I may
> not have any luck. Don't expect to hear much from me until next week
> though; I'm on holiday starting today and will be visiting family.

Enjoy!

cheers,
daniel


2012-11-19 20:33:30

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 09/22] brcm80211: Allow trace support to be enabled separately from debug

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> Since the runtime overhead of trace support is small when tracing is
> disabled, users may be interested in turning on trace support while
> leaving other debug features off. Add a new config option named
> CONFIG_BRCM_TRACING for this purpose.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/Kconfig | 11 +++++++++++
> .../brcm80211/brcmsmac/brcms_trace_events.h | 6 +++---
> 2 files changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
> index c9d811e..3735c27 100644
> --- a/drivers/net/wireless/brcm80211/Kconfig
> +++ b/drivers/net/wireless/brcm80211/Kconfig
> @@ -63,6 +63,17 @@ config BRCMISCAN
> new E-Scan method which uses less memory in firmware and gives no
> limitation on the number of scan results.
>
> +config BRCM_TRACING
> + bool "Broadcom device tracing"
> + depends on BRCMSMAC || BRCMFMAC
> + ---help---
> + If you say Y here, the Broadcom wireless drivers will register
> + with ftrace to dump event information into the trace ringbuffer.
> + Tracing can be enabled at runtime to aid in debugging wireless
> + issues. This option adds a small amount of overhead when tracing
> + is disabled. If unsure, say Y to allow developers to better help
> + you when wireless problems occur.
> +

I regard this as a debugging feature. Did you consider making it depend
on BRCMDBG instead? Or do you think that BRCMDBG code would affect
run-time behavior during tracing.

> config BRCMDBG
> bool "Broadcom driver debug functions"
> depends on BRCMSMAC || BRCMFMAC



2012-11-19 18:33:59

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 01/22] brcmsmac: Introduce AMPDU sessions for assembling AMPDUs

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> AMPDU session allows MPDUs to be temporarily queued until either a full
> AMPDU has been collected or circumstances dictate that transmission
> should start with a partial AMPDU. Packets are added to the session by
> calling brcms_c_ampdu_add_frame(). brcms_c_ampdu_finalize() should be
> called to fix up the tx headers in the first and last packet before
> adding the packets to the DMA ring. brmcs_c_sendampdu() is converted to
> using AMPDU sessions.
>
> This patch has no real value on it's own, but is needed in preparation
> for elimination of the tx packet queue from brcmsmac.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 625 +++++++++++++----------
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 26 +
> 2 files changed, 377 insertions(+), 274 deletions(-)




2012-11-15 14:08:32

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 08/22] brcmsmac: Reduce number of entries in tx DMA rings

Currently up to 256 frames can be queued for each DMA ring. This is
excessive, and now that we have better flow control we can get by with
less. Experimentation has shown 64 to work well.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 2b8987c..ca93214 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -232,8 +232,8 @@

#define MAX_DMA_SEGS 4

-/* Max # of entries in Tx FIFO based on 4kb page size */
-#define NTXD 256
+/* # of entries in Tx FIFO */
+#define NTXD 64
/* Max # of entries in Rx FIFO based on 4kb page size */
#define NRXD 256

--
1.7.9.5


2012-11-19 18:48:38

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 08/22] brcmsmac: Reduce number of entries in tx DMA rings

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> Currently up to 256 frames can be queued for each DMA ring. This is
> excessive, and now that we have better flow control we can get by with
> less. Experimentation has shown 64 to work well.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)



2012-11-19 20:39:26

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 18/22] brcmsmac: Add brcms_dbg_ht() debug macro

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> Also convert relevant messages to use this macro.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 35 ++++++++++++-----------
> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 1 +
> drivers/net/wireless/brcm80211/brcmsmac/stf.c | 8 ++++--
> drivers/net/wireless/brcm80211/include/defs.h | 1 +
> 4 files changed, 25 insertions(+), 20 deletions(-)




2012-11-19 18:42:21

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 05/22] brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> The mac80211 tx queues and brcmsmac DMA fifos both map directly to AC
> levels. Therefore it's much more straightforward to queue tx frames and
> choose the tx fifo based on the mac80211 queue instead of mapping 802.1D
> priority tags to precedence levels then back to AC levels. mac80211
> already maps the 802.1D levels to the appropriate AC levels and queues
> management frames at the maximum priority, so the results should be
> identical.
>
> One functional change resulting from this patch is that AMPDU retries no
> longer get a priority boost to queue them ahead of packets with the same

True. I believe the statement actually applies to any retry include
non-AMPDU.

> priority already in the tx queue. This behavior will be restored (in
> effect at least) in a later patch when the tx queue is removed.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 13 +----
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 67 ++++++++---------------
> drivers/net/wireless/brcm80211/brcmsmac/main.h | 6 +-
> drivers/net/wireless/brcm80211/brcmsmac/pub.h | 26 +--------
> 4 files changed, 26 insertions(+), 86 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> index 135af9a..8abf39d 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> @@ -365,6 +342,21 @@ static const char fifo_names[6][0];
> static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
> #endif
>
> +/* Mapping of ieee80211 AC numbers to tx fifos */
> +static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
> + [IEEE80211_AC_VO] = TX_AC_VO_FIFO,
> + [IEEE80211_AC_VI] = TX_AC_VI_FIFO,
> + [IEEE80211_AC_BE] = TX_AC_BE_FIFO,
> + [IEEE80211_AC_BK] = TX_AC_BK_FIFO,

Minor comment: Can you get rid of the tab before the equal sign and use
space instead?

> @@ -6068,14 +6054,13 @@ static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
> }
>
> void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
> - struct sk_buff *sdu, uint prec)
> + struct sk_buff *sdu)
> {
> struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
> struct pktq *q = &qi->q;
> - int prio;
> -
> - prio = sdu->priority;
> + uint prec;

the term prec, short for precedence, may be confusing as the concept is
removed.

> + prec = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
> if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
> /*
> * we might hit this condtion in case



2012-11-19 20:36:56

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 14/22] brcmsmac: Add brcms_dbg_mac80211() debug macro

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> This macro is used for messages related to the 802.11 MAC layer.
> Relevant messages are also converted to use this macro.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 3 +-
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 59 +++++++++++++----------
> drivers/net/wireless/brcm80211/include/defs.h | 1 +
> 3 files changed, 36 insertions(+), 27 deletions(-)




2012-11-15 19:47:45

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> Hi Arend,
>
> As promised, here's the updated patch series for brcmsmac to remove the
> tx packet queue, add flow control, and add enhanced debug trace support.
> I've broken up the tx rework into multiple patches as you requested.
> Most notably I've split out the AMPDU session support into a separate
> patch, which should make it easier to review that change. I've done
> basic testing of each of the new commits to try and verify that no
> obvious regressions are introduced by any of them.

Great. I already noticed the increase in the number of patches. Thanks
for breaking up the tx path patch. We will review the changes and put it
in nightly regression test rig.

Regards,
Arend


2012-11-19 20:37:20

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 15/22] brcmsmac: Add rx and tx debug macros

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> Also convert relevant messages over to use thses macros.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 2 ++
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 18 ++++++++----------
> drivers/net/wireless/brcm80211/include/defs.h | 2 ++
> 3 files changed, 12 insertions(+), 10 deletions(-)




2012-11-26 21:20:58

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 26.11.2012 20:36, Seth Forshee wrote:
> On Wed, Nov 21, 2012 at 08:35:28AM -0600, Seth Forshee wrote:
>>> My 'test' setup is following: I downloaded a larger file and let a youtube
>>> video play. With tracing enabled the download and the playback did work nicely.
>>>
>>> Without tracing enabled playing back only a youtube video was 'triggering'
>>> the problem. It downloads a few seconds of content in a burst and then the playback
>>> starts. Under normal conditions, the app will continue downloading the video at a
>>> lower rate. But this normally doesn't happen right now. Often it will just stop
>>> working and often the connection is completely blocked, e.g. pinging a host
>>> wont work.
>>
>> I'll see if I can reproduce, but if it's specific to the AP then I may
>> not have any luck. Don't expect to hear much from me until next week
>> though; I'm on holiday starting today and will be visiting family.
>
> It seems I'm unable to reproduce the problem with any of the APs
> available to me, unfortunately.

I tried it again with disabled the TX trace but I can't reproduce it
either. Well, I am sick of this AP and I might just get a better one
(which should be fairly simple).

Thanks for looking into this.

cheers,
daniel


2012-11-15 14:08:52

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 17/22] brcmsmac: Add brcms_dbg_dma() debug macro

Also convert relevant messages to use this macro.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 1 +
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 155 ++++++++++-------------
drivers/net/wireless/brcm80211/brcmsmac/dma.h | 2 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 10 +-
drivers/net/wireless/brcm80211/include/defs.h | 1 +
5 files changed, 73 insertions(+), 96 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
index 1114833..2e7e077 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -40,5 +40,6 @@ static inline void __brcms_dbg(struct device *dev, u32 level,
#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a)
#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a)
#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a)
+#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a)

#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index d7ce1ac..ba33443 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -14,8 +14,6 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/pci.h>
@@ -30,6 +28,7 @@
#include "soc.h"
#include "scb.h"
#include "ampdu.h"
+#include "debug.h"

/*
* dma register field offset calculation
@@ -181,28 +180,6 @@

#define BCMEXTRAHDROOM 172

-/* debug/trace */
-#ifdef DEBUG
-#define DMA_ERROR(fmt, ...) \
-do { \
- if (*di->msg_level & 1) \
- pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
-} while (0)
-#define DMA_TRACE(fmt, ...) \
-do { \
- if (*di->msg_level & 2) \
- pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
-} while (0)
-#else
-#define DMA_ERROR(fmt, ...) \
- no_printk(fmt, ##__VA_ARGS__)
-#define DMA_TRACE(fmt, ...) \
- no_printk(fmt, ##__VA_ARGS__)
-#endif /* DEBUG */
-
-#define DMA_NONE(fmt, ...) \
- no_printk(fmt, ##__VA_ARGS__)
-
#define MAXNAMEL 8 /* 8 char names */

/* macros to convert between byte offsets and indexes */
@@ -229,7 +206,6 @@ struct dma64desc {
/* dma engine software state */
struct dma_info {
struct dma_pub dma; /* exported structure */
- uint *msg_level; /* message level pointer */
char name[MAXNAMEL]; /* callers name for diag msgs */

struct bcma_device *core;
@@ -306,12 +282,6 @@ struct dma_info {
bool aligndesc_4k;
};

-/*
- * default dma message level (if input msg_level
- * pointer is null in dma_attach())
- */
-static uint dma_msg_level;
-
/* Check for odd number of 1's */
static u32 parity32(__le32 data)
{
@@ -379,7 +349,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
uint dmactrlflags;

if (di == NULL) {
- DMA_ERROR("NULL dma handle\n");
+ brcms_dbg_dma(di->core, "NULL dma handle\n");
return 0;
}

@@ -431,13 +401,15 @@ static bool _dma_isaddrext(struct dma_info *di)
/* not all tx or rx channel are available */
if (di->d64txregbase != 0) {
if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
- DMA_ERROR("%s: DMA64 tx doesn't have AE set\n",
- di->name);
+ brcms_dbg_dma(di->core,
+ "%s: DMA64 tx doesn't have AE set\n",
+ di->name);
return true;
} else if (di->d64rxregbase != 0) {
if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
- DMA_ERROR("%s: DMA64 rx doesn't have AE set\n",
- di->name);
+ brcms_dbg_dma(di->core,
+ "%s: DMA64 rx doesn't have AE set\n",
+ di->name);
return true;
}

@@ -538,8 +510,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction)
va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
&alloced, &di->txdpaorig);
if (va == NULL) {
- DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
- di->name);
+ brcms_dbg_dma(di->core,
+ "%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
+ di->name);
return false;
}
align = (1 << align_bits);
@@ -552,8 +525,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction)
va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
&alloced, &di->rxdpaorig);
if (va == NULL) {
- DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
- di->name);
+ brcms_dbg_dma(di->core,
+ "%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
+ di->name);
return false;
}
align = (1 << align_bits);
@@ -575,7 +549,7 @@ static bool _dma_alloc(struct dma_info *di, uint direction)
struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
uint rxbufsize, int rxextheadroom,
- uint nrxpost, uint rxoffset, uint *msg_level)
+ uint nrxpost, uint rxoffset)
{
struct si_pub *sih = wlc->hw->sih;
struct bcma_device *core = wlc->hw->d11core;
@@ -589,9 +563,6 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
if (di == NULL)
return NULL;

- di->msg_level = msg_level ? msg_level : &dma_msg_level;
-
-
di->dma64 =
((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64);

@@ -607,11 +578,11 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
*/
_dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);

- DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d "
- "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
- "txregbase %u rxregbase %u\n", name, "DMA64",
- di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
- rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);
+ brcms_dbg_dma(di->core, "%s: %s flags 0x%x ntxd %d nrxd %d "
+ "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
+ "txregbase %u rxregbase %u\n", name, "DMA64",
+ di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
+ rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);

/* make a private copy of our callers name */
strncpy(di->name, name, MAXNAMEL);
@@ -673,8 +644,8 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
di->dmadesc_align = 4; /* 16 byte alignment */
}

- DMA_NONE("DMA descriptor align_needed %d, align %d\n",
- di->aligndesc_4k, di->dmadesc_align);
+ brcms_dbg_dma(di->core, "DMA descriptor align_needed %d, align %d\n",
+ di->aligndesc_4k, di->dmadesc_align);

/* allocate tx packet pointer vector */
if (ntxd) {
@@ -712,13 +683,15 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,

if ((di->ddoffsetlow != 0) && !di->addrext) {
if (di->txdpa > SI_PCI_DMA_SZ) {
- DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n",
- di->name, (u32)di->txdpa);
+ brcms_dbg_dma(di->core,
+ "%s: txdpa 0x%x: addrext not supported\n",
+ di->name, (u32)di->txdpa);
goto fail;
}
if (di->rxdpa > SI_PCI_DMA_SZ) {
- DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n",
- di->name, (u32)di->rxdpa);
+ brcms_dbg_dma(di->core,
+ "%s: rxdpa 0x%x: addrext not supported\n",
+ di->name, (u32)di->rxdpa);
goto fail;
}
}
@@ -726,10 +699,11 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
/* Initialize AMPDU session */
brcms_c_ampdu_reset_session(&di->ampdu_session, wlc);

- DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
- di->ddoffsetlow, di->ddoffsethigh,
- di->dataoffsetlow, di->dataoffsethigh,
- di->addrext);
+ brcms_dbg_dma(di->core,
+ "ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
+ di->ddoffsetlow, di->ddoffsethigh,
+ di->dataoffsetlow, di->dataoffsethigh,
+ di->addrext);

return (struct dma_pub *) di;

@@ -775,7 +749,7 @@ void dma_detach(struct dma_pub *pub)
{
struct dma_info *di = (struct dma_info *)pub;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

/* free dma descriptor rings */
if (di->txd64)
@@ -851,7 +825,7 @@ static void _dma_rxenable(struct dma_info *di)
uint dmactrlflags = di->dma.dmactrlflags;
u32 control;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

control = D64_RC_RE | (bcma_read32(di->core,
DMA64RXREGOFFS(di, control)) &
@@ -871,7 +845,7 @@ void dma_rxinit(struct dma_pub *pub)
{
struct dma_info *di = (struct dma_info *)pub;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

if (di->nrxd == 0)
return;
@@ -966,7 +940,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
return 0;

len = le16_to_cpu(*(__le16 *) (p->data));
- DMA_TRACE("%s: dma_rx len %d\n", di->name, len);
+ brcms_dbg_dma(di->core, "%s: dma_rx len %d\n", di->name, len);
dma_spin_for_len(len, p);

/* set actual length */
@@ -993,14 +967,15 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
DMA64RXREGOFFS(di, status0)) &
D64_RS0_CD_MASK) - di->rcvptrbase) &
D64_RS0_CD_MASK, struct dma64desc);
- DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
- di->rxin, di->rxout, cur);
+ brcms_dbg_dma(di->core,
+ "rxin %d rxout %d, hw_curr %d\n",
+ di->rxin, di->rxout, cur);
}
#endif /* DEBUG */

if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
- DMA_ERROR("%s: bad frame length (%d)\n",
- di->name, len);
+ brcms_dbg_dma(di->core, "%s: bad frame length (%d)\n",
+ di->name, len);
skb_queue_walk_safe(&dma_frames, p, next) {
skb_unlink(p, &dma_frames);
brcmu_pkt_buf_free_skb(p);
@@ -1017,7 +992,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)

static bool dma64_rxidle(struct dma_info *di)
{
- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

if (di->nrxd == 0)
return true;
@@ -1070,7 +1045,7 @@ bool dma_rxfill(struct dma_pub *pub)

n = di->nrxpost - nrxdactive(di, rxin, rxout);

- DMA_TRACE("%s: post %d\n", di->name, n);
+ brcms_dbg_dma(di->core, "%s: post %d\n", di->name, n);

if (di->rxbufsize > BCMEXTRAHDROOM)
extra_offset = di->rxextrahdrroom;
@@ -1083,9 +1058,11 @@ bool dma_rxfill(struct dma_pub *pub)
p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);

if (p == NULL) {
- DMA_ERROR("%s: out of rxbufs\n", di->name);
+ brcms_dbg_dma(di->core, "%s: out of rxbufs\n",
+ di->name);
if (i == 0 && dma64_rxidle(di)) {
- DMA_ERROR("%s: ring is empty !\n", di->name);
+ brcms_dbg_dma(di->core, "%s: ring is empty !\n",
+ di->name);
ring_empty = true;
}
di->dma.rxnobuf++;
@@ -1130,7 +1107,7 @@ void dma_rxreclaim(struct dma_pub *pub)
struct dma_info *di = (struct dma_info *)pub;
struct sk_buff *p;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

while ((p = _dma_getnextrxp(di, true)))
brcmu_pkt_buf_free_skb(p);
@@ -1161,7 +1138,7 @@ void dma_txinit(struct dma_pub *pub)
struct dma_info *di = (struct dma_info *)pub;
u32 control = D64_XC_XE;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

if (di->ntxd == 0)
return;
@@ -1193,7 +1170,7 @@ void dma_txsuspend(struct dma_pub *pub)
{
struct dma_info *di = (struct dma_info *)pub;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

if (di->ntxd == 0)
return;
@@ -1205,7 +1182,7 @@ void dma_txresume(struct dma_pub *pub)
{
struct dma_info *di = (struct dma_info *)pub;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

if (di->ntxd == 0)
return;
@@ -1228,11 +1205,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
struct dma_info *di = (struct dma_info *)pub;
struct sk_buff *p;

- DMA_TRACE("%s: %s\n",
- di->name,
- range == DMA_RANGE_ALL ? "all" :
- range == DMA_RANGE_TRANSMITTED ? "transmitted" :
- "transferred");
+ brcms_dbg_dma(di->core, "%s: %s\n",
+ di->name,
+ range == DMA_RANGE_ALL ? "all" :
+ range == DMA_RANGE_TRANSMITTED ? "transmitted" :
+ "transferred");

if (di->txin == di->txout)
return;
@@ -1392,7 +1369,7 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
struct ieee80211_tx_info *tx_info;
bool is_ampdu;

- DMA_TRACE("%s:\n", di->name);
+ brcms_dbg_dma(di->core, "%s:\n", di->name);

/* no use to transmit a zero length packet */
if (p->len == 0)
@@ -1430,7 +1407,7 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
return 0;

outoftxd:
- DMA_ERROR("%s: out of txds !!!\n", di->name);
+ brcms_dbg_dma(di->core, "%s: out of txds !!!\n", di->name);
brcmu_pkt_buf_free_skb(p);
di->dma.txavail = 0;
di->dma.txnobuf++;
@@ -1482,11 +1459,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
u16 active_desc;
struct sk_buff *txp;

- DMA_TRACE("%s: %s\n",
- di->name,
- range == DMA_RANGE_ALL ? "all" :
- range == DMA_RANGE_TRANSMITTED ? "transmitted" :
- "transferred");
+ brcms_dbg_dma(di->core, "%s: %s\n",
+ di->name,
+ range == DMA_RANGE_ALL ? "all" :
+ range == DMA_RANGE_TRANSMITTED ? "transmitted" :
+ "transferred");

if (di->ntxd == 0)
return NULL;
@@ -1545,8 +1522,8 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
return txp;

bogus:
- DMA_NONE("bogus curr: start %d end %d txout %d\n",
- start, end, di->txout);
+ brcms_dbg_dma(di->core, "bogus curr: start %d end %d txout %d\n",
+ start, end, di->txout);
return NULL;
}

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
index 459abf1..ff5b80b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
@@ -78,7 +78,7 @@ extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
uint txregbase, uint rxregbase,
uint ntxd, uint nrxd,
uint rxbufsize, int rxextheadroom,
- uint nrxpost, uint rxoffset, uint *msg_level);
+ uint nrxpost, uint rxoffset);

void dma_rxinit(struct dma_pub *pub);
int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 54fa177..58e1f01 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1153,7 +1153,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
dmareg(DMA_RX, 0),
(wme ? NTXD : 0), NRXD,
RXBUFSZ, -1, NRXBUFPOST,
- BRCMS_HWRXOFF, &brcm_msg_level);
+ BRCMS_HWRXOFF);
dma_attach_err |= (NULL == wlc_hw->di[0]);

/*
@@ -1164,8 +1164,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
*/
wlc_hw->di[1] = dma_attach(name, wlc,
dmareg(DMA_TX, 1), 0,
- NTXD, 0, 0, -1, 0, 0,
- &brcm_msg_level);
+ NTXD, 0, 0, -1, 0, 0);
dma_attach_err |= (NULL == wlc_hw->di[1]);

/*
@@ -1175,8 +1174,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
*/
wlc_hw->di[2] = dma_attach(name, wlc,
dmareg(DMA_TX, 2), 0,
- NTXD, 0, 0, -1, 0, 0,
- &brcm_msg_level);
+ NTXD, 0, 0, -1, 0, 0);
dma_attach_err |= (NULL == wlc_hw->di[2]);
/*
* FIFO 3
@@ -1186,7 +1184,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
wlc_hw->di[3] = dma_attach(name, wlc,
dmareg(DMA_TX, 3),
0, NTXD, 0, 0, -1,
- 0, 0, &brcm_msg_level);
+ 0, 0);
dma_attach_err |= (NULL == wlc_hw->di[3]);
/* Cleaner to leave this as if with AP defined */

diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index 12dd33f..54ffe7f 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -84,6 +84,7 @@
#define BRCM_DL_RX 0x00000004
#define BRCM_DL_TX 0x00000008
#define BRCM_DL_INT 0x00000010
+#define BRCM_DL_DMA 0x00000020

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-11-20 22:35:19

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 20.11.2012 21:54, Seth Forshee wrote:
> On Tue, Nov 20, 2012 at 06:44:08PM +0100, Daniel Wagner wrote:
>> Hi Seth,
>>
>> On 20.11.2012 15:28, Seth Forshee wrote:
>>> On Tue, Nov 20, 2012 at 08:30:10AM +0100, Daniel Wagner wrote:
>>>> Hi Seth,
>>>>
>>>> On 19.11.2012 20:11, Daniel Wagner wrote:
>>>>> Works perfectly fine on my machine.
>>>>
>>>> Well, not really true. Though I am not sure if this what I am seeing
>>>> related to your changes. I see following log only when I am using my
>>>> home AP. The pattern is that when the connection stop working I see
>>>> something like this in the log:
>>>>
>>>> [ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
>>>> [ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
>>>> [ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68 tid 0
>>>> [ 8735.573701] wlan0: activated addBA response timer on tid 0
>>>> [ 8735.578826] wlan0: switched off addBA timer for tid 0
>>>> [ 8735.578834] wlan0: Aggregation is on for tid 0
>>>> [ 8749.687530] wlan0: tx session timer expired on tid 0
>>>> [ 8749.687558] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
>>>> [ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0
>>>>
>>>>
>>>> This is what I do: First establishing a connection, then after a while any
>>>> traffic seems stops for a period and sometimes it recovers from that point. If
>>>> not a disconnect/connect (using ConnMan) dance fixes the problem.
>>>
>>> The tx session timer expiring is a result of not having any aggregate
>>> transfers in a while. In my testing with iperf I see periods where the
>>> transfer seems to stall, but it always recovers. These are less frequent
>>> after my patches, but they still happen, and I haven't been able to work
>>> out the cause yet. I'm not sure whether these are related to what you're
>>> seeing or not.
>>>
>>> Luckily I've added a bunch of new debug code. Could you make sure you
>>> have MAC80211_MESSAGE_TRACING and BRCM_TRACING enabled in your config
>>> and collect a trace when this is happening by running:
>>>
>>> trace-cmd record -e mac80211 -e mac80211_msg -e brcmsmac \
>>> -e brcmsmac_tx -e brcmsmac_msg
>>>
>>> This going to collect a lot of data, and you should bump up the trace
>>> buffer size to avoid overruns. Once you've got a trace please compress
>>> trace.dat and put it along with your dmesg somewhere where I can get at
>>> them.
>>
>> I hope I got it right. Here are the requested logs:
>>
>> http://www.monom.org/misc/brcmsmac/traces/
>
> Looks like you got it right. The period you traced doesn't seem to cover
> any of the block ack session timeouts, but I do see this:
>
> [ 225.269777] wlan0: release an RX reorder frame due to timeout on earlier frames
> [ 243.869220] wlan0: unexpected AddBA Req from 1c:c6:3c:1f:50:68 on tid 0
> [ 243.869233] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 32
> [ 243.869250] wlan0: Rx A-MPDU request on tid 0 result 0
> [ 252.254013] brcmsmac bcma0:0: brcms_c_ampdu_dotxstatus_complete: Pkt tx suppressed, illegal channel possibly 13
> <snip repeated messages>
> [ 259.798966] wlan0: release an RX reorder frame due to timeout on earlier frames
> <snip repeated messages>
> [ 265.193640] wlan0: unexpected AddBA Req from 1c:c6:3c:1f:50:68 on tid 0
> [ 265.193648] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 32
> [ 265.193663] wlan0: Rx A-MPDU request on tid 0 result 0
>
> Does something in this time frame correspond to your loss in
> connectivity? The number of packets being sent and received varies some
> throughout the trace but generally stays pretty low. It never completely
> stops though.

I am currently not able to reproduce a complete loss of connectivity.
I have updated from rc3 to rc6 but still using your v2 patchset. Don't
know if this makes a difference. Anyway, the above log was created
with the laptop more away (working place) from the AP. The complete drop of
connectivity happens normally in the living room.

For the second attempt I started to log with the laptop placed at
my working place and then moved later to the living room which is nearer
towards the AP. It seems to trigger the BA timeouts.

> Other than the messages above I don't notice any obvious problems. If
> you can pinpoint exactly what range of timestamps corresponds to your
> problems I can look a bit closer.

Maybe a have look at (this is in the living room)

6119.448028 first drop in througput but it revored
6169.045370 second drop in thoughput but it revored

> Is this a regression introduced by these patches, or was the connection
> with this AP also not working well without them?

I saw the same behavior before but didn't really look closely what
is happening. So I would say this is not a regression.

The new logs also includes also this:

[ 5443.454178] brcmsmac bcma0:0: brcms_c_ampdu_dotxstatus_complete: Pkt tx suppressed, illegal channel possibly 1
[ 5444.185118] ------------[ cut here ]------------
[ 5444.185156] WARNING: at drivers/net/wireless/brcm80211/brcmsmac/main.c:7567 brcms_c_wait_for_tx_completion+0xab/0xc0 [brcmsmac]()
[ 5444.185160] Hardware name: MacBookAir5,2
[ 5444.185162] Modules linked in: tcp_lp lockd sunrpc rfcomm iptable_nat nf_nat_ipv4 nf_nat bnep ip6t_REJECT nf_conntrack_ipv4 nf_conntrack_ipv6 nf_defrag_ipv6 nf_defrag_ipv4 xt_state ip6table_filter nf_conntrack ip6_tables nls_utf8 hfsplus arc4 brcmsmac cordic brcmutil mac80211 cfg80211 iTCO_wdt iTCO_vendor_support joydev snd_hda_codec_hdmi snd_hda_codec_cirrus snd_hda_intel snd_hda_codec snd_hwdep applesmc snd_seq coretemp input_polldev crc32c_intel btusb bluetooth snd_seq_device ghash_clmulni_intel microcode snd_pcm rfkill bcm5974 i2c_i801 pcspkr lpc_ich snd_page_alloc snd_timer mfd_core snd bcma soundcore apple_bl binfmt_misc vhost_net tun macvtap macvlan kvm_intel kvm uinput i915 video i2c_algo_bit drm_kms_helper drm i2c_core
[ 5444.185258] Pid: 2425, comm: kworker/u:24 Not tainted 3.7.0-rc6+ #15
[ 5444.185261] Call Trace:
[ 5444.185276] [<ffffffff8105cacf>] warn_slowpath_common+0x7f/0xc0
[ 5444.185283] [<ffffffff8105cb2a>] warn_slowpath_null+0x1a/0x20
[ 5444.185305] [<ffffffffa041b95b>] brcms_c_wait_for_tx_completion+0xab/0xc0 [brcmsmac]
[ 5444.185319] [<ffffffffa040f68b>] brcms_ops_flush+0x3b/0x60 [brcmsmac]
[ 5444.185351] [<ffffffffa038ec6d>] ieee80211_scan_work+0x34d/0x5e0 [mac80211]
[ 5444.185362] [<ffffffff8101358e>] ? __switch_to+0x13e/0x4a0
[ 5444.185371] [<ffffffff81100ba5>] ? tracing_is_on+0x15/0x30
[ 5444.185381] [<ffffffff81078767>] process_one_work+0x147/0x480
[ 5444.185405] [<ffffffffa038e920>] ? ieee80211_run_deferred_scan+0x90/0x90 [mac80211]
[ 5444.185414] [<ffffffff8107ab2e>] worker_thread+0x15e/0x450
[ 5444.185422] [<ffffffff8107a9d0>] ? flush_delayed_work+0x60/0x60
[ 5444.185430] [<ffffffff8107fdd0>] kthread+0xc0/0xd0
[ 5444.185437] [<ffffffff81010000>] ? ftrace_raw_event_xen_mmu_flush_tlb_others+0xa0/0xe0
[ 5444.185444] [<ffffffff8107fd10>] ? kthread_create_on_node+0x120/0x120
[ 5444.185451] [<ffffffff8161d6ec>] ret_from_fork+0x7c/0xb0
[ 5444.185457] [<ffffffff8107fd10>] ? kthread_create_on_node+0x120/0x120
[ 5444.185462] ---[ end trace 2d063ce11cec7f11 ]---

cheers,
daniel


2012-11-19 20:37:50

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 16/22] brcmsmac: Add brcms_dbg_int() debug macro

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> Also convert relevant message to use this macro.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 1 +
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 12 ++++++------
> drivers/net/wireless/brcm80211/include/defs.h | 1 +
> 3 files changed, 8 insertions(+), 6 deletions(-)




2012-11-27 16:22:46

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 09/22] brcm80211: Allow trace support to be enabled separately from debug

On Mon, Nov 19, 2012 at 03:33:00PM -0600, Seth Forshee wrote:
> > That seems reasonable. Have you any significant impact in throughput
> > with tracing enabled?
>
> I've really only tested with tracing enabled. Compared to before this
> patch series the peak performance (as measured with iperf using a TCP
> connection) is close enough that any differences would be lost in the
> noise, and average performance is better due to the transfer rate being
> more stable. I'll run some tests with and without tracing enabled to
> compare the results. I may not get to it before next week though due to
> the Thanksgiving holiday here in the US.

I've done some unscientific comparison between builds with and without
BRCM_TRACING enabled. UDP iperf performance was identical, both send and
receive. With TCP the difference in throughput was small, definitely
within the range of noise for my small sample size. So as far as I can
tell enabling tracing has a negligible impact on throughput.

Seth


2012-11-15 14:08:30

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 07/22] brcmsmac: Use correct descriptor count when calculating next rx descriptor

nextrxd() is calling txd(), which means that the tx descriptor count is
used to determine when to wrap for determining the next ring buffer
entry. This has worked so far since the driver has been using the same
number of rx and tx descriptors, but it's obviously going to be a
problem if different numbers of descriptors are used.

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 426b9a9..d7ce1ac 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -361,7 +361,7 @@ static uint prevtxd(struct dma_info *di, uint i)

static uint nextrxd(struct dma_info *di, uint i)
{
- return txd(di, i + 1);
+ return rxd(di, i + 1);
}

static uint ntxdactive(struct dma_info *di, uint h, uint t)
--
1.7.9.5


2012-11-19 20:50:33

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 05/22] brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels

On 11/19/2012 08:16 PM, Seth Forshee wrote:
>> True. I believe the statement actually applies to any retry include
>> >non-AMPDU.
> I don't see that non-AMPDU frames are ever requeued after failed tx. Am
> I overlooking soemthing?

Ah, you are right. non-ampdu frame retries are handled in hardware.

Gr. AvS


2012-11-15 14:08:58

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 20/22] brcmsmac: Add tracepoint for macintstatus

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
.../brcm80211/brcmsmac/brcms_trace_events.h | 20 ++++++++++++++++++++
drivers/net/wireless/brcm80211/brcmsmac/main.c | 8 ++++----
2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index 96a962a..2ef7580 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -85,6 +85,26 @@ TRACE_EVENT(brcms_dpc,
)
);

+TRACE_EVENT(brcms_macintstatus,
+ TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus,
+ u32 mask),
+ TP_ARGS(dev, in_isr, macintstatus, mask),
+ TP_STRUCT__entry(
+ __string(dev, dev_name(dev))
+ __field(int, in_isr)
+ __field(u32, macintstatus)
+ __field(u32, mask)
+ ),
+ TP_fast_assign(
+ __assign_str(dev, dev_name(dev));
+ __entry->in_isr = in_isr;
+ __entry->macintstatus = macintstatus;
+ __entry->mask = mask;
+ ),
+ TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev),
+ __entry->in_isr, __entry->macintstatus, __entry->mask)
+);
+
#undef TRACE_SYSTEM
#define TRACE_SYSTEM brcmsmac_tx

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 289f283..f7da9b3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -2552,13 +2552,13 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
{
struct brcms_hardware *wlc_hw = wlc->hw;
struct bcma_device *core = wlc_hw->d11core;
- u32 macintstatus;
+ u32 macintstatus, mask;

/* macintstatus includes a DMA interrupt summary bit */
macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));
+ mask = in_isr ? wlc->macintmask : wlc->defmacintmask;

- brcms_dbg_int(core, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
- macintstatus);
+ trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask);

/* detect cardbus removed, in power down(suspend) and in reset */
if (brcms_deviceremoved(wlc))
@@ -2571,7 +2571,7 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
return 0;

/* defer unsolicited interrupts */
- macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
+ macintstatus &= mask;

/* if not for us */
if (macintstatus == 0)
--
1.7.9.5


2012-11-21 17:57:05

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 11/21/2012 03:35 PM, Seth Forshee wrote:
>
> I'll see if I can reproduce, but if it's specific to the AP then I may
> not have any luck. Don't expect to hear much from me until next week
> though; I'm on holiday starting today and will be visiting family.
>
> Seth
>

The family does not like you testing on their AP, huh ;-) Happy holiday(s).

Gr. AvS


2012-11-15 14:08:23

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 04/22] brcmsmac: Remove unimplemented flow control functions

Functions for flow control exist but remain unimplemented. Remove these
in advance of adding real flow control.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 31 ------------------------
1 file changed, 31 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index e4ef457..135af9a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -35,12 +35,6 @@
#include "main.h"
#include "soc.h"

-/*
- * Indication for txflowcontrol that all priority bits in
- * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
- */
-#define ALLPRIO -1
-
/* watchdog timer, in unit of ms */
#define TIMER_INTERVAL_WATCHDOG 1000
/* radio monitor timer, in unit of ms */
@@ -3767,25 +3761,6 @@ static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
}

-static void
-brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi, bool on, int prio)
-{
- /* transmit flowcontrol is not yet implemented */
-}
-
-static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
-{
- struct brcms_txq_info *qi;
-
- for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
- if (qi->stopped) {
- brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
- qi->stopped = 0;
- }
- }
-}
-
/* push sw hps and wake state through hardware */
static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
{
@@ -5353,9 +5328,6 @@ uint brcms_c_down(struct brcms_c_info *wlc)

wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);

- /* clear txq flow control */
- brcms_c_txflowcontrol_reset(wlc);
-
/* flush tx queues */
for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
brcmu_pktq_flush(&qi->q, true, NULL, NULL);
@@ -8302,9 +8274,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
if (mute_tx)
brcms_b_mute(wlc->hw, true);

- /* clear tx flow control */
- brcms_c_txflowcontrol_reset(wlc);
-
/* enable the RF Disable Delay timer */
bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT);

--
1.7.9.5


2012-11-15 14:08:56

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 19/22] brcmsmac: Improve tx trace and debug support

Add the brcmsmac_tx trace system for tx debugging. Existing code to dump
tx status and descriptors are converted to using tracepoints, allowing
for more efficient collection and post-processing of this data. These
tracepoints are placed to collect data for all tx frames instead of only
on errors. Logging of tx errors is also improved.

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 11 +-
.../brcm80211/brcmsmac/brcms_trace_events.h | 53 ++++
drivers/net/wireless/brcm80211/brcmsmac/main.c | 271 +++-----------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 9 -
4 files changed, 94 insertions(+), 250 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 56d2d6b..1de94f3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -22,6 +22,7 @@
#include "main.h"
#include "ampdu.h"
#include "debug.h"
+#include "brcms_trace_events.h"

/* max number of mpdus in an ampdu */
#define AMPDU_MAX_MPDU 32
@@ -930,12 +931,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
brcms_err(wlc->hw->d11core,
"%s: ampdu tx phy error (0x%x)\n",
__func__, txs->phyerr);
-
- if (brcm_msg_level & BRCM_DL_INFO) {
- brcmu_prpkt("txpkt (AMPDU)", p);
- brcms_c_print_txdesc((struct d11txh *) p->data);
- }
- brcms_c_print_txstatus(txs);
}
}

@@ -948,6 +943,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;

+ trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh));
+
if (tot_mpdu == 0) {
mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
@@ -1077,6 +1074,8 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
while (p) {
tx_info = IEEE80211_SKB_CB(p);
txh = (struct d11txh *) p->data;
+ trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
+ sizeof(*txh));
mcl = le16_to_cpu(txh->MacTxControlLow);
brcmu_pkt_buf_free_skb(p);
/* break out if last packet of ampdu */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index a9aed1f..96a962a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -18,6 +18,8 @@

#define __TRACE_BRCMSMAC_H

+#include <linux/types.h>
+#include <linux/device.h>
#include <linux/tracepoint.h>
#include "mac80211_if.h"

@@ -84,6 +86,57 @@ TRACE_EVENT(brcms_dpc,
);

#undef TRACE_SYSTEM
+#define TRACE_SYSTEM brcmsmac_tx
+
+TRACE_EVENT(brcms_txdesc,
+ TP_PROTO(const struct device *dev,
+ void *txh, size_t txh_len),
+ TP_ARGS(dev, txh, txh_len),
+ TP_STRUCT__entry(
+ __string(dev, dev_name(dev))
+ __dynamic_array(u8, txh, txh_len)
+ ),
+ TP_fast_assign(
+ __assign_str(dev, dev_name(dev));
+ memcpy(__get_dynamic_array(txh), txh, txh_len);
+ ),
+ TP_printk("[%s] txdesc", __get_str(dev))
+);
+
+TRACE_EVENT(brcms_txstatus,
+ TP_PROTO(const struct device *dev, u16 framelen, u16 frameid,
+ u16 status, u16 lasttxtime, u16 sequence, u16 phyerr,
+ u16 ackphyrxsh),
+ TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr,
+ ackphyrxsh),
+ TP_STRUCT__entry(
+ __string(dev, dev_name(dev))
+ __field(u16, framelen)
+ __field(u16, frameid)
+ __field(u16, status)
+ __field(u16, lasttxtime)
+ __field(u16, sequence)
+ __field(u16, phyerr)
+ __field(u16, ackphyrxsh)
+ ),
+ TP_fast_assign(
+ __assign_str(dev, dev_name(dev));
+ __entry->framelen = framelen;
+ __entry->frameid = frameid;
+ __entry->status = status;
+ __entry->lasttxtime = lasttxtime;
+ __entry->sequence = sequence;
+ __entry->phyerr = phyerr;
+ __entry->ackphyrxsh = ackphyrxsh;
+ ),
+ TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x "
+ "Seq %#04x PHYTxStatus %#04x RxAck %#04x",
+ __get_str(dev), __entry->frameid, __entry->status,
+ __entry->lasttxtime, __entry->sequence, __entry->phyerr,
+ __entry->ackphyrxsh)
+);
+
+#undef TRACE_SYSTEM
#define TRACE_SYSTEM brcmsmac_msg

#define MAX_MSG_LEN 100
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 58e1f01..289f283 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -36,6 +36,7 @@
#include "soc.h"
#include "dma.h"
#include "debug.h"
+#include "brcms_trace_events.h"

/* watchdog timer, in unit of ms */
#define TIMER_INTERVAL_WATCHDOG 1000
@@ -862,7 +863,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
struct sk_buff *p = NULL;
uint queue = NFIFO;
struct dma_pub *dma = NULL;
- struct d11txh *txh;
+ struct d11txh *txh = NULL;
struct scb *scb = NULL;
bool free_pdu;
int tx_rts, tx_frame_count, tx_rts_count;
@@ -875,6 +876,10 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
int i;
bool fatal = true;

+ trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen,
+ txs->frameid, txs->status, txs->lasttxtime,
+ txs->sequence, txs->phyerr, txs->ackphyrxsh);
+
/* discard intermediate indications for ucode with one legitimate case:
* e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
* but the subsequent tx of DATA failed. so it will start rts/cts
@@ -888,29 +893,30 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
}

queue = txs->frameid & TXFID_QUEUE_MASK;
- if (queue >= NFIFO)
+ if (queue >= NFIFO) {
+ brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue);
goto out;
+ }

dma = wlc->hw->di[queue];

p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
- if (p == NULL)
+ if (p == NULL) {
+ brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n");
goto out;
+ }

txh = (struct d11txh *) (p->data);
mcl = le16_to_cpu(txh->MacTxControlLow);

- if (txs->phyerr) {
- if (brcm_msg_level & BRCM_DL_INFO) {
- brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
- txs->phyerr, txh->MainRates);
- brcms_c_print_txdesc(txh);
- }
- brcms_c_print_txstatus(txs);
- }
+ if (txs->phyerr)
+ brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
+ txs->phyerr, txh->MainRates);

- if (txs->frameid != le16_to_cpu(txh->TxFrameID))
+ if (txs->frameid != le16_to_cpu(txh->TxFrameID)) {
+ brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n");
goto out;
+ }
tx_info = IEEE80211_SKB_CB(p);
h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);

@@ -923,11 +929,20 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
goto out;
}

+ /*
+ * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU
+ * frames; this traces them for the rest.
+ */
+ trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh));
+
supr_status = txs->status & TX_STATUS_SUPR_MASK;
- if (supr_status == TX_STATUS_SUPR_BADCH)
+ if (supr_status == TX_STATUS_SUPR_BADCH) {
+ unsigned xfts = le16_to_cpu(txh->XtraFrameTypes);
brcms_dbg_tx(wlc->hw->d11core,
- "Pkt tx suppressed, possibly channel %d\n",
+ "Pkt tx suppressed, dest chan %u, current %d\n",
+ (xfts >> XFTS_CHANNEL_SHIFT) & 0xff,
CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+ }

tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
tx_frame_count =
@@ -1018,8 +1033,13 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
fatal = false;

out:
- if (fatal && p)
- brcmu_pkt_buf_free_skb(p);
+ if (fatal) {
+ if (txh)
+ trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
+ sizeof(*txh));
+ if (p)
+ brcmu_pkt_buf_free_skb(p);
+ }

if (dma && queue < NFIFO) {
u16 ac_queue = brcms_fifo_to_ac(queue);
@@ -1049,8 +1069,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
*/
uint max_tx_num = bound ? TXSBND : -1;

- brcms_dbg_tx(core, "wl%d\n", wlc_hw->unit);
-
txs = &txstatus;
core = wlc_hw->d11core;
*fatal = false;
@@ -5662,45 +5680,6 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
return -ENODATA;
}

-void brcms_c_print_txstatus(struct tx_status *txs)
-{
- pr_debug("\ntxpkt (MPDU) Complete\n");
-
- pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status);
-
- pr_debug("[15:12] %d frame attempts\n",
- (txs->status & TX_STATUS_FRM_RTX_MASK) >>
- TX_STATUS_FRM_RTX_SHIFT);
- pr_debug(" [11:8] %d rts attempts\n",
- (txs->status & TX_STATUS_RTS_RTX_MASK) >>
- TX_STATUS_RTS_RTX_SHIFT);
- pr_debug(" [7] %d PM mode indicated\n",
- txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
- pr_debug(" [6] %d intermediate status\n",
- txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
- pr_debug(" [5] %d AMPDU\n",
- txs->status & TX_STATUS_AMPDU ? 1 : 0);
- pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n",
- (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
- (const char *[]) {
- "None",
- "PMQ Entry",
- "Flush request",
- "Previous frag failure",
- "Channel mismatch",
- "Lifetime Expiry",
- "Underflow"
- } [(txs->status & TX_STATUS_SUPR_MASK) >>
- TX_STATUS_SUPR_SHIFT]);
- pr_debug(" [1] %d acked\n",
- txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
-
- pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
- txs->lasttxtime, txs->sequence, txs->phyerr,
- (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
- (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
-}
-
static bool brcms_c_chipmatch_pci(struct bcma_device *core)
{
struct pci_dev *pcidev = core->bus->host_pci;
@@ -5749,184 +5728,6 @@ bool brcms_c_chipmatch(struct bcma_device *core)
}
}

-#if defined(DEBUG)
-void brcms_c_print_txdesc(struct d11txh *txh)
-{
- u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
- u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
- u16 mfc = le16_to_cpu(txh->MacFrameControl);
- u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
- u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
- u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
- u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
- u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
- u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
- u16 mainrates = le16_to_cpu(txh->MainRates);
- u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
- u8 *iv = txh->IV;
- u8 *ra = txh->TxFrameRA;
- u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
- u8 *rtspfb = txh->RTSPLCPFallback;
- u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
- u8 *fragpfb = txh->FragPLCPFallback;
- u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
- u16 mmodelen = le16_to_cpu(txh->MModeLen);
- u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
- u16 tfid = le16_to_cpu(txh->TxFrameID);
- u16 txs = le16_to_cpu(txh->TxStatus);
- u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
- u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
- u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
- u16 mmbyte = le16_to_cpu(txh->MinMBytes);
-
- u8 *rtsph = txh->RTSPhyHeader;
- struct ieee80211_rts rts = txh->rts_frame;
-
- /* add plcp header along with txh descriptor */
- brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
- "Raw TxDesc + plcp header:\n");
-
- pr_debug("TxCtlLow: %04x ", mtcl);
- pr_debug("TxCtlHigh: %04x ", mtch);
- pr_debug("FC: %04x ", mfc);
- pr_debug("FES Time: %04x\n", tfest);
- pr_debug("PhyCtl: %04x%s ", ptcw,
- (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
- pr_debug("PhyCtl_1: %04x ", ptcw_1);
- pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
- pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
- pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
- pr_debug("MainRates: %04x ", mainrates);
- pr_debug("XtraFrameTypes: %04x ", xtraft);
- pr_debug("\n");
-
- print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
- print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
- ra, sizeof(txh->TxFrameRA));
-
- pr_debug("Fb FES Time: %04x ", tfestfb);
- print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
- rtspfb, sizeof(txh->RTSPLCPFallback));
- pr_debug("RTS DUR: %04x ", rtsdfb);
- print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
- fragpfb, sizeof(txh->FragPLCPFallback));
- pr_debug("DUR: %04x", fragdfb);
- pr_debug("\n");
-
- pr_debug("MModeLen: %04x ", mmodelen);
- pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
-
- pr_debug("FrameID: %04x\n", tfid);
- pr_debug("TxStatus: %04x\n", txs);
-
- pr_debug("MaxNumMpdu: %04x\n", mnmpdu);
- pr_debug("MaxAggbyte: %04x\n", mabyte);
- pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f);
- pr_debug("MinByte: %04x\n", mmbyte);
-
- print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
- rtsph, sizeof(txh->RTSPhyHeader));
- print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
- (u8 *)&rts, sizeof(txh->rts_frame));
- pr_debug("\n");
-}
-#endif /* defined(DEBUG) */
-
-#if defined(DEBUG)
-static int
-brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
- int len)
-{
- int i;
- char *p = buf;
- char hexstr[16];
- int slen = 0, nlen = 0;
- u32 bit;
- const char *name;
-
- if (len < 2 || !buf)
- return 0;
-
- buf[0] = '\0';
-
- for (i = 0; flags != 0; i++) {
- bit = bd[i].bit;
- name = bd[i].name;
- if (bit == 0 && flags != 0) {
- /* print any unnamed bits */
- snprintf(hexstr, 16, "0x%X", flags);
- name = hexstr;
- flags = 0; /* exit loop */
- } else if ((flags & bit) == 0)
- continue;
- flags &= ~bit;
- nlen = strlen(name);
- slen += nlen;
- /* count btwn flag space */
- if (flags != 0)
- slen += 1;
- /* need NULL char as well */
- if (len <= slen)
- break;
- /* copy NULL char but don't count it */
- strncpy(p, name, nlen + 1);
- p += nlen;
- /* copy btwn flag space and NULL char */
- if (flags != 0)
- p += snprintf(p, 2, " ");
- len -= slen;
- }
-
- /* indicate the str was too short */
- if (flags != 0) {
- if (len < 2)
- p -= 2 - len; /* overwrite last char */
- p += snprintf(p, 2, ">");
- }
-
- return (int)(p - buf);
-}
-#endif /* defined(DEBUG) */
-
-#if defined(DEBUG)
-void brcms_c_print_rxh(struct d11rxhdr *rxh)
-{
- u16 len = rxh->RxFrameSize;
- u16 phystatus_0 = rxh->PhyRxStatus_0;
- u16 phystatus_1 = rxh->PhyRxStatus_1;
- u16 phystatus_2 = rxh->PhyRxStatus_2;
- u16 phystatus_3 = rxh->PhyRxStatus_3;
- u16 macstatus1 = rxh->RxStatus1;
- u16 macstatus2 = rxh->RxStatus2;
- char flagstr[64];
- char lenbuf[20];
- static const struct brcms_c_bit_desc macstat_flags[] = {
- {RXS_FCSERR, "FCSErr"},
- {RXS_RESPFRAMETX, "Reply"},
- {RXS_PBPRES, "PADDING"},
- {RXS_DECATMPT, "DeCr"},
- {RXS_DECERR, "DeCrErr"},
- {RXS_BCNSENT, "Bcn"},
- {0, NULL}
- };
-
- brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
-
- brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
-
- snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
-
- pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len,
- (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
- pr_debug("RxPHYStatus: %04x %04x %04x %04x\n",
- phystatus_0, phystatus_1, phystatus_2, phystatus_3);
- pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr);
- pr_debug("RXMACaggtype: %x\n",
- (macstatus2 & RXS_AGGTYPE_MASK));
- pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime);
-}
-#endif /* defined(DEBUG) */
-
u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
{
u16 table_ptr;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 8a58cc1..fb44774 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -612,18 +612,9 @@ struct brcms_bss_cfg {

extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
struct sk_buff *p);
-extern void brcms_c_print_txstatus(struct tx_status *txs);
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks);

-#if defined(DEBUG)
-extern void brcms_c_print_txdesc(struct d11txh *txh);
-#else
-static inline void brcms_c_print_txdesc(struct d11txh *txh)
-{
-}
-#endif
-
extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
--
1.7.9.5


2012-11-15 14:08:36

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 10/22] brcm80211: Convert log message levels to debug levels

In preparation for enhancements to debug and trace support, convert the
message levels to debug levels which will be used for enabling
categories of debug messages. The two message levels are little-used
anyway and are combined into the BRCM_DL_INFO debug level.

Acked-by: Arend van Spriel <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 2 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 4 ++--
drivers/net/wireless/brcm80211/brcmsmac/types.h | 2 +-
drivers/net/wireless/brcm80211/include/defs.h | 5 ++---
4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index c62fd3d..93d4ecd 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -926,7 +926,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
__func__, txs->phyerr);

- if (brcm_msg_level & LOG_ERROR_VAL) {
+ if (brcm_msg_level & BRCM_DL_INFO) {
brcmu_prpkt("txpkt (AMPDU)", p);
brcms_c_print_txdesc((struct d11txh *) p->data);
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index ca93214..a5bf3b6 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -281,7 +281,7 @@ struct edcf_acparam {
/* debug/trace */
uint brcm_msg_level =
#if defined(DEBUG)
- LOG_ERROR_VAL;
+ BRCM_DL_INFO;
#else
0;
#endif /* DEBUG */
@@ -902,7 +902,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
mcl = le16_to_cpu(txh->MacTxControlLow);

if (txs->phyerr) {
- if (brcm_msg_level & LOG_ERROR_VAL) {
+ if (brcm_msg_level & BRCM_DL_INFO) {
wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
txs->phyerr, txh->MainRates);
brcms_c_print_txdesc(txh);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
index e3abc0e..ae1f3ad 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -246,7 +246,7 @@

#define BCMMSG(dev, fmt, args...) \
do { \
- if (brcm_msg_level & LOG_TRACE_VAL) \
+ if (brcm_msg_level & BRCM_DL_INFO) \
wiphy_err(dev, "%s: " fmt, __func__, ##args); \
} while (0)

diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index f0d8c04..223eb2b 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -78,9 +78,8 @@
#define PM_OFF 0
#define PM_MAX 1

-/* Message levels */
-#define LOG_ERROR_VAL 0x00000001
-#define LOG_TRACE_VAL 0x00000002
+/* Debug levels */
+#define BRCM_DL_INFO 0x00000001

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-11-20 17:44:10

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Seth,

On 20.11.2012 15:28, Seth Forshee wrote:
> On Tue, Nov 20, 2012 at 08:30:10AM +0100, Daniel Wagner wrote:
>> Hi Seth,
>>
>> On 19.11.2012 20:11, Daniel Wagner wrote:
>>> Works perfectly fine on my machine.
>>
>> Well, not really true. Though I am not sure if this what I am seeing
>> related to your changes. I see following log only when I am using my
>> home AP. The pattern is that when the connection stop working I see
>> something like this in the log:
>>
>> [ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
>> [ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
>> [ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68 tid 0
>> [ 8735.573701] wlan0: activated addBA response timer on tid 0
>> [ 8735.578826] wlan0: switched off addBA timer for tid 0
>> [ 8735.578834] wlan0: Aggregation is on for tid 0
>> [ 8749.687530] wlan0: tx session timer expired on tid 0
>> [ 8749.687558] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
>> [ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0
>>
>>
>> This is what I do: First establishing a connection, then after a while any
>> traffic seems stops for a period and sometimes it recovers from that point. If
>> not a disconnect/connect (using ConnMan) dance fixes the problem.
>
> The tx session timer expiring is a result of not having any aggregate
> transfers in a while. In my testing with iperf I see periods where the
> transfer seems to stall, but it always recovers. These are less frequent
> after my patches, but they still happen, and I haven't been able to work
> out the cause yet. I'm not sure whether these are related to what you're
> seeing or not.
>
> Luckily I've added a bunch of new debug code. Could you make sure you
> have MAC80211_MESSAGE_TRACING and BRCM_TRACING enabled in your config
> and collect a trace when this is happening by running:
>
> trace-cmd record -e mac80211 -e mac80211_msg -e brcmsmac \
> -e brcmsmac_tx -e brcmsmac_msg
>
> This going to collect a lot of data, and you should bump up the trace
> buffer size to avoid overruns. Once you've got a trace please compress
> trace.dat and put it along with your dmesg somewhere where I can get at
> them.

I hope I got it right. Here are the requested logs:

http://www.monom.org/misc/brcmsmac/traces/

thanks,
daniel

2012-11-20 22:45:07

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

>> Looks like you got it right. The period you traced doesn't seem to cover
>> any of the block ack session timeouts, but I do see this:
>>
>> [ 225.269777] wlan0: release an RX reorder frame due to timeout on earlier frames
>> [ 243.869220] wlan0: unexpected AddBA Req from 1c:c6:3c:1f:50:68 on tid 0
>> [ 243.869233] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 32
>> [ 243.869250] wlan0: Rx A-MPDU request on tid 0 result 0
>> [ 252.254013] brcmsmac bcma0:0: brcms_c_ampdu_dotxstatus_complete: Pkt tx suppressed, illegal channel possibly 13
>> <snip repeated messages>
>> [ 259.798966] wlan0: release an RX reorder frame due to timeout on earlier frames
>> <snip repeated messages>
>> [ 265.193640] wlan0: unexpected AddBA Req from 1c:c6:3c:1f:50:68 on tid 0
>> [ 265.193648] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 32
>> [ 265.193663] wlan0: Rx A-MPDU request on tid 0 result 0
>>
>> Does something in this time frame correspond to your loss in
>> connectivity? The number of packets being sent and received varies some
>> throughout the trace but generally stays pretty low. It never completely
>> stops though.
>
> I am currently not able to reproduce a complete loss of connectivity.

I fear it is a heisenbug. After turning the tracing off I was able to
reproduce it very easily.



2012-11-20 20:54:26

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Tue, Nov 20, 2012 at 06:44:08PM +0100, Daniel Wagner wrote:
> Hi Seth,
>
> On 20.11.2012 15:28, Seth Forshee wrote:
> >On Tue, Nov 20, 2012 at 08:30:10AM +0100, Daniel Wagner wrote:
> >>Hi Seth,
> >>
> >>On 19.11.2012 20:11, Daniel Wagner wrote:
> >>>Works perfectly fine on my machine.
> >>
> >>Well, not really true. Though I am not sure if this what I am seeing
> >>related to your changes. I see following log only when I am using my
> >>home AP. The pattern is that when the connection stop working I see
> >>something like this in the log:
> >>
> >>[ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
> >>[ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
> >>[ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68 tid 0
> >>[ 8735.573701] wlan0: activated addBA response timer on tid 0
> >>[ 8735.578826] wlan0: switched off addBA timer for tid 0
> >>[ 8735.578834] wlan0: Aggregation is on for tid 0
> >>[ 8749.687530] wlan0: tx session timer expired on tid 0
> >>[ 8749.687558] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
> >>[ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0
> >>
> >>
> >>This is what I do: First establishing a connection, then after a while any
> >>traffic seems stops for a period and sometimes it recovers from that point. If
> >>not a disconnect/connect (using ConnMan) dance fixes the problem.
> >
> >The tx session timer expiring is a result of not having any aggregate
> >transfers in a while. In my testing with iperf I see periods where the
> >transfer seems to stall, but it always recovers. These are less frequent
> >after my patches, but they still happen, and I haven't been able to work
> >out the cause yet. I'm not sure whether these are related to what you're
> >seeing or not.
> >
> >Luckily I've added a bunch of new debug code. Could you make sure you
> >have MAC80211_MESSAGE_TRACING and BRCM_TRACING enabled in your config
> >and collect a trace when this is happening by running:
> >
> > trace-cmd record -e mac80211 -e mac80211_msg -e brcmsmac \
> > -e brcmsmac_tx -e brcmsmac_msg
> >
> >This going to collect a lot of data, and you should bump up the trace
> >buffer size to avoid overruns. Once you've got a trace please compress
> >trace.dat and put it along with your dmesg somewhere where I can get at
> >them.
>
> I hope I got it right. Here are the requested logs:
>
> http://www.monom.org/misc/brcmsmac/traces/

Looks like you got it right. The period you traced doesn't seem to cover
any of the block ack session timeouts, but I do see this:

[ 225.269777] wlan0: release an RX reorder frame due to timeout on earlier frames
[ 243.869220] wlan0: unexpected AddBA Req from 1c:c6:3c:1f:50:68 on tid 0
[ 243.869233] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 32
[ 243.869250] wlan0: Rx A-MPDU request on tid 0 result 0
[ 252.254013] brcmsmac bcma0:0: brcms_c_ampdu_dotxstatus_complete: Pkt tx suppressed, illegal channel possibly 13
<snip repeated messages>
[ 259.798966] wlan0: release an RX reorder frame due to timeout on earlier frames
<snip repeated messages>
[ 265.193640] wlan0: unexpected AddBA Req from 1c:c6:3c:1f:50:68 on tid 0
[ 265.193648] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 32
[ 265.193663] wlan0: Rx A-MPDU request on tid 0 result 0

Does something in this time frame correspond to your loss in
connectivity? The number of packets being sent and received varies some
throughout the trace but generally stays pretty low. It never completely
stops though.

Other than the messages above I don't notice any obvious problems. If
you can pinpoint exactly what range of timestamps corresponds to your
problems I can look a bit closer.

Is this a regression introduced by these patches, or was the connection
with this AP also not working well without them?

Thanks,
Seth


2012-11-15 14:08:54

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 18/22] brcmsmac: Add brcms_dbg_ht() debug macro

Also convert relevant messages to use this macro.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 35 ++++++++++++-----------
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 1 +
drivers/net/wireless/brcm80211/brcmsmac/stf.c | 8 ++++--
drivers/net/wireless/brcm80211/include/defs.h | 1 +
4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 2916ddf..56d2d6b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -371,7 +371,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
offsetof(struct macstat, txfunfl[fid]));
new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
if (new_txunfl == 0) {
- BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
+ brcms_dbg_ht(wlc->hw->d11core,
+ "TX status FRAG set but no tx underflows\n");
return -1;
}
fifo->prev_txfunfl = cur_txunfl;
@@ -393,8 +394,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
if (fifo->accum_txfunfl < 10)
return 0;

- BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n",
- current_ampdu_cnt, fifo->accum_txfunfl);
+ brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n",
+ current_ampdu_cnt, fifo->accum_txfunfl);

/*
compute the current ratio of tx unfl per ampdu.
@@ -447,9 +448,10 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
(max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
/ (max_mpdu * FFPLD_MPDU_SIZE)) * 100;

- BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
- "pre-load size %d\n",
- fifo->dmaxferrate, fifo->ampdu_pld_size);
+ brcms_dbg_ht(wlc->hw->d11core,
+ "DMA estimated transfer rate %d; "
+ "pre-load size %d\n",
+ fifo->dmaxferrate, fifo->ampdu_pld_size);
} else {

/* decrease ampdu size */
@@ -810,9 +812,9 @@ void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session)
BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
}

- BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
- wlc->pub->unit, skb_queue_len(&session->skb_list),
- session->ampdu_len);
+ brcms_dbg_ht(wlc->hw->d11core, "wl%d: count %d ampdu_len %d\n",
+ wlc->pub->unit, skb_queue_len(&session->skb_list),
+ session->ampdu_len);
}

static void
@@ -852,7 +854,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
u8 antselid = 0;
u8 retry_limit, rr_retry_limit;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
- struct wiphy *wiphy = wlc->wiphy;

#ifdef DEBUG
u8 hole[AMPDU_MAX_MPDU];
@@ -956,10 +957,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
ack_recd = false;
if (ba_recd) {
bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
- BCMMSG(wiphy,
- "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
- tid, seq, start_seq, bindex,
- isset(bitmap, bindex), index);
+ brcms_dbg_ht(wlc->hw->d11core,
+ "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
+ tid, seq, start_seq, bindex,
+ isset(bitmap, bindex), index);
/* if acked then clear bit and free packet */
if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
&& isset(bitmap, bindex)) {
@@ -1010,9 +1011,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
IEEE80211_TX_STAT_AMPDU_NO_BACK;
skb_pull(p, D11_PHY_HDR_LEN);
skb_pull(p, D11_TXH_LEN);
- BCMMSG(wiphy,
- "BA Timeout, seq %d, in_transit %d\n",
- seq, ini->tx_in_transit);
+ brcms_dbg_ht(wlc->hw->d11core,
+ "BA Timeout, seq %d, in_transit %d\n",
+ seq, ini->tx_in_transit);
ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
p);
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
index 2e7e077..c0d2cf7 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -41,5 +41,6 @@ static inline void __brcms_dbg(struct device *dev, u32 level,
#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a)
#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a)
#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a)
+#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a)

#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
index ed1d1aa..dd91627 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -23,6 +23,7 @@
#include "channel.h"
#include "main.h"
#include "stf.h"
+#include "debug.h"

#define MIN_SPATIAL_EXPANSION 0
#define MAX_SPATIAL_EXPANSION 1
@@ -160,8 +161,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
u8 core_mask)
{
- BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
- wlc->pub->unit, Nsts, core_mask);
+ brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n",
+ wlc->pub->unit, Nsts, core_mask);

if (hweight8(core_mask) > wlc->stf->txstreams)
core_mask = 0;
@@ -194,7 +195,8 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
int i;
u8 core_mask = 0;

- BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
+ brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit,
+ val);

wlc->stf->spatial_policy = (s8) val;
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index 54ffe7f..fb7cbcf 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -85,6 +85,7 @@
#define BRCM_DL_TX 0x00000008
#define BRCM_DL_INT 0x00000010
#define BRCM_DL_DMA 0x00000020
+#define BRCM_DL_HT 0x00000040

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-11-19 18:35:16

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 02/22] brcmsmac: Don't weight AMPDU packets in txfifo

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> According to the comments this "reduces rate lag," but in reality the
> only way this value is used is for determining whether or not any frames
> remain to be transmitted. Therefore there's no reason for AMPDU packets
> to receive any weighting.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 12 +++---------
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 19 +++++++++----------
> drivers/net/wireless/brcm80211/brcmsmac/main.h | 6 ++----
> 3 files changed, 14 insertions(+), 23 deletions(-)



2012-11-15 14:08:34

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 09/22] brcm80211: Allow trace support to be enabled separately from debug

Since the runtime overhead of trace support is small when tracing is
disabled, users may be interested in turning on trace support while
leaving other debug features off. Add a new config option named
CONFIG_BRCM_TRACING for this purpose.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/Kconfig | 11 +++++++++++
.../brcm80211/brcmsmac/brcms_trace_events.h | 6 +++---
2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index c9d811e..3735c27 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -63,6 +63,17 @@ config BRCMISCAN
new E-Scan method which uses less memory in firmware and gives no
limitation on the number of scan results.

+config BRCM_TRACING
+ bool "Broadcom device tracing"
+ depends on BRCMSMAC || BRCMFMAC
+ ---help---
+ If you say Y here, the Broadcom wireless drivers will register
+ with ftrace to dump event information into the trace ringbuffer.
+ Tracing can be enabled at runtime to aid in debugging wireless
+ issues. This option adds a small amount of overhead when tracing
+ is disabled. If unsure, say Y to allow developers to better help
+ you when wireless problems occur.
+
config BRCMDBG
bool "Broadcom driver debug functions"
depends on BRCMSMAC || BRCMFMAC
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index 27dd73e..bcf6969 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -24,7 +24,7 @@
#include <linux/tracepoint.h>
#include "mac80211_if.h"

-#ifndef CONFIG_BRCMDBG
+#ifndef CONFIG_BRCM_TRACING
#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {}
@@ -80,7 +80,7 @@ TRACE_EVENT(brcms_dpc,

#endif /* __TRACE_BRCMSMAC_H */

-#ifdef CONFIG_BRCMDBG
+#ifdef CONFIG_BRCM_TRACING

#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
@@ -89,4 +89,4 @@ TRACE_EVENT(brcms_dpc,

#include <trace/define_trace.h>

-#endif /* CONFIG_BRCMDBG */
+#endif /* CONFIG_BRCM_TRACING */
--
1.7.9.5


2012-11-19 21:33:22

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Mon, Nov 19, 2012 at 09:45:00PM +0100, Arend van Spriel wrote:
> On 11/15/2012 03:07 PM, Seth Forshee wrote:
> >Hi Arend,
> >
> >As promised, here's the updated patch series for brcmsmac to remove the
> >tx packet queue, add flow control, and add enhanced debug trace support.
> >I've broken up the tx rework into multiple patches as you requested.
> >Most notably I've split out the AMPDU session support into a separate
> >patch, which should make it easier to review that change. I've done
> >basic testing of each of the new commits to try and verify that no
> >obvious regressions are introduced by any of them.
>
> I replied to the patches that were reworked. We skipped the already
> Acked-by patches in this review round.

Great, thanks! I'm hoping it's not to late to get these in for 3.8.

John: Arend had contacted me off-list last week noting a conflict with
wireless-testing. I resolved this and pushed it to the following branch
if you'd like to take the patches from there. It is lacking the
Reviewed-by tags that Arend supplied today, however.

git://kernel.ubuntu.com/sforshee/linux.git brcms-tx-wireless-testing

> The patches have been in nightly testing on bcm43224 for a couple of
> days. It still occasionally does show the infamous warning in the
> .flush() callback. Can not have it all. I want to run the changes on
> bcm4313 as well.

Hopefully we can get this one taken care of soon, and the channel
suppression errors as well ;-)

Seth


2012-11-20 14:28:29

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Tue, Nov 20, 2012 at 08:30:10AM +0100, Daniel Wagner wrote:
> Hi Seth,
>
> On 19.11.2012 20:11, Daniel Wagner wrote:
> > Works perfectly fine on my machine.
>
> Well, not really true. Though I am not sure if this what I am seeing
> related to your changes. I see following log only when I am using my
> home AP. The pattern is that when the connection stop working I see
> something like this in the log:
>
> [ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
> [ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
> [ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68 tid 0
> [ 8735.573701] wlan0: activated addBA response timer on tid 0
> [ 8735.578826] wlan0: switched off addBA timer for tid 0
> [ 8735.578834] wlan0: Aggregation is on for tid 0
> [ 8749.687530] wlan0: tx session timer expired on tid 0
> [ 8749.687558] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
> [ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0
>
>
> This is what I do: First establishing a connection, then after a while any
> traffic seems stops for a period and sometimes it recovers from that point. If
> not a disconnect/connect (using ConnMan) dance fixes the problem.

The tx session timer expiring is a result of not having any aggregate
transfers in a while. In my testing with iperf I see periods where the
transfer seems to stall, but it always recovers. These are less frequent
after my patches, but they still happen, and I haven't been able to work
out the cause yet. I'm not sure whether these are related to what you're
seeing or not.

Luckily I've added a bunch of new debug code. Could you make sure you
have MAC80211_MESSAGE_TRACING and BRCM_TRACING enabled in your config
and collect a trace when this is happening by running:

trace-cmd record -e mac80211 -e mac80211_msg -e brcmsmac \
-e brcmsmac_tx -e brcmsmac_msg

This going to collect a lot of data, and you should bump up the trace
buffer size to avoid overruns. Once you've got a trace please compress
trace.dat and put it along with your dmesg somewhere where I can get at
them.

Thanks,
Seth


2012-11-15 14:08:28

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 06/22] brcmsmac: Remove internal tx queue

The brcmsmac internal tx buffering is problematic. The amount of
buffering is excessive (228 packets in addition to the 256 slots in each
DMA ring), and frames may be dropped due to a lack of flow control.

This patch reworks the transmit code path to remove the internal
buffering. Frames are immediately handed off to the DMA support rather
than passing through an intermediate queue. Non-aggregate frames are
queued immediately into the tx rings, and aggregate frames are queued
temporarily in an AMPDU session until ready for transmit.

Transmit flow control is also added to avoid dropping packets when the
tx rings are full. Conceptually this is a separate change, but it's
included in this commit because removing the tx queue without adding
flow control could cause significant problems.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 167 +--------
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 3 -
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 189 ++++++++--
drivers/net/wireless/brcm80211/brcmsmac/dma.h | 9 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 459 ++++++++---------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 33 +-
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 13 -
drivers/net/wireless/brcm80211/brcmsmac/types.h | 1 -
8 files changed, 316 insertions(+), 558 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 0b4a490..c62fd3d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -813,133 +813,6 @@ void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session)
session->ampdu_len);
}

-int
-brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
- struct sk_buff **pdu, int prec)
-{
- struct brcms_c_info *wlc;
- struct sk_buff *p;
- struct brcms_ampdu_session session;
- int err = 0;
- u8 tid;
-
- uint count, fifo, seg_cnt = 0;
- struct scb *scb;
- struct scb_ampdu *scb_ampdu;
- struct scb_ampdu_tid_ini *ini;
- struct ieee80211_tx_info *tx_info;
- u16 qlen;
- struct wiphy *wiphy;
-
- wlc = ampdu->wlc;
- wiphy = wlc->wiphy;
- p = *pdu;
-
- tid = (u8) (p->priority);
-
- scb = &wlc->pri_scb;
- scb_ampdu = &scb->scb_ampdu;
- ini = &scb_ampdu->ini[tid];
-
- /* Let pressure continue to build ... */
- qlen = pktq_plen(&qi->q, prec);
- if (ini->tx_in_transit > 0 &&
- qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
- /* Collect multiple MPDU's to be sent in the next AMPDU */
- return -EBUSY;
-
- /* at this point we intend to transmit an AMPDU */
- brcms_c_ampdu_reset_session(&session, wlc);
-
- while (p) {
- struct ieee80211_tx_rate *txrate;
-
- tx_info = IEEE80211_SKB_CB(p);
- txrate = tx_info->status.rates;
-
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
- err = brcms_c_prep_pdu(wlc, p, &fifo);
- } else {
- wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
- *pdu = NULL;
- err = 0;
- break;
- }
-
- if (err) {
- if (err == -EBUSY) {
- wiphy_err(wiphy, "wl%d: sendampdu: "
- "prep_xdu retry\n", wlc->pub->unit);
- *pdu = p;
- break;
- }
-
- /* error in the packet; reject it */
- wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
- "rejected\n", wlc->pub->unit);
- *pdu = NULL;
- break;
- }
-
- err = brcms_c_ampdu_add_frame(&session, p);
- if (err == -ENOSPC) {
- /*
- * No space for this packet in the AMPDU.
- * Requeue packet and proceed;
- */
- *pdu = p;
- break;
- } else if (err) {
- /* Unexpected error; reject packet */
- wiphy_err(wiphy, "wl%d: sendampdu: add_frame rejected",
- wlc->pub->unit);
- *pdu = NULL;
- break;
- }
-
- seg_cnt += 1;
-
- /*
- * check to see if the next pkt is
- * a candidate for aggregation
- */
- p = pktq_ppeek(&qi->q, prec);
- if (p) {
- tx_info = IEEE80211_SKB_CB(p);
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
- /*
- * check if there are enough
- * descriptors available
- */
- if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
- wiphy_err(wiphy, "%s: No fifo space "
- "!!\n", __func__);
- p = NULL;
- continue;
- }
- /* next packet fit for aggregation so dequeue */
- p = brcmu_pktq_pdeq(&qi->q, prec);
- } else {
- p = NULL;
- }
- }
- } /* end while(p) */
-
- count = skb_queue_len(&session.skb_list);
- ini->tx_in_transit += count;
-
- if (count) {
- /* patch up first and last txh's */
- brcms_c_ampdu_finalize(&session);
-
- while ((p = skb_dequeue(&session.skb_list)) != NULL)
- brcms_c_txfifo(wlc, fifo, p,
- skb_queue_empty(&session.skb_list));
- }
- /* endif (count) */
- return err;
-}
-
static void
brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
struct ieee80211_tx_info *tx_info,
@@ -1113,9 +986,16 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
/* either retransmit or send bar if ack not recd */
if (!ack_recd) {
if (retry && (ini->txretry[index] < (int)retry_limit)) {
+ int ret;
ini->txretry[index]++;
ini->tx_in_transit--;
- brcms_c_txq_enq(wlc, scb, p);
+ ret = brcms_c_txfifo(wlc, queue, p);
+ /*
+ * We shouldn't be out of space in the DMA
+ * ring here since we're reinserting a frame
+ * that was just pulled out.
+ */
+ WARN_ONCE(ret, "queue %d out of txds\n", queue);
} else {
/* Retry timeout */
ini->tx_in_transit--;
@@ -1142,12 +1022,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,

p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
}
- brcms_c_send_q(wlc);

/* update rate state */
antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
-
- brcms_c_txfifo_complete(wlc, queue);
}

void
@@ -1204,7 +1081,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
p = dma_getnexttxp(wlc->hw->di[queue],
DMA_RANGE_TRANSMITTED);
}
- brcms_c_txfifo_complete(wlc, queue);
}
}

@@ -1244,23 +1120,6 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
}

/*
- * callback function that helps flushing ampdu packets from a priority queue
- */
-static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
- struct cb_del_ampdu_pars *ampdu_pars =
- (struct cb_del_ampdu_pars *)arg_a;
- bool rc;
-
- rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
- rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL ||
- tx_info->rate_driver_data[0] == ampdu_pars->sta);
- rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
- return rc;
-}
-
-/*
* callback function that helps invalidating ampdu packets in a DMA queue
*/
static void dma_cb_fn_ampdu(void *txi, void *arg_a)
@@ -1280,15 +1139,5 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a)
void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
struct ieee80211_sta *sta, u16 tid)
{
- struct brcms_txq_info *qi = wlc->pkt_queue;
- struct pktq *pq = &qi->q;
- int prec;
- struct cb_del_ampdu_pars ampdu_pars;
-
- ampdu_pars.sta = sta;
- ampdu_pars.tid = tid;
- for (prec = 0; prec < pq->num_prec; prec++)
- brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
- (void *)&ampdu_pars);
brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
index 9a94923..73d01e5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
@@ -45,9 +45,6 @@ extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session);

extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
-extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
- struct brcms_txq_info *qi,
- struct sk_buff **aggp, int prec);
extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
struct sk_buff *p, struct tx_status *txs);
extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 6444cf1..426b9a9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -19,12 +19,17 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>

#include <brcmu_utils.h>
#include <aiutils.h>
#include "types.h"
+#include "main.h"
#include "dma.h"
#include "soc.h"
+#include "scb.h"
+#include "ampdu.h"

/*
* dma register field offset calculation
@@ -230,6 +235,9 @@ struct dma_info {
struct bcma_device *core;
struct device *dmadev;

+ /* session information for AMPDU */
+ struct brcms_ampdu_session ampdu_session;
+
bool dma64; /* this dma engine is operating in 64-bit mode */
bool addrext; /* this dma engine supports DmaExtendedAddrChanges */

@@ -564,12 +572,13 @@ static bool _dma_alloc(struct dma_info *di, uint direction)
return dma64_alloc(di, direction);
}

-struct dma_pub *dma_attach(char *name, struct si_pub *sih,
- struct bcma_device *core,
+struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
uint rxbufsize, int rxextheadroom,
uint nrxpost, uint rxoffset, uint *msg_level)
{
+ struct si_pub *sih = wlc->hw->sih;
+ struct bcma_device *core = wlc->hw->d11core;
struct dma_info *di;
u8 rev = core->id.rev;
uint size;
@@ -714,6 +723,9 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
}
}

+ /* Initialize AMPDU session */
+ brcms_c_ampdu_reset_session(&di->ampdu_session, wlc);
+
DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
di->ddoffsetlow, di->ddoffsethigh,
di->dataoffsetlow, di->dataoffsethigh,
@@ -1016,6 +1028,17 @@ static bool dma64_rxidle(struct dma_info *di)
D64_RS0_CD_MASK));
}

+static bool dma64_txidle(struct dma_info *di)
+{
+ if (di->ntxd == 0)
+ return true;
+
+ return ((bcma_read32(di->core,
+ DMA64TXREGOFFS(di, status0)) & D64_XS0_CD_MASK) ==
+ (bcma_read32(di->core, DMA64TXREGOFFS(di, ptr)) &
+ D64_XS0_CD_MASK));
+}
+
/*
* post receive buffers
* return false is refill failed completely and ring is empty this will stall
@@ -1264,50 +1287,25 @@ bool dma_rxreset(struct dma_pub *pub)
return status == D64_RS0_RS_DISABLED;
}

-/* Update count of available tx descriptors based on current DMA state */
-static void dma_update_txavail(struct dma_info *di)
+static void dma_txenq(struct dma_info *di, struct sk_buff *p)
{
- /*
- * Available space is number of descriptors less the number of
- * active descriptors and the number of queued AMPDU frames.
- */
- di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
-}
-
-
-/*
- * !! tx entry routine
- * WARNING: call must check the return value for error.
- * the error(toss frames) could be fatal and cause many subsequent hard
- * to debug problems
- */
-int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
-{
- struct dma_info *di = (struct dma_info *)pub;
unsigned char *data;
uint len;
u16 txout;
u32 flags = 0;
dma_addr_t pa;

- DMA_TRACE("%s:\n", di->name);
-
txout = di->txout;

+ if (WARN_ON(nexttxd(di, txout) == di->txin))
+ return;
+
/*
* obtain and initialize transmit descriptor entry.
*/
data = p->data;
len = p->len;

- /* no use to transmit a zero length packet */
- if (len == 0)
- return 0;
-
- /* return nonzero if out of tx descriptors */
- if (nexttxd(di, txout) == di->txin)
- goto outoftxd;
-
/* get physical address of buffer start */
pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);

@@ -1329,15 +1327,106 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)

/* bump the tx descriptor index */
di->txout = txout;
+}

- /* kick the chip */
- if (commit)
- bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
- di->xmtptrbase + I2B(txout, struct dma64desc));
+static void ampdu_finalize(struct dma_info *di)
+{
+ struct brcms_ampdu_session *session = &di->ampdu_session;
+ struct sk_buff *p;
+
+ if (WARN_ON(skb_queue_empty(&session->skb_list)))
+ return;
+
+ brcms_c_ampdu_finalize(session);
+
+ while (!skb_queue_empty(&session->skb_list)) {
+ p = skb_dequeue(&session->skb_list);
+ dma_txenq(di, p);
+ }
+
+ bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
+ di->xmtptrbase + I2B(di->txout, struct dma64desc));
+ brcms_c_ampdu_reset_session(session, session->wlc);
+}
+
+static void prep_ampdu_frame(struct dma_info *di, struct sk_buff *p)
+{
+ struct brcms_ampdu_session *session = &di->ampdu_session;
+ int ret;
+
+ ret = brcms_c_ampdu_add_frame(session, p);
+ if (ret == -ENOSPC) {
+ /*
+ * AMPDU cannot accomodate this frame. Close out the in-
+ * progress AMPDU session and start a new one.
+ */
+ ampdu_finalize(di);
+ ret = brcms_c_ampdu_add_frame(session, p);
+ }
+
+ WARN_ON(ret);
+}
+
+/* Update count of available tx descriptors based on current DMA state */
+static void dma_update_txavail(struct dma_info *di)
+{
+ /*
+ * Available space is number of descriptors less the number of
+ * active descriptors and the number of queued AMPDU frames.
+ */
+ di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) -
+ skb_queue_len(&di->ampdu_session.skb_list) - 1;
+}
+
+/*
+ * !! tx entry routine
+ * WARNING: call must check the return value for error.
+ * the error(toss frames) could be fatal and cause many subsequent hard
+ * to debug problems
+ */
+int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
+ struct sk_buff *p)
+{
+ struct dma_info *di = (struct dma_info *)pub;
+ struct brcms_ampdu_session *session = &di->ampdu_session;
+ struct ieee80211_tx_info *tx_info;
+ bool is_ampdu;
+
+ DMA_TRACE("%s:\n", di->name);
+
+ /* no use to transmit a zero length packet */
+ if (p->len == 0)
+ return 0;
+
+ /* return nonzero if out of tx descriptors */
+ if (di->dma.txavail == 0 || nexttxd(di, di->txout) == di->txin)
+ goto outoftxd;
+
+ tx_info = IEEE80211_SKB_CB(p);
+ is_ampdu = tx_info->flags & IEEE80211_TX_CTL_AMPDU;
+ if (is_ampdu)
+ prep_ampdu_frame(di, p);
+ else
+ dma_txenq(di, p);

/* tx flow control */
dma_update_txavail(di);

+ /* kick the chip */
+ if (is_ampdu) {
+ /*
+ * Start sending data if we've got a full AMPDU, there's
+ * no more space in the DMA ring, or the ring isn't
+ * currently transmitting.
+ */
+ if (skb_queue_len(&session->skb_list) == session->max_ampdu_frames ||
+ di->dma.txavail == 0 || dma64_txidle(di))
+ ampdu_finalize(di);
+ } else {
+ bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
+ di->xmtptrbase + I2B(di->txout, struct dma64desc));
+ }
+
return 0;

outoftxd:
@@ -1345,7 +1434,35 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
brcmu_pkt_buf_free_skb(p);
di->dma.txavail = 0;
di->dma.txnobuf++;
- return -1;
+ return -ENOSPC;
+}
+
+void dma_txflush(struct dma_pub *pub)
+{
+ struct dma_info *di = (struct dma_info *)pub;
+ struct brcms_ampdu_session *session = &di->ampdu_session;
+
+ if (!skb_queue_empty(&session->skb_list))
+ ampdu_finalize(di);
+}
+
+int dma_txpending(struct dma_pub *pub)
+{
+ struct dma_info *di = (struct dma_info *)pub;
+ return ntxdactive(di, di->txin, di->txout);
+}
+
+/*
+ * If we have an active AMPDU session and are not transmitting,
+ * this function will force tx to start.
+ */
+void dma_kick_tx(struct dma_pub *pub)
+{
+ struct dma_info *di = (struct dma_info *)pub;
+ struct brcms_ampdu_session *session = &di->ampdu_session;
+
+ if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di))
+ ampdu_finalize(di);
}

/*
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
index cc269ee..459abf1 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
@@ -74,8 +74,7 @@ struct dma_pub {
uint txnobuf; /* tx out of dma descriptors */
};

-extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
- struct bcma_device *d11core,
+extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc,
uint txregbase, uint rxregbase,
uint ntxd, uint nrxd,
uint rxbufsize, int rxextheadroom,
@@ -87,7 +86,11 @@ bool dma_rxfill(struct dma_pub *pub);
bool dma_rxreset(struct dma_pub *pub);
bool dma_txreset(struct dma_pub *pub);
void dma_txinit(struct dma_pub *pub);
-int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
+int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
+ struct sk_buff *p0);
+void dma_txflush(struct dma_pub *pub);
+int dma_txpending(struct dma_pub *pub);
+void dma_kick_tx(struct dma_pub *pub);
void dma_txsuspend(struct dma_pub *pub);
bool dma_txsuspended(struct dma_pub *pub);
void dma_txresume(struct dma_pub *pub);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 8abf39d..2b8987c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -34,6 +34,7 @@
#include "ucode_loader.h"
#include "main.h"
#include "soc.h"
+#include "dma.h"

/* watchdog timer, in unit of ms */
#define TIMER_INTERVAL_WATCHDOG 1000
@@ -236,12 +237,12 @@
/* Max # of entries in Rx FIFO based on 4kb page size */
#define NRXD 256

+/* Amount of headroom to leave in Tx FIFO */
+#define TX_HEADROOM 4
+
/* try to keep this # rbufs posted to the chip */
#define NRXBUFPOST 32

-/* data msg txq hiwat mark */
-#define BRCMS_DATAHIWAT 50
-
/* max # frames to process in brcms_c_recv() */
#define RXBND 8
/* max # tx status to process in wlc_txstatus() */
@@ -303,6 +304,18 @@ static const u8 wme_ac2fifo[] = {
TX_AC_BK_FIFO
};

+/* 802.1D Priority to precedence queue mapping */
+const u8 wlc_prio2prec_map[] = {
+ _BRCMS_PREC_BE, /* 0 BE - Best-effort */
+ _BRCMS_PREC_BK, /* 1 BK - Background */
+ _BRCMS_PREC_NONE, /* 2 None = - */
+ _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
+ _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
+ _BRCMS_PREC_VI, /* 5 Vi - Video */
+ _BRCMS_PREC_VO, /* 6 Vo - Voice */
+ _BRCMS_PREC_NC, /* 7 NC - Network Control */
+};
+
static const u16 xmtfifo_sz[][NFIFO] = {
/* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
{20, 192, 192, 21, 17, 5},
@@ -350,6 +363,14 @@ static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
[IEEE80211_AC_BK] = TX_AC_BK_FIFO,
};

+/* Mapping of tx fifos to ieee80211 AC numbers */
+static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = {
+ [TX_AC_BK_FIFO] = IEEE80211_AC_BK,
+ [TX_AC_BE_FIFO] = IEEE80211_AC_BE,
+ [TX_AC_VI_FIFO] = IEEE80211_AC_VI,
+ [TX_AC_VO_FIFO] = IEEE80211_AC_VO,
+};
+
static u8 brcms_ac_to_fifo(u8 ac)
{
if (ac >= ARRAY_SIZE(ac_to_fifo_mapping))
@@ -357,6 +378,13 @@ static u8 brcms_ac_to_fifo(u8 ac)
return ac_to_fifo_mapping[ac];
}

+static u8 brcms_fifo_to_ac(u8 fifo)
+{
+ if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping))
+ return IEEE80211_AC_BE;
+ return fifo_to_ac_mapping[fifo];
+}
+
/* Find basic rate for a given rate */
static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
{
@@ -401,10 +429,15 @@ static bool brcms_deviceremoved(struct brcms_c_info *wlc)
}

/* sum the individual fifo tx pending packet counts */
-static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
+static int brcms_txpktpendtot(struct brcms_c_info *wlc)
{
- return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
- wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
+ int i;
+ int pending = 0;
+
+ for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
+ if (wlc->hw->di[i])
+ pending += dma_txpending(wlc->hw->di[i]);
+ return pending;
}

static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
@@ -827,8 +860,9 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
static bool
brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
{
- struct sk_buff *p;
- uint queue;
+ struct sk_buff *p = NULL;
+ uint queue = NFIFO;
+ struct dma_pub *dma = NULL;
struct d11txh *txh;
struct scb *scb = NULL;
bool free_pdu;
@@ -840,6 +874,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *txrate;
int i;
+ bool fatal = true;

/* discard intermediate indications for ucode with one legitimate case:
* e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
@@ -849,18 +884,19 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
if (!(txs->status & TX_STATUS_AMPDU)
&& (txs->status & TX_STATUS_INTERMEDIATE)) {
BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
- return false;
+ fatal = false;
+ goto out;
}

queue = txs->frameid & TXFID_QUEUE_MASK;
- if (queue >= NFIFO) {
- p = NULL;
- goto fatal;
- }
+ if (queue >= NFIFO)
+ goto out;
+
+ dma = wlc->hw->di[queue];

p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
if (p == NULL)
- goto fatal;
+ goto out;

txh = (struct d11txh *) (p->data);
mcl = le16_to_cpu(txh->MacTxControlLow);
@@ -875,7 +911,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
}

if (txs->frameid != le16_to_cpu(txh->TxFrameID))
- goto fatal;
+ goto out;
tx_info = IEEE80211_SKB_CB(p);
h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);

@@ -884,7 +920,8 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)

if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
- return false;
+ fatal = false;
+ goto out;
}

supr_status = txs->status & TX_STATUS_SUPR_MASK;
@@ -968,8 +1005,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
totlen = p->len;
free_pdu = true;

- brcms_c_txfifo_complete(wlc, queue);
-
if (lastframe) {
/* remove PLCP & Broadcom tx descriptor header */
skb_pull(p, D11_PHY_HDR_LEN);
@@ -980,14 +1015,21 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
"tx_status\n", __func__);
}

- return false;
+ fatal = false;

- fatal:
- if (p)
+ out:
+ if (fatal && p)
brcmu_pkt_buf_free_skb(p);

- return true;
+ if (dma && queue < NFIFO) {
+ u16 ac_queue = brcms_fifo_to_ac(queue);
+ if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO &&
+ ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue))
+ ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue);
+ dma_kick_tx(dma);
+ }

+ return fatal;
}

/* process tx completion events in BMAC
@@ -1044,9 +1086,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
if (n >= max_tx_num)
morepending = true;

- if (!pktq_empty(&wlc->pkt_queue->q))
- brcms_c_send_q(wlc);
-
return morepending;
}

@@ -1111,7 +1150,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
* TX: TX_AC_BK_FIFO (TX AC Background data packets)
* RX: RX_FIFO (RX data packets)
*/
- wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
+ wlc_hw->di[0] = dma_attach(name, wlc,
(wme ? dmareg(DMA_TX, 0) : 0),
dmareg(DMA_RX, 0),
(wme ? NTXD : 0), NRXD,
@@ -1125,7 +1164,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
* (legacy) TX_DATA_FIFO (TX data packets)
* RX: UNUSED
*/
- wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
+ wlc_hw->di[1] = dma_attach(name, wlc,
dmareg(DMA_TX, 1), 0,
NTXD, 0, 0, -1, 0, 0,
&brcm_msg_level);
@@ -1136,7 +1175,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
* TX: TX_AC_VI_FIFO (TX AC Video data packets)
* RX: UNUSED
*/
- wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
+ wlc_hw->di[2] = dma_attach(name, wlc,
dmareg(DMA_TX, 2), 0,
NTXD, 0, 0, -1, 0, 0,
&brcm_msg_level);
@@ -1146,7 +1185,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
* TX: TX_AC_VO_FIFO (TX AC Voice data packets)
* (legacy) TX_CTL_FIFO (TX control & mgmt packets)
*/
- wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
+ wlc_hw->di[3] = dma_attach(name, wlc,
dmareg(DMA_TX, 3),
0, NTXD, 0, 0, -1,
0, 0, &brcm_msg_level);
@@ -2870,12 +2909,14 @@ static void brcms_c_flushqueues(struct brcms_c_info *wlc)
uint i;

/* free any posted tx packets */
- for (i = 0; i < NFIFO; i++)
+ for (i = 0; i < NFIFO; i++) {
if (wlc_hw->di[i]) {
dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
- wlc->core->txpktpend[i] = 0;
- BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
+ if (i < TX_BCMC_FIFO)
+ ieee80211_wake_queue(wlc->pub->ieee_hw,
+ brcms_fifo_to_ac(i));
}
+ }

/* free any posted rx packets */
dma_rxreclaim(wlc_hw->di[RX_FIFO]);
@@ -3738,15 +3779,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
return 0;
}

-/*
- * Initialize the base precedence map for dequeueing
- * from txq based on WME settings
- */
-static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
-{
- wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
-}
-
/* push sw hps and wake state through hardware */
static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
{
@@ -4797,56 +4829,6 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
bi->flags |= BRCMS_BSS_HT;
}

-static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
-{
- struct brcms_txq_info *qi, *p;
-
- qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
- if (qi != NULL) {
- /*
- * Have enough room for control packets along with HI watermark
- * Also, add room to txq for total psq packets if all the SCBs
- * leave PS mode. The watermark for flowcontrol to OS packets
- * will remain the same
- */
- brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
- 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
-
- /* add this queue to the the global list */
- p = wlc->tx_queues;
- if (p == NULL) {
- wlc->tx_queues = qi;
- } else {
- while (p->next != NULL)
- p = p->next;
- p->next = qi;
- }
- }
- return qi;
-}
-
-static void brcms_c_txq_free(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi)
-{
- struct brcms_txq_info *p;
-
- if (qi == NULL)
- return;
-
- /* remove the queue from the linked list */
- p = wlc->tx_queues;
- if (p == qi)
- wlc->tx_queues = p->next;
- else {
- while (p != NULL && p->next != qi)
- p = p->next;
- if (p != NULL)
- p->next = p->next->next;
- }
-
- kfree(qi);
-}
-
static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
{
uint i;
@@ -4966,10 +4948,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc)

brcms_c_detach_module(wlc);

-
- while (wlc->tx_queues != NULL)
- brcms_c_txq_free(wlc, wlc->tx_queues);
-
brcms_c_detach_mfree(wlc);
return callbacks;
}
@@ -5275,7 +5253,6 @@ uint brcms_c_down(struct brcms_c_info *wlc)
uint callbacks = 0;
int i;
bool dev_gone = false;
- struct brcms_txq_info *qi;

BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);

@@ -5314,10 +5291,6 @@ uint brcms_c_down(struct brcms_c_info *wlc)

wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);

- /* flush tx queues */
- for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
- brcmu_pktq_flush(&qi->q, true, NULL, NULL);
-
callbacks += brcms_b_down_finish(wlc->hw);

/* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
@@ -5991,85 +5964,6 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
}

-static bool
-brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
- struct sk_buff *pkt, int prec, bool head)
-{
- struct sk_buff *p;
- int eprec = -1; /* precedence to evict from */
-
- /* Determine precedence from which to evict packet, if any */
- if (pktq_pfull(q, prec))
- eprec = prec;
- else if (pktq_full(q)) {
- p = brcmu_pktq_peek_tail(q, &eprec);
- if (eprec > prec) {
- wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
- "\n", __func__, eprec, prec);
- return false;
- }
- }
-
- /* Evict if needed */
- if (eprec >= 0) {
- bool discard_oldest;
-
- discard_oldest = ac_bitmap_tst(0, eprec);
-
- /* Refuse newer packet unless configured to discard oldest */
- if (eprec == prec && !discard_oldest) {
- wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
- "\n", __func__, prec);
- return false;
- }
-
- /* Evict packet according to discard policy */
- p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
- brcmu_pktq_pdeq_tail(q, eprec);
- brcmu_pkt_buf_free_skb(p);
- }
-
- /* Enqueue */
- if (head)
- p = brcmu_pktq_penq_head(q, prec, pkt);
- else
- p = brcmu_pktq_penq(q, prec, pkt);
-
- return true;
-}
-
-/*
- * Attempts to queue a packet onto a multiple-precedence queue,
- * if necessary evicting a lower precedence packet from the queue.
- *
- * 'prec' is the precedence number that has already been mapped
- * from the packet priority.
- *
- * Returns true if packet consumed (queued), false if not.
- */
-static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
- struct sk_buff *pkt, int prec)
-{
- return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
-}
-
-void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
- struct sk_buff *sdu)
-{
- struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
- struct pktq *q = &qi->q;
- uint prec;
-
- prec = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
- if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
- /*
- * we might hit this condtion in case
- * packet flooding from mac80211 stack
- */
- brcmu_pkt_buf_free_skb(sdu);
- }
-}
-
/*
* bcmc_fid_generate:
* Generate frame ID for a BCMC packet. The frag field is not used
@@ -7230,70 +7124,33 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
return 0;
}

-void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
- struct ieee80211_hw *hw)
+static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
{
- uint fifo;
- struct scb *scb = &wlc->pri_scb;
-
- fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
- if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
- return;
- brcms_c_txq_enq(wlc, scb, sdu);
- brcms_c_send_q(wlc);
-}
-
-void brcms_c_send_q(struct brcms_c_info *wlc)
-{
- struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
- int prec;
- u16 prec_map;
- int err = 0, i, count;
- uint fifo;
- struct brcms_txq_info *qi = wlc->pkt_queue;
- struct pktq *q = &qi->q;
- struct ieee80211_tx_info *tx_info;
+ struct dma_pub *dma;
+ int fifo, ret = -ENOSPC;
+ struct d11txh *txh;
+ u16 frameid = INVALIDFID;

- prec_map = wlc->tx_prec_map;
+ fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb));
+ dma = wlc->hw->di[fifo];
+ txh = (struct d11txh *)(skb->data);

- /* Send all the enq'd pkts that we can.
- * Dequeue packets with precedence with empty HW fifo only
- */
- while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
- tx_info = IEEE80211_SKB_CB(pkt[0]);
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
- err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
- } else {
- count = 1;
- err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
- if (!err) {
- for (i = 0; i < count; i++)
- brcms_c_txfifo(wlc, fifo, pkt[i], true);
- }
- }
-
- if (err == -EBUSY) {
- brcmu_pktq_penq_head(q, prec, pkt[0]);
- /*
- * If send failed due to any other reason than a
- * change in HW FIFO condition, quit. Otherwise,
- * read the new prec_map!
- */
- if (prec_map == wlc->tx_prec_map)
- break;
- prec_map = wlc->tx_prec_map;
- }
+ if (dma->txavail == 0) {
+ /*
+ * We sometimes get a frame from mac80211 after stopping
+ * the queues. This only ever seems to be a single frame
+ * and is seems likely to be a race. TX_HEADROOM should
+ * ensure that we have enough space to handle these stray
+ * packets, so warn if there isn't. If we're out of space
+ * in the tx ring and the tx queue isn't stopped then
+ * we've really got a bug; warn loudly if that happens.
+ */
+ wiphy_warn(wlc->wiphy,
+ "Received frame for tx with no space in DMA ring\n");
+ WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw,
+ skb_get_queue_mapping(skb)));
+ return -ENOSPC;
}
-}
-
-void
-brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
- bool commit)
-{
- u16 frameid = INVALIDFID;
- struct d11txh *txh;
-
- txh = (struct d11txh *) (p->data);

/* When a BC/MC frame is being committed to the BCMC fifo
* via DMA (NOT PIO), update ucode or BSS info as appropriate.
@@ -7301,16 +7158,6 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
if (fifo == TX_BCMC_FIFO)
frameid = le16_to_cpu(txh->TxFrameID);

- /*
- * Bump up pending count for if not using rpc. If rpc is
- * used, this will be handled in brcms_b_txfifo()
- */
- if (commit) {
- wlc->core->txpktpend[fifo] += 1;
- BCMMSG(wlc->wiphy, "pktpend inc 1 to %d\n",
- wlc->core->txpktpend[fifo]);
- }
-
/* Commit BCMC sequence number in the SHM frame ID location */
if (frameid != INVALIDFID) {
/*
@@ -7320,8 +7167,52 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
}

- if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0)
+ ret = brcms_c_txfifo(wlc, fifo, skb);
+ /*
+ * The only reason for brcms_c_txfifo to fail is because
+ * there weren't any DMA descriptors, but we've already
+ * checked for that. So if it does fail yell loudly.
+ */
+ WARN_ON_ONCE(ret);
+
+ return ret;
+}
+
+void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
+ struct ieee80211_hw *hw)
+{
+ uint fifo;
+ struct scb *scb = &wlc->pri_scb;
+
+ fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
+ if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
+ return;
+ if (brcms_c_tx(wlc, sdu))
+ dev_kfree_skb_any(sdu);
+}
+
+int
+brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p)
+{
+ struct dma_pub *dma = wlc->hw->di[fifo];
+ int ret;
+ u16 queue;
+
+ ret = dma_txfast(wlc, dma, p);
+ if (ret < 0)
wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
+
+ /*
+ * Stop queue if DMA ring is full. Reserve some free descriptors,
+ * as we sometimes receive a frame from mac80211 after the queues
+ * are stopped.
+ */
+ queue = skb_get_queue_mapping(p);
+ if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO &&
+ !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue))
+ ieee80211_stop_queue(wlc->pub->ieee_hw, queue);
+
+ return ret;
}

u32
@@ -7371,19 +7262,6 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
return rts_rspec;
}

-void
-brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo)
-{
- wlc->core->txpktpend[fifo] -= 1;
- BCMMSG(wlc->wiphy, "pktpend dec 1 to %d\n",
- wlc->core->txpktpend[fifo]);
-
- /* There is more room; mark precedences related to this FIFO sendable */
- wlc->tx_prec_map |= 1 << fifo;
-
- /* figure out which bsscfg is being worked on... */
-}
-
/* Update beacon listen interval in shared memory */
static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
{
@@ -7831,35 +7709,6 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
}

-/* prepares pdu for transmission. returns BCM error codes */
-int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
-{
- uint fifo;
- struct d11txh *txh;
- struct ieee80211_hdr *h;
- struct scb *scb;
-
- txh = (struct d11txh *) (pdu->data);
- h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
-
- /* get the pkt queue info. This was put at brcms_c_sendctl or
- * brcms_c_send for PDU */
- fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
-
- scb = NULL;
-
- *fifop = fifo;
-
- /* return if insufficient dma resources */
- if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
- /* Mark precedences related to this FIFO, unsendable */
- /* A fifo is full. Clear precedences related to that FIFO */
- wlc->tx_prec_map &= ~(1 << fifo);
- return -EBUSY;
- }
- return 0;
-}
-
int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks)
{
@@ -7925,13 +7774,15 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
{
int timeout = 20;
+ int i;

- /* flush packet queue when requested */
- if (drop)
- brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
+ /* Kick DMA to send any pending AMPDU */
+ for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
+ if (wlc->hw->di[i])
+ dma_txflush(wlc->hw->di[i]);

/* wait for queue and DMA fifos to run dry */
- while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
+ while (brcms_txpktpendtot(wlc) > 0) {
brcms_msleep(wlc->wl, 1);

if (--timeout == 0)
@@ -8159,10 +8010,6 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
brcms_rfkill_set_hw_state(wlc->wl);
}

- /* send any enq'd tx packets. Just makes sure to jump start tx */
- if (!pktq_empty(&wlc->pkt_queue->q))
- brcms_c_send_q(wlc);
-
/* it isn't done and needs to be resched if macintstatus is non-zero */
return wlc->macintstatus != 0;

@@ -8234,9 +8081,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF);
brcms_c_edcf_setparams(wlc, false);

- /* Init precedence maps for empty FIFOs */
- brcms_c_tx_prec_map_init(wlc);
-
/* read the ucode version if we have not yet done so */
if (wlc->ucode_rev == 0) {
wlc->ucode_rev =
@@ -8409,15 +8253,6 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
* Complete the wlc default state initializations..
*/

- /* allocate our initial queue */
- wlc->pkt_queue = brcms_c_txq_alloc(wlc);
- if (wlc->pkt_queue == NULL) {
- wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
- unit, __func__);
- err = 100;
- goto fail;
- }
-
wlc->bsscfg->wlc = wlc;

wlc->mimoft = FT_HT;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 4e3af67..8a58cc1 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -239,7 +239,6 @@ struct brcms_core {

/* fifo */
uint *txavail[NFIFO]; /* # tx descriptors available */
- s16 txpktpend[NFIFO]; /* tx admission control */

struct macstat *macstat_snapshot; /* mac hw prev read values */
};
@@ -379,19 +378,6 @@ struct brcms_hardware {
*/
};

-/* TX Queue information
- *
- * Each flow of traffic out of the device has a TX Queue with independent
- * flow control. Several interfaces may be associated with a single TX Queue
- * if they belong to the same flow of traffic from the device. For multi-channel
- * operation there are independent TX Queues for each channel.
- */
-struct brcms_txq_info {
- struct brcms_txq_info *next;
- struct pktq q;
- uint stopped; /* tx flow control bits */
-};
-
/*
* Principal common driver data structure.
*
@@ -432,11 +418,8 @@ struct brcms_txq_info {
* WDlast: last time wlc_watchdog() was called.
* edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.
* wme_retries: per-AC retry limits.
- * tx_prec_map: Precedence map based on HW FIFO space.
- * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
* bsscfg: set of BSS configurations, idx 0 is default and always valid.
* cfg: the primary bsscfg (can be AP or STA).
- * tx_queues: common TX Queue list.
* modulecb:
* mimoft: SIGN or 11N.
* cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
@@ -466,7 +449,6 @@ struct brcms_txq_info {
* tempsense_lasttime;
* tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
* tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
- * pkt_queue: txq for transmit packets.
* wiphy:
* pri_scb: primary Station Control Block
*/
@@ -530,13 +512,9 @@ struct brcms_c_info {
u16 edcf_txop[IEEE80211_NUM_ACS];

u16 wme_retries[IEEE80211_NUM_ACS];
- u16 tx_prec_map;

struct brcms_bss_cfg *bsscfg;

- /* tx queue */
- struct brcms_txq_info *tx_queues;
-
struct modulecb *modulecb;

u8 mimoft;
@@ -581,7 +559,6 @@ struct brcms_c_info {
u16 tx_duty_cycle_ofdm;
u16 tx_duty_cycle_cck;

- struct brcms_txq_info *pkt_queue;
struct wiphy *wiphy;
struct scb pri_scb;
};
@@ -633,11 +610,8 @@ struct brcms_bss_cfg {
struct brcms_bss_info *current_bss;
};

-extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
- struct sk_buff *p, bool commit);
-extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo);
-extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
- struct sk_buff *sdu);
+extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
+ struct sk_buff *p);
extern void brcms_c_print_txstatus(struct tx_status *txs);
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks);
@@ -652,9 +626,6 @@ static inline void brcms_c_print_txdesc(struct d11txh *txh)

extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
-extern void brcms_c_send_q(struct brcms_c_info *wlc);
-extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
- uint *fifo);
extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
uint mac_len);
extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 40ccc69..0148dec 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -200,19 +200,6 @@ enum wlc_par_id {
/* WL11N Support */
#define AMPDU_AGG_HOST 1

-#define BRCMS_PREC_COUNT 4 /* Max precedence level implemented */
-
-/* Mask to describe all precedence levels */
-#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
-
-/*
- * This maps priority to one precedence higher - Used by PS-Poll response
- * packets to simulate enqueue-at-head operation, but still maintain the
- * order on the queue
- */
-#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
- BRCMS_PREC_COUNT - 1)
-
/* network protection config */
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
index e11ae83..e3abc0e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -281,7 +281,6 @@ struct ieee80211_tx_queue_params;
struct brcms_info;
struct brcms_c_info;
struct brcms_hardware;
-struct brcms_txq_info;
struct brcms_band;
struct dma_pub;
struct si_pub;
--
1.7.9.5


2012-11-16 08:37:28

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 01/22] brcmsmac: Introduce AMPDU sessions for assembling AMPDUs

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> AMPDU session allows MPDUs to be temporarily queued until either a full
> AMPDU has been collected or circumstances dictate that transmission
> should start with a partial AMPDU. Packets are added to the session by

I started reviewing this and reading this commit message got me
wondering about the .flush() problems. I realized the flush would be a
"circumstance" to start transmission of a partial AMPDU, but I am pretty
sure it currently is not treated as such.

Regards,
Arend

> calling brcms_c_ampdu_add_frame(). brcms_c_ampdu_finalize() should be
> called to fix up the tx headers in the first and last packet before
> adding the packets to the DMA ring. brmcs_c_sendampdu() is converted to
> using AMPDU sessions.
>
> This patch has no real value on it's own, but is needed in preparation
> for elimination of the tx packet queue from brcmsmac.
>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 625 +++++++++++++----------
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 26 +
> 2 files changed, 377 insertions(+), 274 deletions(-)



2012-11-19 20:38:36

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 17/22] brcmsmac: Add brcms_dbg_dma() debug macro

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> Also convert relevant messages to use this macro.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 1 +
> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 155 ++++++++++-------------
> drivers/net/wireless/brcm80211/brcmsmac/dma.h | 2 +-
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 10 +-
> drivers/net/wireless/brcm80211/include/defs.h | 1 +
> 5 files changed, 73 insertions(+), 96 deletions(-)




2012-11-15 14:08:19

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 02/22] brcmsmac: Don't weight AMPDU packets in txfifo

According to the comments this "reduces rate lag," but in reality the
only way this value is used is for determining whether or not any frames
remain to be transmitted. Therefore there's no reason for AMPDU packets
to receive any weighting.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 12 +++---------
drivers/net/wireless/brcm80211/brcmsmac/main.c | 19 +++++++++----------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 6 ++----
3 files changed, 14 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 5739534..ea84087 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -40,8 +40,6 @@
#define AMPDU_DEF_RETRY_LIMIT 5
/* default tx retry limit at reg rate */
#define AMPDU_DEF_RR_RETRY_LIMIT 2
-/* default weight of ampdu in txfifo */
-#define AMPDU_DEF_TXPKT_WEIGHT 2
/* default ffpld reserved bytes */
#define AMPDU_DEF_FFPLD_RSVD 2048
/* # of inis to be freed on detach */
@@ -114,7 +112,6 @@ struct brcms_fifo_info {
* mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
* max_pdu: max pdus allowed in ampdu
* dur: max duration of an ampdu (in msec)
- * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
* rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
* ffpld_rsvd: number of bytes to reserve for preload
* max_txlen: max size of ampdu per mcs, bw and sgi
@@ -136,7 +133,6 @@ struct ampdu_info {
u8 mpdu_density;
s8 max_pdu;
u8 dur;
- u8 txpkt_weight;
u8 rx_factor;
u32 ffpld_rsvd;
u32 max_txlen[MCS_TABLE_SIZE][2][2];
@@ -247,7 +243,6 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
ampdu->max_pdu = AUTO;
ampdu->dur = AMPDU_MAX_DUR;
- ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;

ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
/*
@@ -942,8 +937,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,

while ((p = skb_dequeue(&session.skb_list)) != NULL)
brcms_c_txfifo(wlc, fifo, p,
- skb_queue_empty(&session.skb_list),
- ampdu->txpkt_weight);
+ skb_queue_empty(&session.skb_list));
}
/* endif (count) */
return err;
@@ -1162,7 +1156,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
/* update rate state */
antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);

- brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+ brcms_c_txfifo_complete(wlc, queue);
}

void
@@ -1219,7 +1213,7 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
p = dma_getnexttxp(wlc->hw->di[queue],
DMA_RANGE_TRANSMITTED);
}
- brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+ brcms_c_txfifo_complete(wlc, queue);
}
}

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 75086b3..e4ef457 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -982,7 +982,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
totlen = p->len;
free_pdu = true;

- brcms_c_txfifo_complete(wlc, queue, 1);
+ brcms_c_txfifo_complete(wlc, queue);

if (lastframe) {
/* remove PLCP & Broadcom tx descriptor header */
@@ -7319,8 +7319,7 @@ void brcms_c_send_q(struct brcms_c_info *wlc)
err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
if (!err) {
for (i = 0; i < count; i++)
- brcms_c_txfifo(wlc, fifo, pkt[i], true,
- 1);
+ brcms_c_txfifo(wlc, fifo, pkt[i], true);
}
}

@@ -7340,7 +7339,7 @@ void brcms_c_send_q(struct brcms_c_info *wlc)

void
brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
- bool commit, s8 txpktpend)
+ bool commit)
{
u16 frameid = INVALIDFID;
struct d11txh *txh;
@@ -7358,9 +7357,9 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
* used, this will be handled in brcms_b_txfifo()
*/
if (commit) {
- wlc->core->txpktpend[fifo] += txpktpend;
- BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
- txpktpend, wlc->core->txpktpend[fifo]);
+ wlc->core->txpktpend[fifo] += 1;
+ BCMMSG(wlc->wiphy, "pktpend inc 1 to %d\n",
+ wlc->core->txpktpend[fifo]);
}

/* Commit BCMC sequence number in the SHM frame ID location */
@@ -7424,10 +7423,10 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
}

void
-brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
+brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo)
{
- wlc->core->txpktpend[fifo] -= txpktpend;
- BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
+ wlc->core->txpktpend[fifo] -= 1;
+ BCMMSG(wlc->wiphy, "pktpend dec 1 to %d\n",
wlc->core->txpktpend[fifo]);

/* There is more room; mark precedences related to this FIFO sendable */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 8debc74..0ab7d36 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -638,10 +638,8 @@ struct brcms_bss_cfg {
};

extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
- struct sk_buff *p,
- bool commit, s8 txpktpend);
-extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
- s8 txpktpend);
+ struct sk_buff *p, bool commit);
+extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo);
extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
struct sk_buff *sdu, uint prec);
extern void brcms_c_print_txstatus(struct tx_status *txs);
--
1.7.9.5


2012-11-20 07:30:12

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Seth,

On 19.11.2012 20:11, Daniel Wagner wrote:
> Works perfectly fine on my machine.

Well, not really true. Though I am not sure if this what I am seeing
related to your changes. I see following log only when I am using my
home AP. The pattern is that when the connection stop working I see
something like this in the log:

[ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
[ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
[ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68 tid 0
[ 8735.573701] wlan0: activated addBA response timer on tid 0
[ 8735.578826] wlan0: switched off addBA timer for tid 0
[ 8735.578834] wlan0: Aggregation is on for tid 0
[ 8749.687530] wlan0: tx session timer expired on tid 0
[ 8749.687558] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
[ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0


This is what I do: First establishing a connection, then after a while any
traffic seems stops for a period and sometimes it recovers from that point. If
not a disconnect/connect (using ConnMan) dance fixes the problem.

Here some more logs with the reconnect dance.

[ 8726.077111] wlan0: deauthenticating from 1c:c6:3c:1f:50:68 by local choice (reason=3)
[ 8726.077147] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
[ 8726.078819] wlan0: Rx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0 recipient reason: 36
[ 8726.078824] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0
[ 8726.080882] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 3
[ 8726.080892] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 2
[ 8726.080899] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 1
[ 8726.080904] wlan0: Removed STA 1c:c6:3c:1f:50:68
[ 8726.081038] brcmsmac bcma0:0: brcmsmac: brcms_ops_bss_info_changed: disassociated
[ 8726.081061] brcmsmac bcma0:0: brcms_ops_bss_info_changed: arp filtering: enabled false, count 1 (implement)
[ 8726.081069] brcmsmac bcma0:0: brcms_ops_bss_info_changed: qos enabled: false (implement)
[ 8726.083399] cfg80211: Calling CRDA to update world regulatory domain
[ 8726.087764] wlan0: Destroyed STA 1c:c6:3c:1f:50:68
[ 8726.094448] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[ 8726.110106] cfg80211: World regulatory domain updated:
[ 8726.110116] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[ 8726.110123] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[ 8726.110130] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[ 8726.110135] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[ 8726.110141] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[ 8726.110145] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[ 8726.110192] cfg80211: Calling CRDA for country: DE
[ 8726.122480] cfg80211: Regulatory domain changed to country: DE
[ 8726.122490] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[ 8726.122496] cfg80211: (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 8726.122502] cfg80211: (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 8726.122508] cfg80211: (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 8726.122513] cfg80211: (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)
[ 8727.076039] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[ 8735.043286] wlan0: authenticate with 1c:c6:3c:1f:50:68
[ 8735.043307] wlan0: Allocated STA 1c:c6:3c:1f:50:68
[ 8735.049752] wlan0: Inserted STA 1c:c6:3c:1f:50:68
[ 8735.049761] wlan0: send auth to 1c:c6:3c:1f:50:68 (try 1/3)
[ 8735.057482] wlan0: authenticated
[ 8735.057497] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 2
[ 8735.058281] wlan0: associate with 1c:c6:3c:1f:50:68 (try 1/3)
[ 8735.114690] wlan0: RX AssocResp from 1c:c6:3c:1f:50:68 (capab=0x431 status=0 aid=3)
[ 8735.114709] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 3
[ 8735.114717] wlan0: WMM queue=2 aci=0 acm=0 aifs=3 cWmin=15 cWmax=1023 txop=0 uapsd=0
[ 8735.114844] wlan0: WMM queue=3 aci=1 acm=0 aifs=7 cWmin=15 cWmax=1023 txop=0 uapsd=0
[ 8735.114965] wlan0: WMM queue=1 aci=2 acm=0 aifs=2 cWmin=7 cWmax=15 txop=94 uapsd=0
[ 8735.115087] wlan0: WMM queue=0 aci=3 acm=0 aifs=2 cWmin=3 cWmax=7 txop=47 uapsd=0
[ 8735.115301] brcmsmac bcma0:0: brcmsmac: brcms_ops_bss_info_changed: associated
[ 8735.115321] brcmsmac bcma0:0: brcms_ops_bss_info_changed: arp filtering: enabled true, count 0 (implement)
[ 8735.115334] brcmsmac bcma0:0: brcms_ops_bss_info_changed: qos enabled: true (implement)
[ 8735.115361] wlan0: associated
[ 8735.116132] cfg80211: Calling CRDA for country: DE
[ 8735.116218] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[ 8735.118204] wlan0: dropped frame to 1c:c6:3c:1f:50:68 (unauthorized port)
[ 8735.120665] cfg80211: Regulatory domain changed to country: DE
[ 8735.120672] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[ 8735.120678] cfg80211: (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 8735.120682] cfg80211: (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 8735.120687] cfg80211: (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 8735.120692] cfg80211: (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)
[ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
[ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
[ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68 tid 0
[ 8735.573701] wlan0: activated addBA response timer on tid 0
[ 8735.578826] wlan0: switched off addBA timer for tid 0
[ 8735.578834] wlan0: Aggregation is on for tid 0
[ 8749.687530] wlan0: tx session timer expired on tid 0
[ 8749.687558] wlan0: Tx BA session stop requested for 1c:c6:3c:1f:50:68 tid 0
[ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68 tid 0


cheers,
daniel

2012-11-15 14:08:21

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 03/22] brcmsmac: Add helper function for updating txavail count

Use this helper function rather than open-coding the same calculation in
multiple places.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 5e53305..6444cf1 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -1264,6 +1264,17 @@ bool dma_rxreset(struct dma_pub *pub)
return status == D64_RS0_RS_DISABLED;
}

+/* Update count of available tx descriptors based on current DMA state */
+static void dma_update_txavail(struct dma_info *di)
+{
+ /*
+ * Available space is number of descriptors less the number of
+ * active descriptors and the number of queued AMPDU frames.
+ */
+ di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
+}
+
+
/*
* !! tx entry routine
* WARNING: call must check the return value for error.
@@ -1325,7 +1336,7 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
di->xmtptrbase + I2B(txout, struct dma64desc));

/* tx flow control */
- di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
+ dma_update_txavail(di);

return 0;

@@ -1412,7 +1423,7 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
di->txin = i;

/* tx flow control */
- di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
+ dma_update_txavail(di);

return txp;

--
1.7.9.5


2012-11-15 14:08:40

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 12/22] brcmsmac: Add support for writing debug messages to the trace buffer

Add a new brcmsmac_msg trace system to enable writing of debug messages
to the trace buffer, and add brcms_* macros for storing device debug
messages in the trace buffer in addition to the printk log buffer.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/Makefile | 3 +-
.../brcm80211/brcmsmac/brcms_trace_events.h | 68 +++++++++++++++++++-
drivers/net/wireless/brcm80211/brcmsmac/debug.c | 44 +++++++++++++
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 40 ++++++++++++
4 files changed, 151 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.c
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.h

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index e227c4c..d3d4151 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -40,7 +40,8 @@ BRCMSMAC_OFILES := \
phy/phytbl_n.o \
phy/phy_qmath.o \
dma.o \
- brcms_trace_events.o
+ brcms_trace_events.o \
+ debug.o

MODULEPFX := brcmsmac

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index bcf6969..a9aed1f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -14,9 +14,6 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM brcmsmac
-
#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)

#define __TRACE_BRCMSMAC_H
@@ -28,8 +25,16 @@
#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {}
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(...)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
+static inline void trace_ ## name(proto) {}
#endif

+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM brcmsmac
+
/*
* We define a tracepoint, its arguments, its printk format and its
* 'fast binary record' layout.
@@ -78,6 +83,63 @@ TRACE_EVENT(brcms_dpc,
)
);

+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM brcmsmac_msg
+
+#define MAX_MSG_LEN 100
+
+DECLARE_EVENT_CLASS(brcms_msg_event,
+ TP_PROTO(struct va_format *vaf),
+ TP_ARGS(vaf),
+ TP_STRUCT__entry(
+ __dynamic_array(char, msg, MAX_MSG_LEN)
+ ),
+ TP_fast_assign(
+ WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+ MAX_MSG_LEN, vaf->fmt,
+ *vaf->va) >= MAX_MSG_LEN);
+ ),
+ TP_printk("%s", __get_str(msg))
+);
+
+DEFINE_EVENT(brcms_msg_event, brcms_info,
+ TP_PROTO(struct va_format *vaf),
+ TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(brcms_msg_event, brcms_warn,
+ TP_PROTO(struct va_format *vaf),
+ TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(brcms_msg_event, brcms_err,
+ TP_PROTO(struct va_format *vaf),
+ TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(brcms_msg_event, brcms_crit,
+ TP_PROTO(struct va_format *vaf),
+ TP_ARGS(vaf)
+);
+
+TRACE_EVENT(brcms_dbg,
+ TP_PROTO(u32 level, const char *func, struct va_format *vaf),
+ TP_ARGS(level, func, vaf),
+ TP_STRUCT__entry(
+ __field(u32, level)
+ __string(func, func)
+ __dynamic_array(char, msg, MAX_MSG_LEN)
+ ),
+ TP_fast_assign(
+ __entry->level = level;
+ __assign_str(func, func);
+ WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+ MAX_MSG_LEN, vaf->fmt,
+ *vaf->va) >= MAX_MSG_LEN);
+ ),
+ TP_printk("%s: %s", __get_str(func), __get_str(msg))
+);
+
#endif /* __TRACE_BRCMSMAC_H */

#ifdef CONFIG_BRCM_TRACING
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
new file mode 100644
index 0000000..6ba4136
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
@@ -0,0 +1,44 @@
+#include <linux/net.h>
+#include "types.h"
+#include "debug.h"
+#include "brcms_trace_events.h"
+
+#define __brcms_fn(fn) \
+void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
+{ \
+ struct va_format vaf = { \
+ .fmt = fmt, \
+ }; \
+ va_list args; \
+ \
+ va_start(args, fmt); \
+ vaf.va = &args; \
+ dev_ ##fn(dev, "%pV", &vaf); \
+ trace_brcms_ ##fn(&vaf); \
+ va_end(args); \
+}
+
+__brcms_fn(info)
+__brcms_fn(warn)
+__brcms_fn(err)
+__brcms_fn(crit)
+
+#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
+void __brcms_dbg(struct device *dev, u32 level, const char *func,
+ const char *fmt, ...)
+{
+ struct va_format vaf = {
+ .fmt = fmt,
+ };
+ va_list args;
+
+ va_start(args, fmt);
+ vaf.va = &args;
+#ifdef CONFIG_BRCMDBG
+ if ((brcm_msg_level & level) && net_ratelimit())
+ dev_err(dev, "%s %pV", func, &vaf);
+#endif
+ trace_brcms_dbg(level, func, &vaf);
+ va_end(args);
+}
+#endif
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
new file mode 100644
index 0000000..6f2fe3b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -0,0 +1,40 @@
+#ifndef _BRCMS_DEBUG_H_
+#define _BRCMS_DEBUG_H_
+
+#include <linux/device.h>
+#include <linux/bcma/bcma.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include "main.h"
+#include "mac80211_if.h"
+
+void __brcms_info(struct device *dev, const char *fmt, ...);
+void __brcms_warn(struct device *dev, const char *fmt, ...);
+void __brcms_err(struct device *dev, const char *fmt, ...);
+void __brcms_crit(struct device *dev, const char *fmt, ...);
+
+#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
+void __brcms_dbg(struct device *dev, u32 level, const char *func,
+ const char *fmt, ...);
+#else
+static inline void __brcms_dbg(struct device *dev, u32 level,
+ const char *func, const char *fmt, ...)
+{
+}
+#endif
+
+/*
+ * Debug macros cannot be used when wlc is uninitialized. Generally
+ * this means any code that could run before brcms_c_attach() has
+ * returned successfully probably shouldn't use the following macros.
+ */
+
+#define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a)
+#define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a)
+#define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a)
+#define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a)
+#define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a)
+
+#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a)
+
+#endif /* _BRCMS_DEBUG_H_ */
--
1.7.9.5


2012-11-19 21:15:18

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 09/22] brcm80211: Allow trace support to be enabled separately from debug

On Mon, Nov 19, 2012 at 09:33:13PM +0100, Arend van Spriel wrote:
> On 11/15/2012 03:07 PM, Seth Forshee wrote:
> >Since the runtime overhead of trace support is small when tracing is
> >disabled, users may be interested in turning on trace support while
> >leaving other debug features off. Add a new config option named
> >CONFIG_BRCM_TRACING for this purpose.
>
> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
> Reviewed-by: Arend van Spriel
> >Signed-off-by: Seth Forshee <[email protected]>
> >---
> > drivers/net/wireless/brcm80211/Kconfig | 11 +++++++++++
> > .../brcm80211/brcmsmac/brcms_trace_events.h | 6 +++---
> > 2 files changed, 14 insertions(+), 3 deletions(-)
> >
> >diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
> >index c9d811e..3735c27 100644
> >--- a/drivers/net/wireless/brcm80211/Kconfig
> >+++ b/drivers/net/wireless/brcm80211/Kconfig
> >@@ -63,6 +63,17 @@ config BRCMISCAN
> > new E-Scan method which uses less memory in firmware and gives no
> > limitation on the number of scan results.
> >
> >+config BRCM_TRACING
> >+ bool "Broadcom device tracing"
> >+ depends on BRCMSMAC || BRCMFMAC
> >+ ---help---
> >+ If you say Y here, the Broadcom wireless drivers will register
> >+ with ftrace to dump event information into the trace ringbuffer.
> >+ Tracing can be enabled at runtime to aid in debugging wireless
> >+ issues. This option adds a small amount of overhead when tracing
> >+ is disabled. If unsure, say Y to allow developers to better help
> >+ you when wireless problems occur.
> >+
>
> I regard this as a debugging feature. Did you consider making it
> depend on BRCMDBG instead? Or do you think that BRCMDBG code would
> affect run-time behavior during tracing.

It is a debugging feature, but making it depend on BRCMDBG prevents my
intended use case. I'm planning to enable BRCM_TRACING in Ubuntu and to
leave BRCMDBG disabled. This will make it easy for us to ask users for
detailed debug information when needed with minimal overhead during
normal use.

Seth


2012-11-19 20:36:00

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 12/22] brcmsmac: Add support for writing debug messages to the trace buffer

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> Add a new brcmsmac_msg trace system to enable writing of debug messages
> to the trace buffer, and add brcms_* macros for storing device debug
> messages in the trace buffer in addition to the printk log buffer.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/Makefile | 3 +-
> .../brcm80211/brcmsmac/brcms_trace_events.h | 68 +++++++++++++++++++-
> drivers/net/wireless/brcm80211/brcmsmac/debug.c | 44 +++++++++++++
> drivers/net/wireless/brcm80211/brcmsmac/debug.h | 40 ++++++++++++
> 4 files changed, 151 insertions(+), 4 deletions(-)
> create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.c
> create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/debug.h




2012-11-21 09:44:59

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 11/20/2012 11:45 PM, Daniel Wagner wrote:
>>
>> I am currently not able to reproduce a complete loss of connectivity.
>
> I fear it is a heisenbug. After turning the tracing off I was able to
> reproduce it very easily.

That is too bad. I always wondered about the tracing overhead affecting
reproducibility. So the trace that you uploaded was not showing the
issue of connection loss you are having?

Gr. AvS


2012-11-19 20:35:30

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 11/22] brcmsmac: Add module parameter for setting the debug level

On 11/15/2012 03:08 PM, Seth Forshee wrote:
> The debug level can be set by passing debug=... to brcmsmac whenever
> CONFIG_BRCMDBG is enabled.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 16 ++++++++--------
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 7 +------
> 2 files changed, 9 insertions(+), 14 deletions(-)



2012-11-15 14:08:49

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 16/22] brcmsmac: Add brcms_dbg_int() debug macro

Also convert relevant message to use this macro.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/debug.h | 1 +
drivers/net/wireless/brcm80211/brcmsmac/main.c | 12 ++++++------
drivers/net/wireless/brcm80211/include/defs.h | 1 +
3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
index b979128..1114833 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -39,5 +39,6 @@ static inline void __brcms_dbg(struct device *dev, u32 level,
#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a)
#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a)
#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a)
+#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a)

#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index d6df923..54fa177 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -2343,8 +2343,8 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
if (!intstatus)
continue;

- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
- unit, idx, intstatus);
+ brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n",
+ unit, idx, intstatus);

if (intstatus & I_RO) {
brcms_err(core, "wl%d: fifo %d: receive fifo "
@@ -2541,8 +2541,8 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
/* macintstatus includes a DMA interrupt summary bit */
macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));

- BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
- macintstatus);
+ brcms_dbg_int(core, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
+ macintstatus);

/* detect cardbus removed, in power down(suspend) and in reset */
if (brcms_deviceremoved(wlc))
@@ -7950,8 +7950,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
macintstatus = wlc->macintstatus;
wlc->macintstatus = 0;

- BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
- wlc_hw->unit, macintstatus);
+ brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n",
+ wlc_hw->unit, macintstatus);

WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */

diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index 9206d2c..12dd33f 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -83,6 +83,7 @@
#define BRCM_DL_MAC80211 0x00000002
#define BRCM_DL_RX 0x00000004
#define BRCM_DL_TX 0x00000008
+#define BRCM_DL_INT 0x00000010

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-11-21 14:35:33

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Wed, Nov 21, 2012 at 10:56:47AM +0100, Daniel Wagner wrote:
> On 21.11.2012 10:44, Arend van Spriel wrote:
> > On 11/20/2012 11:45 PM, Daniel Wagner wrote:
> >>>
> >>> I am currently not able to reproduce a complete loss of connectivity.
> >>
> >> I fear it is a heisenbug. After turning the tracing off I was able to
> >> reproduce it very easily.

Just to clarify, you see the issue using the same kernel but without
trace-cmd running? If so you might try disabling the brcmsmac_tx
tracepoing, which probably adds the most overhead, and see if you can
reproduce the problem. It obviously won't give as much information but
maybe it will still provide some clues.

> > That is too bad. I always wondered about the tracing overhead affecting
> > reproducibility. So the trace that you uploaded was not showing the
> > issue of connection loss you are having?
>
> The trace does only show that the throughput goes considerable down and the
> download might even stop shortly but overall the system recovers again.
>
> Well, to add some random observation here, I think I see the same pattern
> when using MacOS (yeah, sorry, dual boot). With MacOS the link is usable but
> the throughput sometimes really goes down and recovers then. Obviously, this
> could also be something else, I tried it with an pretty old AP which only
> support 11g. Using the 11g AP didn't show this behavior.
>
> My 'test' setup is following: I downloaded a larger file and let a youtube
> video play. With tracing enabled the download and the playback did work nicely.
>
> Without tracing enabled playing back only a youtube video was 'triggering'
> the problem. It downloads a few seconds of content in a burst and then the playback
> starts. Under normal conditions, the app will continue downloading the video at a
> lower rate. But this normally doesn't happen right now. Often it will just stop
> working and often the connection is completely blocked, e.g. pinging a host
> wont work.

I'll see if I can reproduce, but if it's specific to the AP then I may
not have any luck. Don't expect to hear much from me until next week
though; I'm on holiday starting today and will be visiting family.

Seth

2012-11-15 14:08:25

by Seth Forshee

[permalink] [raw]
Subject: [PATCH v2 05/22] brcmsmac: Use IEEE 802.11 AC levels for pktq precedence levels

The mac80211 tx queues and brcmsmac DMA fifos both map directly to AC
levels. Therefore it's much more straightforward to queue tx frames and
choose the tx fifo based on the mac80211 queue instead of mapping 802.1D
priority tags to precedence levels then back to AC levels. mac80211
already maps the 802.1D levels to the appropriate AC levels and queues
management frames at the maximum priority, so the results should be
identical.

One functional change resulting from this patch is that AMPDU retries no
longer get a priority boost to queue them ahead of packets with the same
priority already in the tx queue. This behavior will be restored (in
effect at least) in a later patch when the tx queue is removed.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 13 +----
drivers/net/wireless/brcm80211/brcmsmac/main.c | 67 ++++++++---------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 6 +-
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 26 +--------
4 files changed, 26 insertions(+), 86 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index ea84087..0b4a490 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -827,7 +827,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
struct scb *scb;
struct scb_ampdu *scb_ampdu;
struct scb_ampdu_tid_ini *ini;
- struct brcms_fifo_info *f;
struct ieee80211_tx_info *tx_info;
u16 qlen;
struct wiphy *wiphy;
@@ -838,8 +837,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,

tid = (u8) (p->priority);

- f = ampdu->fifo_tb + prio2fifo[tid];
-
scb = &wlc->pri_scb;
scb_ampdu = &scb->scb_ampdu;
ini = &scb_ampdu->ini[tid];
@@ -1048,8 +1045,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
* if there were underflows, but pre-loading
* is not active, notify rate adaptation.
*/
- if (brcms_c_ffpld_check_txfunfl(wlc,
- prio2fifo[tid]) > 0)
+ if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0)
tx_error = true;
}
} else if (txs->phyerr) {
@@ -1119,12 +1115,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
if (retry && (ini->txretry[index] < (int)retry_limit)) {
ini->txretry[index]++;
ini->tx_in_transit--;
- /*
- * Use high prededence for retransmit to
- * give some punch
- */
- brcms_c_txq_enq(wlc, scb, p,
- BRCMS_PRIO_TO_HI_PREC(tid));
+ brcms_c_txq_enq(wlc, scb, p);
} else {
/* Retry timeout */
ini->tx_in_transit--;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 135af9a..8abf39d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -277,17 +277,6 @@ struct edcf_acparam {
u16 TXOP;
} __packed;

-const u8 prio2fifo[NUMPRIO] = {
- TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */
- TX_AC_BK_FIFO, /* 1 BK AC_BK Background */
- TX_AC_BK_FIFO, /* 2 -- AC_BK Background */
- TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */
- TX_AC_VI_FIFO, /* 4 CL AC_VI Video */
- TX_AC_VI_FIFO, /* 5 VI AC_VI Video */
- TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */
- TX_AC_VO_FIFO /* 7 NC AC_VO Voice */
-};
-
/* debug/trace */
uint brcm_msg_level =
#if defined(DEBUG)
@@ -314,18 +303,6 @@ static const u8 wme_ac2fifo[] = {
TX_AC_BK_FIFO
};

-/* 802.1D Priority to precedence queue mapping */
-const u8 wlc_prio2prec_map[] = {
- _BRCMS_PREC_BE, /* 0 BE - Best-effort */
- _BRCMS_PREC_BK, /* 1 BK - Background */
- _BRCMS_PREC_NONE, /* 2 None = - */
- _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
- _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
- _BRCMS_PREC_VI, /* 5 Vi - Video */
- _BRCMS_PREC_VO, /* 6 Vo - Voice */
- _BRCMS_PREC_NC, /* 7 NC - Network Control */
-};
-
static const u16 xmtfifo_sz[][NFIFO] = {
/* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
{20, 192, 192, 21, 17, 5},
@@ -365,6 +342,21 @@ static const char fifo_names[6][0];
static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
#endif

+/* Mapping of ieee80211 AC numbers to tx fifos */
+static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
+ [IEEE80211_AC_VO] = TX_AC_VO_FIFO,
+ [IEEE80211_AC_VI] = TX_AC_VI_FIFO,
+ [IEEE80211_AC_BE] = TX_AC_BE_FIFO,
+ [IEEE80211_AC_BK] = TX_AC_BK_FIFO,
+};
+
+static u8 brcms_ac_to_fifo(u8 ac)
+{
+ if (ac >= ARRAY_SIZE(ac_to_fifo_mapping))
+ return TX_AC_BE_FIFO;
+ return ac_to_fifo_mapping[ac];
+}
+
/* Find basic rate for a given rate */
static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
{
@@ -3753,12 +3745,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
{
wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
- memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
-
- wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
- wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
- wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
- wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
}

/* push sw hps and wake state through hardware */
@@ -6068,14 +6054,13 @@ static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
}

void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
- struct sk_buff *sdu, uint prec)
+ struct sk_buff *sdu)
{
struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
struct pktq *q = &qi->q;
- int prio;
-
- prio = sdu->priority;
+ uint prec;

+ prec = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
/*
* we might hit this condtion in case
@@ -7248,21 +7233,13 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
struct ieee80211_hw *hw)
{
- u8 prio;
uint fifo;
struct scb *scb = &wlc->pri_scb;
- struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);

- /*
- * 802.11 standard requires management traffic
- * to go at highest priority
- */
- prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
- MAXPRIO;
- fifo = prio2fifo[prio];
+ fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
return;
- brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
+ brcms_c_txq_enq(wlc, scb, sdu);
brcms_c_send_q(wlc);
}

@@ -7402,7 +7379,7 @@ brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo)
wlc->core->txpktpend[fifo]);

/* There is more room; mark precedences related to this FIFO sendable */
- wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
+ wlc->tx_prec_map |= 1 << fifo;

/* figure out which bsscfg is being worked on... */
}
@@ -7877,7 +7854,7 @@ int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
/* Mark precedences related to this FIFO, unsendable */
/* A fifo is full. Clear precedences related to that FIFO */
- wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
+ wlc->tx_prec_map &= ~(1 << fifo);
return -EBUSY;
}
return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 0ab7d36..4e3af67 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -101,9 +101,6 @@

#define DATA_BLOCK_TX_SUPR (1 << 4)

-/* 802.1D Priority to TX FIFO number for wme */
-extern const u8 prio2fifo[];
-
/* Ucode MCTL_WAKE override bits */
#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
@@ -534,7 +531,6 @@ struct brcms_c_info {

u16 wme_retries[IEEE80211_NUM_ACS];
u16 tx_prec_map;
- u16 fifo2prec_map[NFIFO];

struct brcms_bss_cfg *bsscfg;

@@ -641,7 +637,7 @@ extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
struct sk_buff *p, bool commit);
extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo);
extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
- struct sk_buff *sdu, uint prec);
+ struct sk_buff *sdu);
extern void brcms_c_print_txstatus(struct tx_status *txs);
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 5855f4f..40ccc69 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -200,13 +200,7 @@ enum wlc_par_id {
/* WL11N Support */
#define AMPDU_AGG_HOST 1

-/* pri is priority encoded in the packet. This maps the Packet priority to
- * enqueue precedence as defined in wlc_prec_map
- */
-extern const u8 wlc_prio2prec_map[];
-#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
-
-#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
+#define BRCMS_PREC_COUNT 4 /* Max precedence level implemented */

/* Mask to describe all precedence levels */
#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
@@ -219,24 +213,6 @@ extern const u8 wlc_prio2prec_map[];
#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
BRCMS_PREC_COUNT - 1)

-/* Define a bitmap of precedences comprised by each AC */
-#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
-#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
-#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
-#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
-
/* network protection config */
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
--
1.7.9.5


2012-11-19 18:35:38

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 03/22] brcmsmac: Add helper function for updating txavail count

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> Use this helper function rather than open-coding the same calculation in
> multiple places.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)




2012-11-20 22:35:59

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 20.11.2012 22:09, Arend van Spriel wrote:
> On 11/20/2012 06:44 PM, Daniel Wagner wrote:
>> Hi Seth,
>>
>> On 20.11.2012 15:28, Seth Forshee wrote:
>>> On Tue, Nov 20, 2012 at 08:30:10AM +0100, Daniel Wagner wrote:
>>>> Hi Seth,
>>>>
>>>> On 19.11.2012 20:11, Daniel Wagner wrote:
>>>>> Works perfectly fine on my machine.
>>>>
>>>> Well, not really true. Though I am not sure if this what I am seeing
>>>> related to your changes. I see following log only when I am using my
>>>> home AP. The pattern is that when the connection stop working I see
>>>> something like this in the log:
>>>>
>>>> [ 8735.159091] wlan0: moving STA 1c:c6:3c:1f:50:68 to state 4
>>>> [ 8735.197298] wlan0: Rx A-MPDU request on tid 0 result 0
>>>> [ 8735.566368] wlan0: Open BA session requested for 1c:c6:3c:1f:50:68
>>>> tid 0
>>>> [ 8735.573701] wlan0: activated addBA response timer on tid 0
>>>> [ 8735.578826] wlan0: switched off addBA timer for tid 0
>>>> [ 8735.578834] wlan0: Aggregation is on for tid 0
>>>> [ 8749.687530] wlan0: tx session timer expired on tid 0
>>>> [ 8749.687558] wlan0: Tx BA session stop requested for
>>>> 1c:c6:3c:1f:50:68 tid 0
>>>> [ 8749.700550] wlan0: Stopping Tx BA session for 1c:c6:3c:1f:50:68
>>>> tid 0
>>>>
>>>>
>>>> This is what I do: First establishing a connection, then after a
>>>> while any
>>>> traffic seems stops for a period and sometimes it recovers from that
>>>> point. If
>>>> not a disconnect/connect (using ConnMan) dance fixes the problem.
>>>
>>> The tx session timer expiring is a result of not having any aggregate
>>> transfers in a while. In my testing with iperf I see periods where the
>>> transfer seems to stall, but it always recovers. These are less frequent
>>> after my patches, but they still happen, and I haven't been able to work
>>> out the cause yet. I'm not sure whether these are related to what you're
>>> seeing or not.
>>>
>>> Luckily I've added a bunch of new debug code. Could you make sure you
>>> have MAC80211_MESSAGE_TRACING and BRCM_TRACING enabled in your config
>>> and collect a trace when this is happening by running:
>>>
>>> trace-cmd record -e mac80211 -e mac80211_msg -e brcmsmac \
>>> -e brcmsmac_tx -e brcmsmac_msg
>>>
>>> This going to collect a lot of data, and you should bump up the trace
>>> buffer size to avoid overruns. Once you've got a trace please compress
>>> trace.dat and put it along with your dmesg somewhere where I can get at
>>> them.
>>
>> I hope I got it right. Here are the requested logs:
>>
>> http://www.monom.org/misc/brcmsmac/traces/
>
> What channel is you AP on?

It's on 13 which is the only not too crowed channel in my place.

2012-11-20 21:16:52

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On Tue, Nov 20, 2012 at 10:09:14PM +0100, Arend van Spriel wrote:
> >I hope I got it right. Here are the requested logs:
> >
> >http://www.monom.org/misc/brcmsmac/traces/
>
> What channel is you AP on?

Based on the trace it looks like channel 13.

If you want to take a look at the decoded trace data I've uploaded it to
http://people.canonical.com/~sforshee/brcms-trace/trace.log. I've got a
trace-cmd plugin for the tracepoints I added that makes it easier to
decipher.

Seth

2012-11-19 20:45:18

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> Hi Arend,
>
> As promised, here's the updated patch series for brcmsmac to remove the
> tx packet queue, add flow control, and add enhanced debug trace support.
> I've broken up the tx rework into multiple patches as you requested.
> Most notably I've split out the AMPDU session support into a separate
> patch, which should make it easier to review that change. I've done
> basic testing of each of the new commits to try and verify that no
> obvious regressions are introduced by any of them.

I replied to the patches that were reworked. We skipped the already
Acked-by patches in this review round.

The patches have been in nightly testing on bcm43224 for a couple of
days. It still occasionally does show the infamous warning in the
.flush() callback. Can not have it all. I want to run the changes on
bcm4313 as well.

Gr. AvS



2012-11-19 18:35:50

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 04/22] brcmsmac: Remove unimplemented flow control functions

On 11/15/2012 03:07 PM, Seth Forshee wrote:
> Functions for flow control exist but remain unimplemented. Remove these
> in advance of adding real flow control.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 31 ------------------------
> 1 file changed, 31 deletions(-)




2012-11-20 21:51:51

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 11/20/2012 10:16 PM, Seth Forshee wrote:
> On Tue, Nov 20, 2012 at 10:09:14PM +0100, Arend van Spriel wrote:
>>> I hope I got it right. Here are the requested logs:
>>>
>>> http://www.monom.org/misc/brcmsmac/traces/
>>
>> What channel is you AP on?
>
> Based on the trace it looks like channel 13.

Think so too.

> If you want to take a look at the decoded trace data I've uploaded it to
> http://people.canonical.com/~sforshee/brcms-trace/trace.log. I've got a
> trace-cmd plugin for the tracepoints I added that makes it easier to
> decipher.
>
> Seth
>

Nice :-D Are you sharing it?

Gr. AvS


2012-12-05 08:16:13

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Arend

On 03.12.2012 18:40, Arend van Spriel wrote:
> So what exactly is the brand and model of your home 11n AP. With a bit
> of luck we may have it over here.

It is a "Alice Modem WLAN 1421". It seems to be a device only created for
this ISP. Some research gave me that it might be produced by Arcadyan.
According my findings the chipset would come either from Lantiq
(Infineon) Danube or Amazon-SE.

BTW, I found a lot of people complaining about that crap hardware.
Not only WLAN performance is pretty bad for lot's of people it also has
sever problems keeping the Internet link open. The only working fix
seems to be to replace it with something which is known to work.

Ah, some more googling revealed this:

https://forum.openwrt.org/viewtopic.php?id=15934&p=23

"""
just wanting to know if i am right

I am having an arcardyan AR7505 board here with an Infineon PSB 50601HL V1.2 SOC

it has 2M Flash - EON EN29LV160AB and a RTL8306 Switch

it runs a BRN Bootloader: Wireless ADSL Gateway AMAZON_SE Loader V0.02.06 build Jul 23 2010 00:32:10

i was able to connect a Serial connector and managed to download the firmware as a backup.

after this was trying to run u-boot from memory (this is where i hit the wall)
from my understanding i do upload an uboot.bin (BRN-Version) version via xmodem to
RAM Memory and execute it from there - since this was only a test, i "just"
tried any danube/lantiq uboot to see if it might work.... but it does not.
(most of the time the system just reboots . the rest of the time i get an output
on the serial console that does not seem to be in the correct speed .... and the
system sticks in limbo) can you give me a brief hint what i need to do.

thanks for your help

BTW: it is a German Alice ADSL Wlan 1421 Modem

"""

cheers,
daniel

2012-12-03 08:23:31

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Seth,

On 26.11.2012 22:20, Daniel Wagner wrote:
> On 26.11.2012 20:36, Seth Forshee wrote:
>> On Wed, Nov 21, 2012 at 08:35:28AM -0600, Seth Forshee wrote:
>>>> My 'test' setup is following: I downloaded a larger file and let a
>>>> youtube
>>>> video play. With tracing enabled the download and the playback did
>>>> work nicely.
>>>>
>>>> Without tracing enabled playing back only a youtube video was
>>>> 'triggering'
>>>> the problem. It downloads a few seconds of content in a burst and
>>>> then the playback
>>>> starts. Under normal conditions, the app will continue downloading
>>>> the video at a
>>>> lower rate. But this normally doesn't happen right now. Often it
>>>> will just stop
>>>> working and often the connection is completely blocked, e.g. pinging
>>>> a host
>>>> wont work.
>>>
>>> I'll see if I can reproduce, but if it's specific to the AP then I may
>>> not have any luck. Don't expect to hear much from me until next week
>>> though; I'm on holiday starting today and will be visiting family.
>>
>> It seems I'm unable to reproduce the problem with any of the APs
>> available to me, unfortunately.
>
> I tried it again with disabled the TX trace but I can't reproduce it
> either. Well, I am sick of this AP and I might just get a better one
> (which should be fairly simple).

FYI, I got my old Netgear 11g AP out and I get a very 'smooth' wifi
experience.

If you like you can add Tested-by tag :)

cheers,
daniel

2012-12-03 10:15:38

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

Hi Arend,

On 03.12.2012 09:37, Arend van Spriel wrote:
>> On 26.11.2012 22:20, Daniel Wagner wrote:
>>> On 26.11.2012 20:36, Seth Forshee wrote:
>>>> On Wed, Nov 21, 2012 at 08:35:28AM -0600, Seth Forshee wrote:
>>>>>> My 'test' setup is following: I downloaded a larger file and let a
>>>>>> youtube
>>>>>> video play. With tracing enabled the download and the playback did
>>>>>> work nicely.
>>>>>>
>>>>>> Without tracing enabled playing back only a youtube video was
>>>>>> 'triggering'
>>>>>> the problem. It downloads a few seconds of content in a burst and
>>>>>> then the playback
>>>>>> starts. Under normal conditions, the app will continue downloading
>>>>>> the video at a
>>>>>> lower rate. But this normally doesn't happen right now. Often it
>>>>>> will just stop
>>>>>> working and often the connection is completely blocked, e.g. pinging
>>>>>> a host
>>>>>> wont work.
>>>>>
>>>>> I'll see if I can reproduce, but if it's specific to the AP then I may
>>>>> not have any luck. Don't expect to hear much from me until next week
>>>>> though; I'm on holiday starting today and will be visiting family.
>>>>
>>>> It seems I'm unable to reproduce the problem with any of the APs
>>>> available to me, unfortunately.
>>>
>>> I tried it again with disabled the TX trace but I can't reproduce it
>>> either. Well, I am sick of this AP and I might just get a better one
>>> (which should be fairly simple).
>>
>> FYI, I got my old Netgear 11g AP out and I get a very 'smooth' wifi
>> experience.
>>
>> If you like you can add Tested-by tag :)
>
> You basically tested 11g operation is ok. Still interesting to know,
> because it may indicate that problems start happening when doing 11n
> rates and/or A-MPDU sessions.

A friend of mine have the same 11n AP and for them it also behaves
pretty shitty for him (Windows even worse then Linux...).

I don't know if it is worth to continue to debug with this this
particular 11n AP.

I had a good performance during LinuxCon which indicates that it is
really only my home AP. What I could do is to test with 11n APs at my
workplace and see if the it is really only my home 11n AP.

cheers,
daniel

2012-12-03 17:40:46

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 12/03/2012 11:15 AM, Daniel Wagner wrote:
> Hi Arend,
>
> On 03.12.2012 09:37, Arend van Spriel wrote:
>>> On 26.11.2012 22:20, Daniel Wagner wrote:
>>>> On 26.11.2012 20:36, Seth Forshee wrote:
>>>>> On Wed, Nov 21, 2012 at 08:35:28AM -0600, Seth Forshee wrote:
>>>>>>> My 'test' setup is following: I downloaded a larger file and let a
>>>>>>> youtube
>>>>>>> video play. With tracing enabled the download and the playback did
>>>>>>> work nicely.
>>>>>>>
>>>>>>> Without tracing enabled playing back only a youtube video was
>>>>>>> 'triggering'
>>>>>>> the problem. It downloads a few seconds of content in a burst and
>>>>>>> then the playback
>>>>>>> starts. Under normal conditions, the app will continue downloading
>>>>>>> the video at a
>>>>>>> lower rate. But this normally doesn't happen right now. Often it
>>>>>>> will just stop
>>>>>>> working and often the connection is completely blocked, e.g. pinging
>>>>>>> a host
>>>>>>> wont work.
>>>>>>
>>>>>> I'll see if I can reproduce, but if it's specific to the AP then I
>>>>>> may
>>>>>> not have any luck. Don't expect to hear much from me until next week
>>>>>> though; I'm on holiday starting today and will be visiting family.
>>>>>
>>>>> It seems I'm unable to reproduce the problem with any of the APs
>>>>> available to me, unfortunately.
>>>>
>>>> I tried it again with disabled the TX trace but I can't reproduce it
>>>> either. Well, I am sick of this AP and I might just get a better one
>>>> (which should be fairly simple).
>>>
>>> FYI, I got my old Netgear 11g AP out and I get a very 'smooth' wifi
>>> experience.
>>>
>>> If you like you can add Tested-by tag :)
>>
>> You basically tested 11g operation is ok. Still interesting to know,
>> because it may indicate that problems start happening when doing 11n
>> rates and/or A-MPDU sessions.
>
> A friend of mine have the same 11n AP and for them it also behaves
> pretty shitty for him (Windows even worse then Linux...).
>
> I don't know if it is worth to continue to debug with this this
> particular 11n AP.
>
> I had a good performance during LinuxCon which indicates that it is
> really only my home AP. What I could do is to test with 11n APs at my
> workplace and see if the it is really only my home 11n AP.
>

So what exactly is the brand and model of your home 11n AP. With a bit
of luck we may have it over here.

Gr. AvS



2012-12-04 07:25:46

by Daniel Wagner

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 03.12.2012 18:40, Arend van Spriel wrote:
>>>> FYI, I got my old Netgear 11g AP out and I get a very 'smooth' wifi
>>>> experience.
>>>>
>>>> If you like you can add Tested-by tag :)
>>>
>>> You basically tested 11g operation is ok. Still interesting to know,
>>> because it may indicate that problems start happening when doing 11n
>>> rates and/or A-MPDU sessions.
>>
>> A friend of mine have the same 11n AP and for them it also behaves
>> pretty shitty for him (Windows even worse then Linux...).
>>
>> I don't know if it is worth to continue to debug with this this
>> particular 11n AP.
>>
>> I had a good performance during LinuxCon which indicates that it is
>> really only my home AP. What I could do is to test with 11n APs at my
>> workplace and see if the it is really only my home 11n AP.
>>
>
> So what exactly is the brand and model of your home 11n AP. With a bit
> of luck we may have it over here.

Forgot to check the AP before leaving for work. Will report back this
evening.


2012-12-03 08:37:34

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH v2 00/22] brcmsmac: Tx rework and expanded debug/trace support

On 12/03/2012 09:23 AM, Daniel Wagner wrote:
> Hi Seth,
>
> On 26.11.2012 22:20, Daniel Wagner wrote:
>> On 26.11.2012 20:36, Seth Forshee wrote:
>>> On Wed, Nov 21, 2012 at 08:35:28AM -0600, Seth Forshee wrote:
>>>>> My 'test' setup is following: I downloaded a larger file and let a
>>>>> youtube
>>>>> video play. With tracing enabled the download and the playback did
>>>>> work nicely.
>>>>>
>>>>> Without tracing enabled playing back only a youtube video was
>>>>> 'triggering'
>>>>> the problem. It downloads a few seconds of content in a burst and
>>>>> then the playback
>>>>> starts. Under normal conditions, the app will continue downloading
>>>>> the video at a
>>>>> lower rate. But this normally doesn't happen right now. Often it
>>>>> will just stop
>>>>> working and often the connection is completely blocked, e.g. pinging
>>>>> a host
>>>>> wont work.
>>>>
>>>> I'll see if I can reproduce, but if it's specific to the AP then I may
>>>> not have any luck. Don't expect to hear much from me until next week
>>>> though; I'm on holiday starting today and will be visiting family.
>>>
>>> It seems I'm unable to reproduce the problem with any of the APs
>>> available to me, unfortunately.
>>
>> I tried it again with disabled the TX trace but I can't reproduce it
>> either. Well, I am sick of this AP and I might just get a better one
>> (which should be fairly simple).
>
> FYI, I got my old Netgear 11g AP out and I get a very 'smooth' wifi
> experience.
>
> If you like you can add Tested-by tag :)

You basically tested 11g operation is ok. Still interesting to know,
because it may indicate that problems start happening when doing 11n
rates and/or A-MPDU sessions.

Gr. AvS