2012-10-26 14:23:50

by Seth Forshee

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

I've been looking into the issues with brcmsmac performance reported at
[0] and [1]. I started out looking into the tx queueing based on the "No
where to go" messages in the logs. This code has a number of
shortcomings:

- The amount of bufferring is excessive. The tx queue will buffer up to
228 packets, and each of the tx DMA rings will queue up to 256 more.

- There's no flow control. If the queue fills up packets begin to get
dropped, as evidenced by the "No where to go" messages.

- Without flow control the tx queue probably helps avoid dropping
packets for short bursts due to the sheer number of packets that will
be buffered, but if flow control is added the only remaining benefit
that I can see is that it accumulates packets for aggregation. The tx
queue is far more complex than needed for supporting aggergation,
however.

As a result I worked up the following patches to add flow control remove
the tx queue.

These patches change the tx handler to directly hand off packets to the
DMA code. The convoluted priority->precedence->fifo mapping is converted
to a simple one-to-one mapping of the mac80211 queues to fifos. Non-
aggregate frames are immediately inserted into the DMA ring.

Handling of aggregate frames is not as simple, as some of the tx header
fixups can only happen once we have all the frames for an AMPDU. To
support this without resyncing buffers after they've been added to the
DMA ring I've added the concept of AMPDU sessions. An AMPDU session
simply queues up the frames for a single AMPDU until we are ready to
insert them into the tx ring. There is one session per DMA ring, and
descriptors are reserved in the corresponding ring for all frames queued
in the AMPDU session. This also has the benefit of allowing non-
aggregate frames to be sent without affecting aggregation and without
mapping these frames to a different fifo.

The patches also add flow control to stop incoming tx packets when the
DMA ring is full. In practice I found that we will sometimes receive a
single frame from mac80211 after stopping the queues, so some headroom
is reserved when stopping the queues. I also reduced the number of tx
descriptors per ring to 64 and fixed a bug that prevented having
differing non-zero numbers of tx and rx descriptors for a given ring.

When workig on this I made extensive use of ftrace for debug and
verification. I'm including patches I wrote which expand the trace
support and introduce debug macros which can log messages both to dmesg
and the trace buffer. iwlwifi has similar trace support which we've
enabled in Ubuntu, making it easier to collect debug information from
users experiencing wireless problems.

With these changes I'm no longer seeing dropped frames when the tx
queues are full. Anecdotally I'd also say that my testing with iperf
using TCP seems to show more consistent data rates, resulting in a
higher average data rate (sometimes significantly so), but I don't have
sufficient amounts of data to be sure this is the case.

I'm still observing a few problems when testing with iperf, however. The
first is "Pkt tx suppressed, illegal channel" messages. There are also
large drops in the data rate reported when using TCP, sometimes even
resulting in iperf reporting that no data was transferred for several
seconds. Finally, when using iperf with UDP the number of dropped frames
periodically spikes to high levels. I'm not sure yet, but it looks like
the second and third problems may coincide with scanning.

I also continue to see flush timeouts, but the frequency seems to be
reduced with these changes. Likely this is related to the much smaller
number of packets that will be queued internally for tx.

Thanks,
Seth

[0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1046507
[1] http://www.spinics.net/lists/linux-wireless/msg96287.html


Seth Forshee (18):
brcmsmac: Rework tx code to avoid internal buffering of packets
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: Add macro for checking if debug log levels are enabled
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 INT debug macro
brcmsmac: Add DMA debug macro
brcmsmac: Add 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 but uninformative debug messages

drivers/net/wireless/brcm80211/Kconfig | 12 +
drivers/net/wireless/brcm80211/brcmsmac/Makefile | 3 +-
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 726 ++++++------
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 29 +-
drivers/net/wireless/brcm80211/brcmsmac/antsel.c | 4 +-
.../net/wireless/brcm80211/brcmsmac/brcms_debug.c | 44 +
.../net/wireless/brcm80211/brcmsmac/brcms_debug.h | 46 +
.../brcm80211/brcmsmac/brcms_trace_events.h | 175 ++-
drivers/net/wireless/brcm80211/brcmsmac/channel.c | 10 +-
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 | 1157 ++++++--------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 48 +-
drivers/net/wireless/brcm80211/brcmsmac/stf.c | 8 +-
drivers/net/wireless/brcm80211/brcmsmac/types.h | 5 +-
drivers/net/wireless/brcm80211/include/defs.h | 11 +-
17 files changed, 1302 insertions(+), 1453 deletions(-)
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.c
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h



2012-10-26 14:24:25

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 15/18] 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.

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 | 268 +++-----------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 9 -
4 files changed, 93 insertions(+), 248 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 581b7ef..dc650eb 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 "brcms_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_have_debug_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);
@@ -1078,6 +1075,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 2073f08..28c08f6 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 "brcms_debug.h"
+#include "brcms_trace_events.h"

/*
* Indication for txflowcontrol that all priority bits in
@@ -868,7 +869,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;
@@ -881,6 +882,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
@@ -894,29 +899,31 @@ 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_have_debug_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);
+ 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);

@@ -929,11 +936,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 =
@@ -1024,8 +1040,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);
@@ -1055,8 +1076,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;
@@ -5668,45 +5687,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;
@@ -5755,184 +5735,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-10-26 15:37:27

by Arend van Spriel

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

On 10/26/2012 04:23 PM, Seth Forshee wrote:
> I've been looking into the issues with brcmsmac performance reported at
> [0] and [1]. I started out looking into the tx queueing based on the "No
> where to go" messages in the logs. This code has a number of
> shortcomings:
>
> - The amount of bufferring is excessive. The tx queue will buffer up to
> 228 packets, and each of the tx DMA rings will queue up to 256 more.
>
> - There's no flow control. If the queue fills up packets begin to get
> dropped, as evidenced by the "No where to go" messages.
>
> - Without flow control the tx queue probably helps avoid dropping
> packets for short bursts due to the sheer number of packets that will
> be buffered, but if flow control is added the only remaining benefit
> that I can see is that it accumulates packets for aggregation. The tx
> queue is far more complex than needed for supporting aggergation,
> however.

Thanks, Seth

Nice series that rolled out of your sleeve ;-) We seem to have been
working in parallel here, which is a bit of a pity. One of the things
that we noticed was indeed missing flow control. We did not start adding
that so not work wasted there.

> As a result I worked up the following patches to add flow control remove
> the tx queue.
>
> These patches change the tx handler to directly hand off packets to the
> DMA code. The convoluted priority->precedence->fifo mapping is converted
> to a simple one-to-one mapping of the mac80211 queues to fifos. Non-
> aggregate frames are immediately inserted into the DMA ring.

We considered this during mainlining brcmsmac. So retries are also
queued back on the DMA fifo?

> Handling of aggregate frames is not as simple, as some of the tx header
> fixups can only happen once we have all the frames for an AMPDU. To
> support this without resyncing buffers after they've been added to the
> DMA ring I've added the concept of AMPDU sessions. An AMPDU session
> simply queues up the frames for a single AMPDU until we are ready to
> insert them into the tx ring. There is one session per DMA ring, and
> descriptors are reserved in the corresponding ring for all frames queued
> in the AMPDU session. This also has the benefit of allowing non-
> aggregate frames to be sent without affecting aggregation and without
> mapping these frames to a different fifo.
>
> The patches also add flow control to stop incoming tx packets when the
> DMA ring is full. In practice I found that we will sometimes receive a
> single frame from mac80211 after stopping the queues, so some headroom
> is reserved when stopping the queues. I also reduced the number of tx
> descriptors per ring to 64 and fixed a bug that prevented having
> differing non-zero numbers of tx and rx descriptors for a given ring.
>
> When workig on this I made extensive use of ftrace for debug and
> verification. I'm including patches I wrote which expand the trace
> support and introduce debug macros which can log messages both to dmesg
> and the trace buffer. iwlwifi has similar trace support which we've
> enabled in Ubuntu, making it easier to collect debug information from
> users experiencing wireless problems.
>
> With these changes I'm no longer seeing dropped frames when the tx
> queues are full. Anecdotally I'd also say that my testing with iperf
> using TCP seems to show more consistent data rates, resulting in a
> higher average data rate (sometimes significantly so), but I don't have
> sufficient amounts of data to be sure this is the case.
>
> I'm still observing a few problems when testing with iperf, however. The
> first is "Pkt tx suppressed, illegal channel" messages. There are also

This is tx status feedback coming in directly from ucode. Not found any
clues there yet.

> large drops in the data rate reported when using TCP, sometimes even
> resulting in iperf reporting that no data was transferred for several
> seconds. Finally, when using iperf with UDP the number of dropped frames
> periodically spikes to high levels. I'm not sure yet, but it looks like
> the second and third problems may coincide with scanning.
>
> I also continue to see flush timeouts, but the frequency seems to be
> reduced with these changes. Likely this is related to the much smaller
> number of packets that will be queued internally for tx.

Last week we have been making progress on the flush timeout so a patch
is queued up for that.

Again, thanks for putting a bit of love into brcmsmac. Hope you did not
curse too much in that process ;-) I will publish it internally on our
review server so we can provide our comments.

See you in Barcelona ;-)

Regards,
Arend


2012-10-26 14:23:51

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 01/18] brcmsmac: Rework tx code to avoid internal buffering of packets

The brcmsmac internal tx buffering is problematic for a number of
reasons. The amount of buffering is excessive (228 packets in addition
to the 256 slots in each DMA ring), frames may be dropped due to a lack
of flow control, and the structure of the queues complicates the
otherwise straightforward mapping of mac80211 queues to device fifos.

This patch reworks the transmit code path to eliminate the internal
buffering. Frames are immediately handed off to the DMA support rather
than passing through an intermediate queue. ieee80211_(stop|wake)_queue()
are used for flow control to stop receiving frames when a DMA tx ring is
full.

To handle aggregation the concept of AMPDU sessions is added to the
driver. The AMPDU session allows MPDUs to be temporarily queued by the
DMA code until either a full AMPDU has been collected or circumstances
dictate that transmission should start with a partial AMPDU. The use of
a queue ensures that the tx headers are fully initialized before the
buffers are synced for DMA, and it allows non-aggregate frames to be
immediately placed in the tx ring so that more frames can be collected
for aggregation.

Signed-off-by: Seth Forshee <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 666 ++++++++++-------------
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 29 +-
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 182 ++++++-
drivers/net/wireless/brcm80211/brcmsmac/dma.h | 9 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 514 +++++------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 39 +-
drivers/net/wireless/brcm80211/brcmsmac/types.h | 1 -
7 files changed, 628 insertions(+), 812 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index be5bcfb..bfb04ec 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;
/*
@@ -498,378 +493,324 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
}

-int
-brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
- struct sk_buff **pdu, int prec)
+void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
+ struct brcms_c_info *wlc)
{
- struct brcms_c_info *wlc;
- struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
- u8 tid, ndelim;
- 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;
+ 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;
+}

- 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;
+/*
+ * 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;
- struct ieee80211_hdr *h;
- 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;
+ uint len;
+ u16 mcl;
bool fbr_iscck;
- struct ieee80211_tx_info *tx_info;
- u16 qlen;
- struct wiphy *wiphy;
-
- wlc = ampdu->wlc;
- wiphy = wlc->wiphy;
- p = *pdu;
+ bool rr;

- tid = (u8) (p->priority);
+ 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;

- f = ampdu->fifo_tb + prio2fifo[tid];
+ ampdu_frames = skb_queue_len(&session->skb_list);
+ if (ampdu_frames != 0) {
+ struct sk_buff *first;

- scb = &wlc->pri_scb;
- scb_ampdu = &scb->scb_ampdu;
- ini = &scb_ampdu->ini[tid];
+ if (ampdu_frames + 1 > session->max_ampdu_frames ||
+ session->ampdu_len + len > session->max_ampdu_len)
+ return -ENOSPC;

- /* 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 */
- rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
- ampdu_len = 0;
- dma_len = 0;
- while (p) {
- struct ieee80211_tx_rate *txrate;
-
- tx_info = IEEE80211_SKB_CB(p);
- txrate = tx_info->status.rates;
+ /*
+ * 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;
+ }

- 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;
- }
+ /*
+ * Now that we're sure this frame can be accomodated, update the
+ * session information.
+ */
+ session->ampdu_len += len;
+ session->dma_len += p->len;

- if (err) {
- if (err == -EBUSY) {
- wiphy_err(wiphy, "wl%d: sendampdu: "
- "prep_xdu retry; seq 0x%x\n",
- wlc->pub->unit, seq);
- *pdu = p;
- break;
- }
+ tid = (u8)p->priority;

- /* error in the packet; reject it */
- wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
- "rejected; seq 0x%x\n", wlc->pub->unit, seq);
- *pdu = NULL;
- break;
- }
+ /* Handle retry limits */
+ if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) {
+ txrate[0].count++;
+ rr = true;
+ } else {
+ txrate[1].count++;
+ rr = false;
+ }

- /* 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);
+ 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];

- /* 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;
+ if (rr) {
+ plcp0 = plcp[0];
+ plcp3 = plcp[3];
} 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);
+ plcp0 = txh->FragPLCPFallback[0];
+ plcp3 = txh->FragPLCPFallback[3];

- /* 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);
+ /* 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]);

- dma_len += (u16) p->len;
+ 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);
+ }
+ }

- BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
- " seg_cnt %d null delim %d\n",
- wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
+ /*
+ * 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 */

- txh->MacTxControlLow = cpu_to_le16(mcl);
+ skb_queue_tail(&session->skb_list, p);

- /* this packet is added */
- pkt[count++] = p;
+ return 0;
+}

- /* patch the first MPDU */
- if (count == 1) {
- u8 plcp0, plcp3, is40, sgi;
+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 (rr) {
- plcp0 = plcp[0];
- plcp3 = plcp[3];
- } else {
- plcp0 = txh->FragPLCPFallback[0];
- plcp3 = txh->FragPLCPFallback[3];
+ if (skb_queue_empty(&session->skb_list))
+ return;

- }
- 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);
- }
+ 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);

- 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);
- }
- }
+ 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;
+ }

- /* 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);
- break;
- }
+ /* 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 (count == scb_ampdu->max_pdu)
- break;
+ 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;
+ }

- /*
- * 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) &&
- ((u8) (p->priority) == tid)) {
- plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
- plen = max(scb_ampdu->min_len, plen);
+ 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 ((plen + ampdu_len) > max_ampdu_bytes) {
- p = NULL;
- continue;
- }
+ BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len);
+ /* mark plcp to indicate ampdu */
+ BRCMS_SET_MIMO_PLCP_AMPDU(plcp);

- /*
- * 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) */
+ /* 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;
+ }

- ini->tx_in_transit += count;
+ /* 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;
+ }

- 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);
+ mch = le16_to_cpu(txh->MacTxControlHigh);

- BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
- /* mark plcp to indicate ampdu */
- BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
+ /* 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;

- /* 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;
- }
+ if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
+ TXC_PREAMBLE_RTS_FB_SHORT)
+ rts_fbr_preamble_type = BRCMS_SHORT_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,
+ 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);
+ 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);
}
- /* endif (count) */
- return err;
+
+ BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
+ wlc->pub->unit, skb_queue_len(&session->skb_list),
+ session->ampdu_len);
}

static void
@@ -977,8 +918,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) {
@@ -1046,14 +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--;
+ ret = brcms_c_txfifo(wlc, queue, p);
/*
- * Use high prededence for retransmit to
- * give some punch
+ * We shouldn't be out of space in the DMA
+ * ring here since we're reinserting a frame
+ * that was just pulled out.
*/
- brcms_c_txq_enq(wlc, scb, p,
- BRCMS_PRIO_TO_HI_PREC(tid));
+ WARN_ONCE(ret, "queue %d out of txds\n", queue);
} else {
/* Retry timeout */
ini->tx_in_transit--;
@@ -1080,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, ampdu->txpkt_weight);
}

void
@@ -1097,8 +1036,10 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
struct scb_ampdu_tid_ini *ini;
u32 s1 = 0, s2 = 0;
struct ieee80211_tx_info *tx_info;
+ uint queue;

tx_info = IEEE80211_SKB_CB(p);
+ queue = txs->frameid & TXFID_QUEUE_MASK;

/* BMAC_NOTE: For the split driver, second level txstatus comes later
* So if the ACK was received then wait for the second level else just
@@ -1127,7 +1068,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
} else {
/* loop through all pkts and free */
- u8 queue = txs->frameid & TXFID_QUEUE_MASK;
struct d11txh *txh;
u16 mcl;
while (p) {
@@ -1142,7 +1082,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, ampdu->txpkt_weight);
}
}

@@ -1182,23 +1121,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)
@@ -1218,15 +1140,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 421f4ba..73d01e5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
@@ -17,11 +17,34 @@
#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,
- 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 5e53305..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,39 +1287,25 @@ bool dma_rxreset(struct dma_pub *pub)
return status == D64_RS0_RS_DISABLED;
}

-/*
- * !! 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)
+static void dma_txenq(struct dma_info *di, struct sk_buff *p)
{
- 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);

@@ -1318,14 +1327,105 @@ 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 */
- di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
+ 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;

@@ -1334,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);
}

/*
@@ -1412,7 +1540,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;

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 565c15a..2dd0e4f 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"

/*
* Indication for txflowcontrol that all priority bits in
@@ -242,12 +243,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() */
@@ -283,17 +284,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)
@@ -371,6 +361,36 @@ 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 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,
+};
+
+/* Mapping of tx fifos to ieee80211 AC numbers */
+static const u8 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(fifo_mapping))
+ return TX_AC_BE_FIFO;
+ return fifo_mapping[ac];
+}
+
+static u8 brcms_fifo_to_ac(u8 fifo)
+{
+ if (fifo >= ARRAY_SIZE(ac_mapping))
+ return IEEE80211_AC_BE;
+ return ac_mapping[fifo];
+}
+
/* Find basic rate for a given rate */
static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
{
@@ -415,10 +435,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)
@@ -841,8 +866,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;
@@ -854,6 +880,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,
@@ -863,18 +890,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);
@@ -889,7 +917,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);

@@ -898,7 +926,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;
@@ -982,8 +1011,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, 1);
-
if (lastframe) {
/* remove PLCP & Broadcom tx descriptor header */
skb_pull(p, D11_PHY_HDR_LEN);
@@ -994,14 +1021,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
@@ -1058,9 +1092,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;
}

@@ -1125,7 +1156,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,
@@ -1139,7 +1170,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);
@@ -1150,7 +1181,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);
@@ -1160,7 +1191,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);
@@ -2884,12 +2915,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]);
@@ -3752,40 +3785,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;
- 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;
-}
-
-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)
{
@@ -4836,56 +4835,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;
@@ -5005,10 +4954,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;
}
@@ -5314,7 +5259,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);

@@ -5353,13 +5297,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);
-
callbacks += brcms_b_down_finish(wlc->hw);

/* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
@@ -6033,86 +5970,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, uint prec)
-{
- struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
- struct pktq *q = &qi->q;
- int prio;
-
- prio = sdu->priority;
-
- 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
@@ -7273,79 +7130,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)
{
- 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];
- 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_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,
- 1);
- }
- }
-
- 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, s8 txpktpend)
-{
- 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.
@@ -7353,16 +7164,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] += txpktpend;
- BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
- txpktpend, wlc->core->txpktpend[fifo]);
- }
-
/* Commit BCMC sequence number in the SHM frame ID location */
if (frameid != INVALIDFID) {
/*
@@ -7372,8 +7173,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, wlc->hw->di[fifo], 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
@@ -7423,19 +7268,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, s8 txpktpend)
-{
- wlc->core->txpktpend[fifo] -= txpktpend;
- BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
- wlc->core->txpktpend[fifo]);
-
- /* There is more room; mark precedences related to this FIFO sendable */
- wlc->tx_prec_map |= wlc->fifo2prec_map[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)
{
@@ -7883,35 +7715,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 &= ~(wlc->fifo2prec_map[fifo]);
- return -EBUSY;
- }
- return 0;
-}
-
int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks)
{
@@ -7977,13 +7780,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)
@@ -8211,10 +8016,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;

@@ -8286,9 +8087,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 =
@@ -8303,9 +8101,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);

@@ -8464,15 +8259,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 8debc74..8a58cc1 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
@@ -242,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 */
};
@@ -382,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.
*
@@ -435,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.
@@ -469,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
*/
@@ -533,14 +512,9 @@ struct brcms_c_info {
u16 edcf_txop[IEEE80211_NUM_ACS];

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

struct brcms_bss_cfg *bsscfg;

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

u8 mimoft;
@@ -585,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;
};
@@ -637,13 +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, s8 txpktpend);
-extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
- s8 txpktpend);
-extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
- struct sk_buff *sdu, uint prec);
+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);
@@ -658,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/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-10-26 14:24:10

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 09/18] 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.

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 a59954f..279b1a5 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 "brcms_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_have_debug_level(BRCM_DL_INFO)) {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
index 55e12c3..94cd684 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 "brcms_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..a256a89 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 "brcms_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..ebca6a5 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 "brcms_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 fbc39b1..a5fafb0 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 "brcms_debug.h"

/*
* Indication for txflowcontrol that all priority bits in
@@ -646,7 +647,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;
}
@@ -716,7 +717,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);
@@ -745,7 +746,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 */
@@ -756,8 +756,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)) {
@@ -765,12 +766,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);
}
}
}
@@ -785,7 +788,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;

@@ -904,7 +907,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)

if (txs->phyerr) {
if (brcm_have_debug_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);
}
@@ -940,7 +943,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.
@@ -1012,8 +1015,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;
@@ -1061,8 +1065,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));
@@ -1138,7 +1142,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);
@@ -1194,8 +1197,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;
}

@@ -1553,7 +1557,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);

@@ -1762,8 +1766,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);
@@ -1808,7 +1810,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;
@@ -1942,7 +1944,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
@@ -2031,7 +2033,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;
@@ -2042,13 +2044,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);
}
@@ -2261,7 +2263,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));

@@ -2289,8 +2291,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)) {
@@ -2298,8 +2300,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);
}
}
@@ -2336,7 +2338,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;

@@ -2353,35 +2354,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;
}
@@ -2631,8 +2632,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)
@@ -2652,7 +2653,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);
@@ -2670,7 +2670,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;
@@ -2681,7 +2681,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;
@@ -2694,10 +2694,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)),
@@ -2706,7 +2706,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;
@@ -2766,8 +2766,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);
@@ -2828,7 +2826,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;

@@ -2844,8 +2842,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 |
@@ -2861,8 +2859,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 {
/*
@@ -2880,7 +2878,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);

@@ -3137,7 +3135,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 */
@@ -3146,8 +3144,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 */

@@ -3160,8 +3159,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);
@@ -3172,7 +3169,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);
@@ -3217,10 +3214,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));
@@ -3240,7 +3236,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);
@@ -3251,18 +3247,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);
}

@@ -3304,7 +3300,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);

@@ -3387,8 +3383,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)
@@ -3481,7 +3475,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;
@@ -3557,7 +3551,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
@@ -3738,8 +3731,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);
@@ -3762,7 +3755,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;
}
@@ -3936,7 +3930,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;
}
@@ -3947,8 +3941,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;
@@ -4012,6 +4006,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) {
@@ -4084,8 +4082,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;
}

@@ -4103,7 +4101,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;
@@ -4218,8 +4216,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;
}
@@ -4232,8 +4230,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;

@@ -4252,14 +4248,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;
}
@@ -4431,13 +4427,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;

@@ -4709,8 +4705,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;

@@ -4966,7 +4963,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,
@@ -5003,7 +5000,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,
@@ -5042,8 +5039,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);

@@ -5075,7 +5070,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))
@@ -5116,8 +5111,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);
}
@@ -5177,8 +5172,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;

@@ -5205,8 +5198,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;

@@ -5255,12 +5246,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)
@@ -5373,7 +5365,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;
}
@@ -6021,7 +6013,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
@@ -6144,7 +6136,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;
@@ -6154,6 +6146,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;
@@ -6170,7 +6163,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;
@@ -6181,8 +6174,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;
}
@@ -6203,15 +6196,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;
@@ -6219,20 +6212,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;
@@ -6301,7 +6294,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;
@@ -6434,7 +6427,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;
}
@@ -6461,7 +6454,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;
}
@@ -6541,8 +6534,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 */
@@ -6712,7 +6706,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__);
}
@@ -7106,14 +7101,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],
@@ -7146,7 +7143,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)));
@@ -7398,7 +7395,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__);
}

/*
@@ -7417,7 +7415,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__);
}
}
@@ -7427,12 +7425,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__);
}
}
@@ -7843,8 +7841,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);
@@ -7940,10 +7939,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;
@@ -7964,7 +7962,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;
}
}
@@ -7974,7 +7972,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;
}
@@ -7992,7 +7990,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",
@@ -8006,8 +8004,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);
}

@@ -8025,7 +8023,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-10-26 14:24:02

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 06/18] 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.

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 ba6dbf4..a59954f 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_have_debug_level(LOG_ERROR_VAL)) {
+ if (brcm_have_debug_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 5edd84b..0df2d65 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -287,7 +287,7 @@ struct edcf_acparam {
/* debug/trace */
uint brcm_msg_level =
#if defined(DEBUG)
- LOG_ERROR_VAL;
+ BRCM_DL_INFO;
#else
0;
#endif /* DEBUG */
@@ -908,7 +908,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
mcl = le16_to_cpu(txh->MacTxControlLow);

if (txs->phyerr) {
- if (brcm_have_debug_level(LOG_ERROR_VAL)) {
+ if (brcm_have_debug_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 a6c91f3..079ca73 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -248,7 +248,7 @@

#define BCMMSG(dev, fmt, args...) \
do { \
- if (brcm_have_debug_level(LOG_TRACE_VAL)) \
+ if (brcm_have_debug_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 4652d3c..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-10-26 14:24:04

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 07/18] 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 0df2d65..fbc39b1 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -285,12 +285,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-10-26 14:24:13

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 10/18] 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]>
---
.../net/wireless/brcm80211/brcmsmac/brcms_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/brcms_debug.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
index ab7f516..12f513b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_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 a5fafb0..09cca57 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -652,8 +652,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;
@@ -813,8 +814,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];

@@ -842,7 +843,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);
@@ -1730,8 +1731,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);

@@ -2654,8 +2655,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
@@ -2722,8 +2723,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
@@ -3783,7 +3784,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;
@@ -3869,7 +3871,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;

@@ -5984,8 +5987,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
@@ -6003,8 +6007,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);
}

@@ -6012,8 +6017,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
@@ -6067,8 +6073,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;
@@ -6183,9 +6190,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 {
@@ -7474,8 +7481,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-10-26 16:05:03

by Seth Forshee

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

On Fri, Oct 26, 2012 at 05:37:14PM +0200, Arend van Spriel wrote:
> On 10/26/2012 04:23 PM, Seth Forshee wrote:
> >I've been looking into the issues with brcmsmac performance reported at
> >[0] and [1]. I started out looking into the tx queueing based on the "No
> >where to go" messages in the logs. This code has a number of
> >shortcomings:
> >
> > - The amount of bufferring is excessive. The tx queue will buffer up to
> > 228 packets, and each of the tx DMA rings will queue up to 256 more.
> >
> > - There's no flow control. If the queue fills up packets begin to get
> > dropped, as evidenced by the "No where to go" messages.
> >
> > - Without flow control the tx queue probably helps avoid dropping
> > packets for short bursts due to the sheer number of packets that will
> > be buffered, but if flow control is added the only remaining benefit
> > that I can see is that it accumulates packets for aggregation. The tx
> > queue is far more complex than needed for supporting aggergation,
> > however.
>
> Thanks, Seth
>
> Nice series that rolled out of your sleeve ;-) We seem to have been
> working in parallel here, which is a bit of a pity. One of the
> things that we noticed was indeed missing flow control. We did not
> start adding that so not work wasted there.

Hopefully there wasn't too much overlap. I had actually planned to send
these a couple of weeks ago, but I just kept finding little things I
wanted to improve before sending :-)

> >As a result I worked up the following patches to add flow control remove
> >the tx queue.
> >
> >These patches change the tx handler to directly hand off packets to the
> >DMA code. The convoluted priority->precedence->fifo mapping is converted
> >to a simple one-to-one mapping of the mac80211 queues to fifos. Non-
> >aggregate frames are immediately inserted into the DMA ring.
>
> We considered this during mainlining brcmsmac. So retries are also
> queued back on the DMA fifo?

Yes. I've rearranged the stack of tx function calls so that
brcms_c_txfifo() handles flow control and handing off to the DMA code,
and this is what gets called for retransmitting. But the retries are
actually something that I was curious about, so maybe you can answer
some questions for me while we're in Barcelona.

> >Handling of aggregate frames is not as simple, as some of the tx header
> >fixups can only happen once we have all the frames for an AMPDU. To
> >support this without resyncing buffers after they've been added to the
> >DMA ring I've added the concept of AMPDU sessions. An AMPDU session
> >simply queues up the frames for a single AMPDU until we are ready to
> >insert them into the tx ring. There is one session per DMA ring, and
> >descriptors are reserved in the corresponding ring for all frames queued
> >in the AMPDU session. This also has the benefit of allowing non-
> >aggregate frames to be sent without affecting aggregation and without
> >mapping these frames to a different fifo.
> >
> >The patches also add flow control to stop incoming tx packets when the
> >DMA ring is full. In practice I found that we will sometimes receive a
> >single frame from mac80211 after stopping the queues, so some headroom
> >is reserved when stopping the queues. I also reduced the number of tx
> >descriptors per ring to 64 and fixed a bug that prevented having
> >differing non-zero numbers of tx and rx descriptors for a given ring.
> >
> >When workig on this I made extensive use of ftrace for debug and
> >verification. I'm including patches I wrote which expand the trace
> >support and introduce debug macros which can log messages both to dmesg
> >and the trace buffer. iwlwifi has similar trace support which we've
> >enabled in Ubuntu, making it easier to collect debug information from
> >users experiencing wireless problems.
> >
> >With these changes I'm no longer seeing dropped frames when the tx
> >queues are full. Anecdotally I'd also say that my testing with iperf
> >using TCP seems to show more consistent data rates, resulting in a
> >higher average data rate (sometimes significantly so), but I don't have
> >sufficient amounts of data to be sure this is the case.
> >
> >I'm still observing a few problems when testing with iperf, however. The
> >first is "Pkt tx suppressed, illegal channel" messages. There are also
>
> This is tx status feedback coming in directly from ucode. Not found
> any clues there yet.

This is what I'm probably going to look into next. I think the
interaction with mac80211 and brcmsmac wrt scanning might be going bad
somehow, i.e. not all the frames get transmitted before the channel
change occurs, but I really don't understand yet exactly how the
interaction here is supposed to work. I have found that when this
happens the channel in the txh->XtraFrameTypes doesn't match the current
channel.

I probably won't get to that until after wireless mini-summit though, as
I've got two weeks solid of conferences coming up.

> >large drops in the data rate reported when using TCP, sometimes even
> >resulting in iperf reporting that no data was transferred for several
> >seconds. Finally, when using iperf with UDP the number of dropped frames
> >periodically spikes to high levels. I'm not sure yet, but it looks like
> >the second and third problems may coincide with scanning.

Just to note, I'm also wondering if this might be to some degree related
to the illegal channel problems. If the channel is getting changed with
frames still queued for tx then the nullfunc frame to enable powersave
may not be getting transmitted to the AP. The problem with this theory
is that the illegal channel message doesn't always coincide with the
poor performance and dropped frames.

> >I also continue to see flush timeouts, but the frequency seems to be
> >reduced with these changes. Likely this is related to the much smaller
> >number of packets that will be queued internally for tx.
>
> Last week we have been making progress on the flush timeout so a
> patch is queued up for that.

Excellent. Have you published that publicly yet or is it just queued
internally?

> Again, thanks for putting a bit of love into brcmsmac. Hope you did
> not curse too much in that process ;-) I will publish it internally
> on our review server so we can provide our comments.
>
> See you in Barcelona ;-)

Looking forward to meeting up in person!

Seth


2012-10-26 14:24:27

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 16/18] brcmsmac: Add tracepoint for macintstatus

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 28c08f6..075ca46 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -2559,13 +2559,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))
@@ -2578,7 +2578,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-10-26 14:23:53

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 02/18] 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.

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-10-26 14:24:15

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 11/18] brcmsmac: Add RX and TX debug macros

Also convert relevant messages over to use thses macros.

Signed-off-by: Seth Forshee <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/brcms_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/brcms_debug.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
index 12f513b..2b3ca0d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_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 09cca57..d6a7076 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -888,7 +888,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;
}
@@ -931,9 +931,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 =
@@ -1045,7 +1045,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;
@@ -1056,7 +1055,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;
@@ -1534,8 +1533,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);
@@ -7837,7 +7835,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);
@@ -7895,7 +7893,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-10-26 14:24:31

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 18/18] brcmsmac: Remove some noisy but uninformative debug messages

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

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 f860324..987fb56 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 075ca46..9262c00 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -653,10 +653,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);
@@ -4950,8 +4946,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 */
@@ -5785,9 +5779,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
@@ -5805,9 +5796,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);
}

@@ -5815,9 +5803,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
@@ -5871,10 +5856,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);
@@ -7279,9 +7260,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) +
@@ -7635,8 +7613,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);

@@ -7693,7 +7669,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-10-26 14:24:17

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 12/18] brcmsmac: Add INT debug macro

Also convert relevant message to use this macro.

Signed-off-by: Seth Forshee <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/brcms_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/brcms_debug.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
index 2b3ca0d..16f7304 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_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 d6a7076..ba64b38 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -2349,8 +2349,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 "
@@ -2547,8 +2547,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))
@@ -7956,8 +7956,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-10-26 14:23:59

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 05/18] brcm80211: Add macro for checking if debug log levels are enabled

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

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index bfb04ec..ba6dbf4 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_have_debug_level(LOG_ERROR_VAL)) {
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 9b6b1e7..5edd84b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -908,7 +908,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_have_debug_level(LOG_ERROR_VAL)) {
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..a6c91f3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -244,9 +244,11 @@
* ********************************************************************
*/

+#define brcm_have_debug_level(l) (brcm_msg_level & (l))
+
#define BCMMSG(dev, fmt, args...) \
do { \
- if (brcm_msg_level & LOG_TRACE_VAL) \
+ if (brcm_have_debug_level(LOG_TRACE_VAL)) \
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..4652d3c 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -79,8 +79,8 @@
#define PM_MAX 1

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

#define PM_OFF 0
#define PM_MAX 1
--
1.7.9.5


2012-10-26 14:23:55

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 03/18] 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 2dd0e4f..9b6b1e7 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -238,8 +238,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-10-26 14:24:22

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 14/18] brcmsmac: Add 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 ++++++++++----------
.../net/wireless/brcm80211/brcmsmac/brcms_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 279b1a5..581b7ef 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/brcms_debug.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
index 5bfe97f..a278aa2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_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..9722279 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 "brcms_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-10-26 14:24:20

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 13/18] brcmsmac: Add DMA debug macro

Also convert relevant messages to use this macro.

Signed-off-by: Seth Forshee <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/brcms_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/brcms_debug.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
index 16f7304..5bfe97f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_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..5b5dd3c 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 "brcms_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 ba64b38..2073f08 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1159,7 +1159,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]);

/*
@@ -1170,8 +1170,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]);

/*
@@ -1181,8 +1180,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
@@ -1192,7 +1190,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-10-26 14:23:57

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 04/18] 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. This option is selected by
CONFIG_BRCMDBG, leaving behavior of that option unchanged.

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

diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index c9d811e..9e90a23 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -63,8 +63,20 @@ 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
+ select BRCM_TRACING
---help---
Selecting this enables additional code for debug purposes.
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-10-26 14:24:29

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 17/18] brcmsmac: Add tracepoint for AMPDU session information

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 5b5dd3c..f860324 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 "brcms_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-10-26 14:24:06

by Seth Forshee

[permalink] [raw]
Subject: [PATCH 08/18] 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 +-
.../net/wireless/brcm80211/brcmsmac/brcms_debug.c | 44 +++++++++++++
.../net/wireless/brcm80211/brcmsmac/brcms_debug.h | 40 ++++++++++++
.../brcm80211/brcmsmac/brcms_trace_events.h | 68 +++++++++++++++++++-
4 files changed, 151 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.c
create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index e227c4c..4126023 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 \
+ brcms_debug.o

MODULEPFX := brcmsmac

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.c b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.c
new file mode 100644
index 0000000..11ea96c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.c
@@ -0,0 +1,44 @@
+#include <linux/net.h>
+#include "types.h"
+#include "brcms_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_have_debug_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/brcms_debug.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_debug.h
new file mode 100644
index 0000000..ab7f516
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_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_ */
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
--
1.7.9.5


2012-11-14 16:06:05

by Seth Forshee

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

Hi Arend,

I've got v2 patches prepped with your request changes, which I'll send
as soon as I'm finished testing. I did have a question about one of your
requests though.

On Sun, Nov 04, 2012 at 09:25:49PM +0100, Seth Forshee wrote:
> On Sat, Nov 03, 2012 at 06:56:43PM +0100, Arend van Spriel wrote:
> > > brcmsmac: Add module parameter for setting the debug level
> >
> > I would prefer doing this through debugfs.

I mentioned this to you at the wireless summit. If this is moved to
debugfs it will not allow for setting the debug level at module load
time. If we leave it a module parameter it can still be set at runtime
via /sys/module/parameters/brcmsmac/debug, assuming BRCMDBG is enabled.
I currently don't have this change in my v2 patches, but if you still
want it changed to debugfs let me know and I'll take care of it.

Thanks,
Seth

2012-11-06 12:16:59

by Daniel Wagner

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

On 06.11.2012 11:02, Seth Forshee wrote:
> On Tue, Nov 06, 2012 at 09:19:11AM +0100, Daniel Wagner wrote:
>> On 06.11.2012 08:12, Daniel Wagner wrote:
>>> Hi Seth,
>>>
>>> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
>>> (read broken). Since a few days I am using it and the situation improved
>>
>> it = your patch set on top of 3.7-rc3
>
> Thanks for the report. I'm currently running these patches on top of
> 3.7-rc3 as well, but I haven't run into this.
>
> I'm at a conference and haven't had time to look at this in depth, but

Me too. LinuxCon Europe? :)


2012-11-06 12:27:45

by Daniel Wagner

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

Hi Piotr,

On 06.11.2012 11:44, Piotr Haber wrote:
> On 11/06/12 11:20, Arend van Spriel wrote:
>> On 11/06/2012 09:19 AM, Daniel Wagner wrote:
>>> On 06.11.2012 08:12, Daniel Wagner wrote:
>>>> Hi Seth,
>>>>
>>>> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
>>>> (read broken). Since a few days I am using it and the situation improved
>>>
>>> it = your patch set on top of 3.7-rc3
>>>
>>> (/me should not write emails right after getting up)
>>>
>>>
>>
>> Just looked at the screen shots. Only could read the last one. It seems
>> to indicate a problem in the receive path.
>>
>> Gr. AvS
> Hi Daniel,
>
> could you describe your hardware (lspci -nn), infrastructure (iw wlanx
> link/scan) and kernel version?

Sure, forgot to include this details in the beginning.

$ lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation Ivy Bridge DRAM Controller [8086:0154] (rev 09)
00:02.0 VGA compatible controller [0300]: Intel Corporation Device [8086:0166] (rev 09)
00:14.0 USB Controller [0c03]: Intel Corporation Panther Point USB xHCI Host Controller [8086:1e31] (rev 04)
00:16.0 Communication controller [0780]: Intel Corporation Panther Point MEI Controller #1 [8086:1e3a] (rev 04)
00:1a.0 USB Controller [0c03]: Intel Corporation Panther Point USB Enhanced Host Controller #2 [8086:1e2d] (rev 04)
00:1b.0 Audio device [0403]: Intel Corporation Panther Point High Definition Audio Controller [8086:1e20] (rev 04)
00:1c.0 PCI bridge [0604]: Intel Corporation Panther Point PCI Express Root Port 1 [8086:1e10] (rev c4)
00:1c.1 PCI bridge [0604]: Intel Corporation Panther Point PCI Express Root Port 2 [8086:1e12] (rev c4)
00:1c.4 PCI bridge [0604]: Intel Corporation Panther Point PCI Express Root Port 5 [8086:1e18] (rev c4)
00:1d.0 USB Controller [0c03]: Intel Corporation Panther Point USB Enhanced Host Controller #1 [8086:1e26] (rev 04)
00:1f.0 ISA bridge [0601]: Intel Corporation Panther Point LPC Controller [8086:1e56] (rev 04)
00:1f.2 SATA controller [0106]: Intel Corporation Panther Point 6 port SATA AHCI Controller [8086:1e03] (rev 04)
00:1f.3 SMBus [0c05]: Intel Corporation Panther Point SMBus Controller [8086:1e22] (rev 04)
02:00.0 Network controller [0280]: Broadcom Corporation BCM43224 802.11a/b/g/n [14e4:4353] (rev 01)


$ iw wlan0 link
Connected to 10:8c:cf:b5:f7:4f (on wlan0)
SSID: Linux Foundation
freq: 5220
RX: 9419107 bytes (15520 packets)
TX: 353310 bytes (3027 packets)
signal: -63 dBm
tx bitrate: 72.2 MBit/s MCS 7 short GI

bss flags: short-slot-time
dtim period: 0
beacon int: 102



$ sudo iw wlan0 scan
BSS 00:0c:f6:e4:75:7e (on wlan0)
TSF: 8817869184 usec (0d, 02:26:57)
freq: 2462
beacon interval: 100
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -73.00 dBm
last seen: 3394 ms ago
Information elements from Probe Response frame:
SSID: SitecomE4757E
Supported rates: 1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0
DS Parameter set: channel 11
Country: JP Environment: Indoor/Outdoor
Channels [1 - 14] @ 20 dBm
ERP: <no flags>
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: (0x0000)
Extended supported rates: 24.0 36.0 48.0 54.0
HT capabilities:
Capabilities: 0x116e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
RX STBC 1-stream
Max AMSDU length: 3839 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: No restriction (0x00)
HT RX MCS rate indexes supported: 0-7
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 11
* secondary channel offset: below
* STA channel width: any
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 1
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
WPS: * Version: 1.0
* Wi-Fi Protected Setup State: 2 (Configured)
* Response Type: 3 (AP)
* UUID: c38c440e-404a-5a97-acbd-f9b0b51bfed5
* Manufacturer: Sitecom
* Model: BR6229SN
* Model Number: BR6229SN
* Serial Number: Serial Number Here
* Primary Device Type: 6-0050f204-1
* Device name: WLR-1000
* Config methods: Ethernet, Label
* RF Bands: 0x1
BSS 10:8c:cf:b5:f7:4f (on wlan0) -- associated
TSF: 279284657996 usec (3d, 05:34:44)
freq: 5220
beacon interval: 102
capability: ESS Privacy SpectrumMgmt (0x0111)
signal: -61.00 dBm
last seen: 431 ms ago
Information elements from Probe Response frame:
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
Country: ES Environment: Indoor/Outdoor
Channels [36 - 64] @ 23 dBm
Channels [100 - 116] @ 23 dBm
Channels [132 - 140] @ 30 dBm
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 44
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS b8:62:1f:e4:0e:7f (on wlan0)
TSF: 15285338189 usec (0d, 04:14:45)
freq: 5220
beacon interval: 102
capability: ESS Privacy SpectrumMgmt (0x0111)
signal: -76.00 dBm
last seen: 390 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x5 Bitmap[0] 0x20 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [36 - 64] @ 23 dBm
Channels [100 - 116] @ 23 dBm
Channels [132 - 140] @ 30 dBm
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 44
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS b8:62:1f:e8:21:bf (on wlan0)
TSF: 16586969125 usec (0d, 04:36:26)
freq: 5220
beacon interval: 102
capability: ESS Privacy SpectrumMgmt (0x0111)
signal: -83.00 dBm
last seen: 2572 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x0 Bitmap[0] 0x0 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [36 - 64] @ 23 dBm
Channels [100 - 116] @ 23 dBm
Channels [132 - 140] @ 30 dBm
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 44
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 00:1e:4a:58:61:90 (on wlan0)
TSF: 7705607782467 usec (89d, 04:26:47)
freq: 5520
beacon interval: 100
capability: ESS SpectrumMgmt (0x0101)
signal: -79.00 dBm
last seen: 1571 ms ago
SSID: kubi_MeetingRooms
Supported rates: 6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
WMM: * Parameter version 1
* u-APSD
* BE: CW 31-1023, AIFSN 3
* BK: CW 31-1023, AIFSN 7
* VI: CW 15-31, AIFSN 2, TXOP 3008 usec
* VO: CW 7-15, AIFSN 2, TXOP 1504 usec
BSS d8:24:bd:a7:42:d0 (on wlan0)
TSF: 7705682534452 usec (89d, 04:28:02)
freq: 5180
beacon interval: 102
capability: ESS SpectrumMgmt (0x0101)
signal: -79.00 dBm
last seen: 3084 ms ago
SSID: kubi_MeetingRooms
Supported rates: 6.0* 9.0 12.0* 18.0 24.0* 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 36
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS d8:24:bd:da:c9:40 (on wlan0)
TSF: 7705513642036 usec (89d, 04:25:13)
freq: 5200
beacon interval: 102
capability: ESS SpectrumMgmt (0x0101)
signal: -64.00 dBm
last seen: 2914 ms ago
SSID: kubi_MeetingRooms
Supported rates: 6.0* 9.0 12.0* 18.0 24.0* 36.0 48.0 54.0
TIM: DTIM Count 1 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 40
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS d8:24:bd:e9:38:20 (on wlan0)
TSF: 7705516044840 usec (89d, 04:25:16)
freq: 2462
beacon interval: 102
capability: ESS ShortPreamble ShortSlotTime (0x0421)
signal: -76.00 dBm
last seen: 3415 ms ago
Information elements from Probe Response frame:
SSID: kubi_MeetingRooms
Supported rates: 1.0* 2.0* 5.5* 6.0 9.0 11.0* 12.0 18.0
DS Parameter set: channel 11
ERP: Use_Protection
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
Extended supported rates: 24.0 36.0 48.0 54.0
HT operation:
* primary channel: 11
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS d8:24:bd:db:36:80 (on wlan0)
TSF: 7705515835444 usec (89d, 04:25:15)
freq: 5180
beacon interval: 102
capability: ESS SpectrumMgmt (0x0101)
signal: -51.00 dBm
last seen: 3053 ms ago
SSID: kubi_MeetingRooms
Supported rates: 6.0* 9.0 12.0* 18.0 24.0* 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 36
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 8c:b6:4f:2a:4e:a0 (on wlan0)
TSF: 265350875173 usec (3d, 01:42:30)
freq: 2462
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -70.00 dBm
last seen: 3653 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 11
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x3 Bitmap[0] 0x80 (+ 7 octets)
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 11
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 00:1e:4a:55:f5:70 (on wlan0)
TSF: 7705581261196 usec (89d, 04:26:21)
freq: 2462
beacon interval: 100
capability: ESS ShortPreamble ShortSlotTime (0x0421)
signal: -78.00 dBm
last seen: 28054 ms ago
SSID: kubi_MeetingRooms
Supported rates: 1.0* 2.0 5.5 6.0 9.0 11.0 12.0 18.0
DS Parameter set: channel 11
TIM: DTIM Count 1 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
ERP: Use_Protection
Extended supported rates: 24.0 36.0 48.0 54.0
WMM: * Parameter version 1
* u-APSD
* BE: CW 31-1023, AIFSN 3
* BK: CW 31-1023, AIFSN 7
* VI: CW 15-31, AIFSN 2, TXOP 6016 usec
* VO: CW 7-15, AIFSN 2, TXOP 3264 usec
BSS b8:62:1f:e8:21:60 (on wlan0)
TSF: 93501222948 usec (1d, 01:58:21)
freq: 2412
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -78.00 dBm
last seen: 4487 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 1
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x4 Bitmap[0] 0x80 (+ 19 octets)
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 1
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 20:aa:4b:d5:f0:a9 (on wlan0)
TSF: 10973564083 usec (0d, 03:02:53)
freq: 2447
beacon interval: 100
capability: ESS Privacy ShortSlotTime (0x0411)
signal: -77.00 dBm
last seen: 4023 ms ago
Information elements from Probe Response frame:
SSID: Collabora BCN
Supported rates: 1.0* 2.0* 5.5* 11.0* 18.0 24.0 36.0 54.0
DS Parameter set: channel 8
ERP: <no flags>
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 16-PTKSA-RC (0x000c)
Extended supported rates: 6.0 9.0 12.0 48.0
HT capabilities:
Capabilities: 0x18fc
HT20
SM Power Save disabled
RX Greenfield
RX HT20 SGI
RX HT40 SGI
TX STBC
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 8
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
Extended capabilities: HT Information Exchange Supported
WPS: * Version: 1.0
* Wi-Fi Protected Setup State: 2 (Configured)
* Selected Registrar: 0x0
* Response Type: 3 (AP)
* UUID: 28135e4d-044e-c3d8-9d3f-6b860ed1afb6
* Manufacturer: Cisco
* Model: Linksys E2500
* Model Number: v1.0.03
* Serial Number: 42
* Primary Device Type: 6-0050f204-1
* Device name: Linksys E2500
* Config methods: Label, PBC
* RF Bands: 0x3
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS be:e4:8a:f4:5c:36 (on wlan0)
TSF: 517326589 usec (0d, 00:08:37)
freq: 2462
beacon interval: 100
capability: IBSS (0x0002)
signal: -84.00 dBm
last seen: 24133 ms ago
SSID: treasure01
Supported rates: 1.0* 2.0 5.5 11.0 6.0 9.0 12.0 18.0
DS Parameter set: channel 11
Extended supported rates: 24.0 36.0 48.0 54.0
WMM: information: 01 00
BSS 10:8c:cf:b5:e9:60 (on wlan0)
TSF: 262876815396 usec (3d, 01:01:16)
freq: 2412
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -82.00 dBm
last seen: 4474 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 1
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x1 Bitmap[0] 0x0 (+ 27 octets)
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 1
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS c4:0a:cb:64:93:20 (on wlan0)
TSF: 1133067673976 usec (13d, 02:44:27)
freq: 2412
beacon interval: 102
capability: ESS ShortPreamble ShortSlotTime (0x0421)
signal: -82.00 dBm
last seen: 28991 ms ago
SSID: kubi
Supported rates: 1.0* 2.0* 5.5* 6.0 9.0 11.0* 12.0 18.0
DS Parameter set: channel 1
TIM: DTIM Count 1 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x2 (+ 3 octets)
ERP: Use_Protection
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
Extended supported rates: 24.0 36.0 48.0 54.0
HT operation:
* primary channel: 1
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 00:02:cf:e2:3b:fd (on wlan0)
TSF: 15629314173 usec (0d, 04:20:29)
freq: 2472
beacon interval: 100
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -90.00 dBm
last seen: 3428 ms ago
SSID: WLAN_0A
Supported rates: 1.0* 2.0* 5.5* 11.0* 22.0
DS Parameter set: channel 13
TIM: DTIM Count 1 DTIM Period 3 Bitmap Control 0x0 Bitmap[0] 0x0 (+ 8 octets)
ERP: <no flags>
Extended supported rates: 6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0
BSS 00:1e:4a:33:1d:e0 (on wlan0)
TSF: 7705496576593 usec (89d, 04:24:56)
freq: 2412
beacon interval: 100
capability: ESS ShortPreamble ShortSlotTime (0x0421)
signal: -78.00 dBm
last seen: 24268 ms ago
SSID: kubi_MeetingRooms
Supported rates: 1.0* 2.0 5.5 6.0 9.0 11.0 12.0 18.0
DS Parameter set: channel 1
TIM: DTIM Count 0 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
ERP: Use_Protection
Extended supported rates: 24.0 36.0 48.0 54.0
WMM: * Parameter version 1
* u-APSD
* BE: CW 31-1023, AIFSN 3
* BK: CW 31-1023, AIFSN 7
* VI: CW 15-31, AIFSN 2, TXOP 6016 usec
* VO: CW 7-15, AIFSN 2, TXOP 3264 usec
BSS d8:24:bd:b5:0e:e0 (on wlan0)
TSF: 5464302090616 usec (63d, 05:51:42)
freq: 2412
beacon interval: 102
capability: ESS ShortPreamble ShortSlotTime (0x0421)
signal: -83.00 dBm
last seen: 4326 ms ago
Information elements from Probe Response frame:
SSID: kubi_MeetingRooms
Supported rates: 1.0* 2.0* 5.5* 6.0 9.0 11.0* 12.0 18.0
DS Parameter set: channel 1
ERP: Use_Protection
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
Extended supported rates: 24.0 36.0 48.0 54.0
HT operation:
* primary channel: 1
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 30:46:9a:7f:0e:f7 (on wlan0)
TSF: 778689641701 usec (9d, 00:18:09)
freq: 2462
beacon interval: 100
capability: ESS Privacy ShortSlotTime (0x0411)
signal: -90.00 dBm
last seen: 24128 ms ago
SSID: wilduri
Supported rates: 1.0* 2.0* 5.5* 11.0* 18.0 24.0 36.0 54.0
DS Parameter set: channel 11
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x0 Bitmap[0] 0x0
ERP: Barker_Preamble_Mode
RSN: * Version: 1
* Group cipher: TKIP
* Pairwise ciphers: CCMP TKIP
* Authentication suites: PSK
* Capabilities: 16-PTKSA-RC (0x000c)
Extended supported rates: 6.0 9.0 12.0 48.0
HT capabilities:
Capabilities: 0x187c
HT20
SM Power Save disabled
RX Greenfield
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 11
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 1
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WPS: * Version: 1.0
* Wi-Fi Protected Setup State: 2 (Configured)
WPA: * Version: 1
* Group cipher: TKIP
* Pairwise ciphers: CCMP TKIP
* Authentication suites: PSK
* Capabilities: 16-PTKSA-RC (0x000c)
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 10:8c:cf:b5:f7:40 (on wlan0)
TSF: 279281418277 usec (3d, 05:34:41)
freq: 2412
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -60.00 dBm
last seen: 4483 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 1
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x0 Bitmap[0] 0x0 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 1
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 8c:b6:4f:2a:5a:60 (on wlan0)
TSF: 251997720612 usec (2d, 21:59:57)
freq: 2412
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -76.00 dBm
last seen: 4449 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 1
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x0 Bitmap[0] 0x0
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 1
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS d8:24:bd:e8:99:20 (on wlan0)
TSF: 7705513145141 usec (89d, 04:25:13)
freq: 2437
beacon interval: 102
capability: ESS ShortPreamble ShortSlotTime (0x0421)
signal: -65.00 dBm
last seen: 6 ms ago
Information elements from Probe Response frame:
SSID: kubi_MeetingRooms
Supported rates: 1.0* 2.0* 5.5* 6.0 9.0 11.0* 12.0 18.0
DS Parameter set: channel 6
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
Extended supported rates: 24.0 36.0 48.0 54.0
HT operation:
* primary channel: 6
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 5c:33:8e:e3:f6:6b (on wlan0)
TSF: 26771968454 usec (0d, 07:26:11)
freq: 2437
beacon interval: 100
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -91.00 dBm
last seen: 4144 ms ago
SSID: Orange-602e
Supported rates: 1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0
DS Parameter set: channel 6
TIM: DTIM Count 0 DTIM Period 3 Bitmap Control 0x0 Bitmap[0] 0x0
ERP: Use_Protection
RSN: * Version: 1
* Group cipher: TKIP
* Pairwise ciphers: CCMP TKIP
* Authentication suites: PSK
* Capabilities: (0x0000)
WPA: * Version: 1
* Group cipher: TKIP
* Pairwise ciphers: CCMP TKIP
* Authentication suites: PSK
Extended supported rates: 24.0 36.0 48.0 54.0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
HT capabilities:
Capabilities: 0x104c
HT20
SM Power Save disabled
RX HT40 SGI
No RX STBC
Max AMSDU length: 3839 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 6
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 0
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
WPS: * Version: 1.0
* Wi-Fi Protected Setup State: 2 (Configured)
* AP setup locked: 0x00
* UUID: 988b5d2e-602e-988b-5d2e-602e5d2e602e
* RF Bands: 0x1
BSS 10:8c:cf:b5:c4:b0 (on wlan0)
TSF: 15281995812 usec (0d, 04:14:41)
freq: 2437
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -60.00 dBm
last seen: 4143 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 6
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0xd Bitmap[0] 0x0 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 6
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS b8:62:1f:e4:0e:70 (on wlan0)
TSF: 15283041222 usec (0d, 04:14:43)
freq: 2462
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -75.00 dBm
last seen: 3615 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 11
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x0 Bitmap[0] 0x0
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 11
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS b8:62:1f:e8:21:b0 (on wlan0)
TSF: 16586760228 usec (0d, 04:36:26)
freq: 2462
beacon interval: 102
capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
signal: -81.00 dBm
last seen: 3612 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
DS Parameter set: channel 11
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x1 Bitmap[0] 0x0 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [1 - 13] @ 20 dBm
ERP: <no flags>
HT capabilities:
Capabilities: 0x182c
HT20
SM Power Save disabled
RX HT20 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 11
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: nonmember
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 10:8c:cf:b5:c4:bf (on wlan0)
TSF: 15282100261 usec (0d, 04:14:42)
freq: 5180
beacon interval: 102
capability: ESS Privacy SpectrumMgmt (0x0111)
signal: -70.00 dBm
last seen: 3113 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0xc Bitmap[0] 0x0 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [36 - 64] @ 23 dBm
Channels [100 - 116] @ 23 dBm
Channels [132 - 140] @ 30 dBm
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 36
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 1
* HT protection: no
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec
BSS 8c:b6:4f:2a:4e:af (on wlan0)
TSF: 265350979621 usec (3d, 01:42:30)
freq: 5240
beacon interval: 102
capability: ESS Privacy SpectrumMgmt (0x0111)
signal: -73.00 dBm
last seen: 2739 ms ago
SSID: Linux Foundation
Supported rates: 12.0* 18.0* 24.0 36.0 48.0 54.0
TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x15 Bitmap[0] 0x0 (+ 3 octets)
Country: ES Environment: Indoor/Outdoor
Channels [36 - 64] @ 23 dBm
Channels [100 - 116] @ 23 dBm
Channels [132 - 140] @ 30 dBm
HT capabilities:
Capabilities: 0x186e
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
No RX STBC
Max AMSDU length: 7935 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT RX MCS rate indexes supported: 0-15
HT TX MCS rate indexes are undefined
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
HT operation:
* primary channel: 48
* secondary channel offset: no secondary
* STA channel width: 20 MHz
* RIFS: 0
* HT protection: non-HT mixed
* non-GF present: 1
* OBSS non-GF present: 0
* dual beacon: 0
* dual CTS protection: 0
* STBC beacon: 0
* L-SIG TXOP Prot: 0
* PCO active: 0
* PCO phase: 0
WMM: * Parameter version 1
* u-APSD
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec

I applied the patches on top of Linus' tree:

1e207eb1c3f0e8b690401f02fe08e7b53903f010

> I was trying Seth's patches with 4313 and 43224 devices on 3.7-rc3 as
> well and did not run into anything like this.

What I did was to resume the laptop and told ConnMan me that the automatic
connect to to connect to 'Linux Foundation' network failed and then I told
ConnMan to try again to connect. That triggered the panic. I don't have
any logs for this.

cheers,
daniel

2012-11-06 10:46:09

by Piotr Haber

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

On 11/06/12 11:20, Arend van Spriel wrote:
> On 11/06/2012 09:19 AM, Daniel Wagner wrote:
>> On 06.11.2012 08:12, Daniel Wagner wrote:
>>> Hi Seth,
>>>
>>> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
>>> (read broken). Since a few days I am using it and the situation improved
>>
>> it = your patch set on top of 3.7-rc3
>>
>> (/me should not write emails right after getting up)
>>
>>
>
> Just looked at the screen shots. Only could read the last one. It seems
> to indicate a problem in the receive path.
>
> Gr. AvS
Hi Daniel,

could you describe your hardware (lspci -nn), infrastructure (iw wlanx
link/scan) and kernel version?

I was trying Seth's patches with 4313 and 43224 devices on 3.7-rc3 as
well and did not run into anything like this.


Thanks
Piotr


2012-11-03 17:56:58

by Arend van Spriel

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

On 10/26/2012 04:23 PM, Seth Forshee wrote:
> I've been looking into the issues with brcmsmac performance reported at
> [0] and [1]. I started out looking into the tx queueing based on the "No
> where to go" messages in the logs. This code has a number of
> shortcomings:
>
> - The amount of bufferring is excessive. The tx queue will buffer up to
> 228 packets, and each of the tx DMA rings will queue up to 256 more.
>
> - There's no flow control. If the queue fills up packets begin to get
> dropped, as evidenced by the "No where to go" messages.
>
> - Without flow control the tx queue probably helps avoid dropping
> packets for short bursts due to the sheer number of packets that will
> be buffered, but if flow control is added the only remaining benefit
> that I can see is that it accumulates packets for aggregation. The tx
> queue is far more complex than needed for supporting aggergation,
> however.
>
> As a result I worked up the following patches to add flow control remove
> the tx queue.
>
> These patches change the tx handler to directly hand off packets to the
> DMA code. The convoluted priority->precedence->fifo mapping is converted
> to a simple one-to-one mapping of the mac80211 queues to fifos. Non-
> aggregate frames are immediately inserted into the DMA ring.

I mentioned earlier we were still looking at the first patch in this
series and do more testing on it. However, I wanted to provide feedback
on the other patches now. See below.

> Thanks,
> Seth
>
> [0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1046507
> [1] http://www.spinics.net/lists/linux-wireless/msg96287.html
>
>
> Seth Forshee (18):
> brcmsmac: Rework tx code to avoid internal buffering of packets

under test

> brcmsmac: Use correct descriptor count when calculating next rx
> descriptor

nice catch. acked.

> brcmsmac: Reduce number of entries in tx DMA rings

under test.

> brcm80211: Allow trace support to be enabled separately from debug

A bit confusing with BRCMDBG selecting BRCMS_TRACING.

> brcm80211: Add macro for checking if debug log levels are enabled

During mainlining we got rid of such a macro. Strange to put something
similar back in there.

> brcm80211: Convert log message levels to debug levels

acked.

> brcmsmac: Add module parameter for setting the debug level

I would prefer doing this through debugfs.

> brcmsmac: Add support for writing debug messages to the trace buffer

can you name the new files just debug.[ch]

> brcmsmac: Use debug macros for general error and debug statements

acked.

> brcmsmac: Add BRCMS_DBG_MAC80211 debug macro
> brcmsmac: Add RX and TX debug macros
> brcmsmac: Add INT debug macro
> brcmsmac: Add DMA debug macro
> brcmsmac: Add HT debug macro

I would prefer the macros to be in lower case.

> brcmsmac: Improve tx trace and debug support

acked.

> brcmsmac: Add tracepoint for macintstatus

useful one. acked.

> brcmsmac: Add tracepoint for AMPDU session information

acked.

> brcmsmac: Remove some noisy but uninformative debug messages

acked. I would say: noisy *and* uninformative but that is just semantics ;-)

Regards,
AvS


2012-11-06 08:19:17

by Daniel Wagner

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

On 06.11.2012 08:12, Daniel Wagner wrote:
> Hi Seth,
>
> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
> (read broken). Since a few days I am using it and the situation improved

it = your patch set on top of 3.7-rc3

(/me should not write emails right after getting up)


2012-11-04 20:25:55

by Seth Forshee

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

On Sat, Nov 03, 2012 at 06:56:43PM +0100, Arend van Spriel wrote:
> On 10/26/2012 04:23 PM, Seth Forshee wrote:
> > I've been looking into the issues with brcmsmac performance reported at
> > [0] and [1]. I started out looking into the tx queueing based on the "No
> > where to go" messages in the logs. This code has a number of
> > shortcomings:
> >
> > - The amount of bufferring is excessive. The tx queue will buffer up to
> > 228 packets, and each of the tx DMA rings will queue up to 256 more.
> >
> > - There's no flow control. If the queue fills up packets begin to get
> > dropped, as evidenced by the "No where to go" messages.
> >
> > - Without flow control the tx queue probably helps avoid dropping
> > packets for short bursts due to the sheer number of packets that will
> > be buffered, but if flow control is added the only remaining benefit
> > that I can see is that it accumulates packets for aggregation. The tx
> > queue is far more complex than needed for supporting aggergation,
> > however.
> >
> > As a result I worked up the following patches to add flow control remove
> > the tx queue.
> >
> > These patches change the tx handler to directly hand off packets to the
> > DMA code. The convoluted priority->precedence->fifo mapping is converted
> > to a simple one-to-one mapping of the mac80211 queues to fifos. Non-
> > aggregate frames are immediately inserted into the DMA ring.
>
> I mentioned earlier we were still looking at the first patch in this
> series and do more testing on it. However, I wanted to provide feedback
> on the other patches now. See below.
>
> > Thanks,
> > Seth
> >
> > [0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1046507
> > [1] http://www.spinics.net/lists/linux-wireless/msg96287.html
> >
> >
> > Seth Forshee (18):
> > brcmsmac: Rework tx code to avoid internal buffering of packets
>
> under test
>
> > brcmsmac: Use correct descriptor count when calculating next rx
> > descriptor
>
> nice catch. acked.
>
> > brcmsmac: Reduce number of entries in tx DMA rings
>
> under test.
>
> > brcm80211: Allow trace support to be enabled separately from debug
>
> A bit confusing with BRCMDBG selecting BRCMS_TRACING.

I did this so that the effect of selecting BRCMDBG was unchanged, since
currently tracing is enabled by BRCMDBG. I'm happy to change it so that
BRCMDBG does not select BRCMS_TRACING if you prefer.

> > brcm80211: Add macro for checking if debug log levels are enabled
>
> During mainlining we got rid of such a macro. Strange to put something
> similar back in there.

I wasn't aware of that. I personally prefer the macro, but I can change
it back to open coding the checks.

> > brcm80211: Convert log message levels to debug levels
>
> acked.
>
> > brcmsmac: Add module parameter for setting the debug level
>
> I would prefer doing this through debugfs.

Okay, I'll change that for v2.

> > brcmsmac: Add support for writing debug messages to the trace buffer
>
> can you name the new files just debug.[ch]

I'll change this for v2 as well.

> > brcmsmac: Use debug macros for general error and debug statements
>
> acked.
>
> > brcmsmac: Add BRCMS_DBG_MAC80211 debug macro
> > brcmsmac: Add RX and TX debug macros
> > brcmsmac: Add INT debug macro
> > brcmsmac: Add DMA debug macro
> > brcmsmac: Add HT debug macro
>
> I would prefer the macros to be in lower case.

Will do.

> > brcmsmac: Improve tx trace and debug support
>
> acked.
>
> > brcmsmac: Add tracepoint for macintstatus
>
> useful one. acked.
>
> > brcmsmac: Add tracepoint for AMPDU session information
>
> acked.
>
> > brcmsmac: Remove some noisy but uninformative debug messages
>
> acked. I would say: noisy *and* uninformative but that is just semantics ;-)

Yes, "and" would be better here.

Thanks for the feedback!

Seth

2012-11-02 10:49:48

by Karl Beldan

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

Hi,

On Fri, Oct 26, 2012 at 09:23:15AM -0500, Seth Forshee wrote:
> I've been looking into the issues with brcmsmac performance reported at
> [0] and [1]. I started out looking into the tx queueing based on the "No
> where to go" messages in the logs. This code has a number of
> shortcomings:
>
> - The amount of bufferring is excessive. The tx queue will buffer up to
> 228 packets, and each of the tx DMA rings will queue up to 256 more.
>
> - There's no flow control. If the queue fills up packets begin to get
> dropped, as evidenced by the "No where to go" messages.
>
> - Without flow control the tx queue probably helps avoid dropping
> packets for short bursts due to the sheer number of packets that will
> be buffered, but if flow control is added the only remaining benefit
> that I can see is that it accumulates packets for aggregation. The tx
> queue is far more complex than needed for supporting aggergation,
> however.
>
> As a result I worked up the following patches to add flow control remove
> the tx queue.
>
> These patches change the tx handler to directly hand off packets to the
> DMA code. The convoluted priority->precedence->fifo mapping is converted
> to a simple one-to-one mapping of the mac80211 queues to fifos. Non-
> aggregate frames are immediately inserted into the DMA ring.
>
> Handling of aggregate frames is not as simple, as some of the tx header
> fixups can only happen once we have all the frames for an AMPDU. To
> support this without resyncing buffers after they've been added to the
> DMA ring I've added the concept of AMPDU sessions. An AMPDU session
> simply queues up the frames for a single AMPDU until we are ready to
> insert them into the tx ring. There is one session per DMA ring, and
> descriptors are reserved in the corresponding ring for all frames queued
> in the AMPDU session. This also has the benefit of allowing non-
> aggregate frames to be sent without affecting aggregation and without
> mapping these frames to a different fifo.
>
> The patches also add flow control to stop incoming tx packets when the
> DMA ring is full. In practice I found that we will sometimes receive a
> single frame from mac80211 after stopping the queues, so some headroom
> is reserved when stopping the queues. I also reduced the number of tx
> descriptors per ring to 64 and fixed a bug that prevented having
> differing non-zero numbers of tx and rx descriptors for a given ring.
>
It is strange that you would get one frame after stopping the queues.
Apart from the iface up/down code which I did not look at, it seems the tx
codepaths for queues stop/wake are all properly protected by spin_lock_bhs.
You mention a possible race in your code comments .. are you referring to
mac80211 or the driver itself ?

> When workig on this I made extensive use of ftrace for debug and
> verification. I'm including patches I wrote which expand the trace
> support and introduce debug macros which can log messages both to dmesg
> and the trace buffer. iwlwifi has similar trace support which we've
> enabled in Ubuntu, making it easier to collect debug information from
> users experiencing wireless problems.
>
> With these changes I'm no longer seeing dropped frames when the tx
> queues are full. Anecdotally I'd also say that my testing with iperf
> using TCP seems to show more consistent data rates, resulting in a
> higher average data rate (sometimes significantly so), but I don't have
> sufficient amounts of data to be sure this is the case.
>
Stopping the queues instead of dropping the skb, the TCP tx throughput should
improve.


Karl

2012-11-06 12:49:39

by Arend van Spriel

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

On 11/06/2012 01:47 PM, Seth Forshee wrote:
> On Tue, Nov 06, 2012 at 01:16:56PM +0100, Daniel Wagner wrote:
>> On 06.11.2012 11:02, Seth Forshee wrote:
>>> On Tue, Nov 06, 2012 at 09:19:11AM +0100, Daniel Wagner wrote:
>>>> On 06.11.2012 08:12, Daniel Wagner wrote:
>>>>> Hi Seth,
>>>>>
>>>>> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
>>>>> (read broken). Since a few days I am using it and the situation improved
>>>>
>>>> it = your patch set on top of 3.7-rc3
>>>
>>> Thanks for the report. I'm currently running these patches on top of
>>> 3.7-rc3 as well, but I haven't run into this.
>>>
>>> I'm at a conference and haven't had time to look at this in depth, but
>>
>> Me too. LinuxCon Europe? :)
>
> Yep :-)
>

Dito. What are you attending now?

Gr. AvS


2012-11-06 07:12:26

by Daniel Wagner

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

Hi Seth,

I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
(read broken). Since a few days I am using it and the situation improved
considerable. Unfortunately, suspend resume had just triggered a kernel
panic. Here a few crappy photos of the crash. Sorry the quality is
rather bad but maybe you can see spot something.

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

cheers,
daniel

2012-11-02 07:28:36

by Seth Forshee

[permalink] [raw]
Subject: Re: [PATCH 01/18] brcmsmac: Rework tx code to avoid internal buffering of packets

On Thu, Nov 01, 2012 at 06:43:28PM +0100, Arend van Spriel wrote:
> On 10/26/2012 04:23 PM, Seth Forshee wrote:
> >The brcmsmac internal tx buffering is problematic for a number of
> >reasons. The amount of buffering is excessive (228 packets in addition
> >to the 256 slots in each DMA ring), frames may be dropped due to a lack
> >of flow control, and the structure of the queues complicates the
> >otherwise straightforward mapping of mac80211 queues to device fifos.
> >
> >This patch reworks the transmit code path to eliminate the internal
> >buffering. Frames are immediately handed off to the DMA support rather
> >than passing through an intermediate queue. ieee80211_(stop|wake)_queue()
> >are used for flow control to stop receiving frames when a DMA tx ring is
> >full.
> >
> >To handle aggregation the concept of AMPDU sessions is added to the
> >driver. The AMPDU session allows MPDUs to be temporarily queued by the
> >DMA code until either a full AMPDU has been collected or circumstances
> >dictate that transmission should start with a partial AMPDU. The use of
> >a queue ensures that the tx headers are fully initialized before the
> >buffers are synced for DMA, and it allows non-aggregate frames to be
> >immediately placed in the tx ring so that more frames can be collected
> >for aggregation.
> >
> >Signed-off-by: Seth Forshee <[email protected]>
> >---
> > drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 666 ++++++++++-------------
> > drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 29 +-
> > drivers/net/wireless/brcm80211/brcmsmac/dma.c | 182 ++++++-
> > drivers/net/wireless/brcm80211/brcmsmac/dma.h | 9 +-
> > drivers/net/wireless/brcm80211/brcmsmac/main.c | 514 +++++------------
> > drivers/net/wireless/brcm80211/brcmsmac/main.h | 39 +-
> > drivers/net/wireless/brcm80211/brcmsmac/types.h | 1 -
> > 7 files changed, 628 insertions(+), 812 deletions(-)
>
> Hi Seth,
>
> The idea behind the change is a good move. However, this change is
> quite a overhaul especially for ampdu code. This makes it pretty
> hard to review. At least against the previous implementation. So we
> still need some time to chew on this one. We have been testing it
> and it looks good there.

Great!

The AMPDU changes do look significant, but in large part they're just
rearranging the code.

> Could you somehow split this change into smaller steps?

I'd given a little thought to breaking it up before I sent the patches,
but for the bulk of the changes it's a little challenging to do so
without making some of the commits regress (e.g. break AMPDU in one
commit then fix it in the next one). I'll take a closer look while I'm
travelling and see if I can work something out.

Thanks,
Seth

2012-11-01 17:43:44

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH 01/18] brcmsmac: Rework tx code to avoid internal buffering of packets

On 10/26/2012 04:23 PM, Seth Forshee wrote:
> The brcmsmac internal tx buffering is problematic for a number of
> reasons. The amount of buffering is excessive (228 packets in addition
> to the 256 slots in each DMA ring), frames may be dropped due to a lack
> of flow control, and the structure of the queues complicates the
> otherwise straightforward mapping of mac80211 queues to device fifos.
>
> This patch reworks the transmit code path to eliminate the internal
> buffering. Frames are immediately handed off to the DMA support rather
> than passing through an intermediate queue. ieee80211_(stop|wake)_queue()
> are used for flow control to stop receiving frames when a DMA tx ring is
> full.
>
> To handle aggregation the concept of AMPDU sessions is added to the
> driver. The AMPDU session allows MPDUs to be temporarily queued by the
> DMA code until either a full AMPDU has been collected or circumstances
> dictate that transmission should start with a partial AMPDU. The use of
> a queue ensures that the tx headers are fully initialized before the
> buffers are synced for DMA, and it allows non-aggregate frames to be
> immediately placed in the tx ring so that more frames can be collected
> for aggregation.
>
> Signed-off-by: Seth Forshee <[email protected]>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 666 ++++++++++-------------
> drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | 29 +-
> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 182 ++++++-
> drivers/net/wireless/brcm80211/brcmsmac/dma.h | 9 +-
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 514 +++++------------
> drivers/net/wireless/brcm80211/brcmsmac/main.h | 39 +-
> drivers/net/wireless/brcm80211/brcmsmac/types.h | 1 -
> 7 files changed, 628 insertions(+), 812 deletions(-)

Hi Seth,

The idea behind the change is a good move. However, this change is quite
a overhaul especially for ampdu code. This makes it pretty hard to
review. At least against the previous implementation. So we still need
some time to chew on this one. We have been testing it and it looks good
there.

Could you somehow split this change into smaller steps?

Gr. Avs


2012-11-06 12:54:49

by Seth Forshee

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

On Tue, Nov 06, 2012 at 01:27:42PM +0100, Daniel Wagner wrote:
> Hi Piotr,
>
> On 06.11.2012 11:44, Piotr Haber wrote:
> > On 11/06/12 11:20, Arend van Spriel wrote:
> >> On 11/06/2012 09:19 AM, Daniel Wagner wrote:
> >>> On 06.11.2012 08:12, Daniel Wagner wrote:
> >>>> Hi Seth,
> >>>>
> >>>> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
> >>>> (read broken). Since a few days I am using it and the situation improved
> >>>
> >>> it = your patch set on top of 3.7-rc3
> >>>
> >>> (/me should not write emails right after getting up)
> >>>
> >>>
> >>
> >> Just looked at the screen shots. Only could read the last one. It seems
> >> to indicate a problem in the receive path.
> >>
> >> Gr. AvS
> > Hi Daniel,
> >
> > could you describe your hardware (lspci -nn), infrastructure (iw wlanx
> > link/scan) and kernel version?
>
> Sure, forgot to include this details in the beginning.
>
> $ lspci -nn
> 00:00.0 Host bridge [0600]: Intel Corporation Ivy Bridge DRAM Controller [8086:0154] (rev 09)
> 00:02.0 VGA compatible controller [0300]: Intel Corporation Device [8086:0166] (rev 09)
> 00:14.0 USB Controller [0c03]: Intel Corporation Panther Point USB xHCI Host Controller [8086:1e31] (rev 04)
> 00:16.0 Communication controller [0780]: Intel Corporation Panther Point MEI Controller #1 [8086:1e3a] (rev 04)
> 00:1a.0 USB Controller [0c03]: Intel Corporation Panther Point USB Enhanced Host Controller #2 [8086:1e2d] (rev 04)
> 00:1b.0 Audio device [0403]: Intel Corporation Panther Point High Definition Audio Controller [8086:1e20] (rev 04)
> 00:1c.0 PCI bridge [0604]: Intel Corporation Panther Point PCI Express Root Port 1 [8086:1e10] (rev c4)
> 00:1c.1 PCI bridge [0604]: Intel Corporation Panther Point PCI Express Root Port 2 [8086:1e12] (rev c4)
> 00:1c.4 PCI bridge [0604]: Intel Corporation Panther Point PCI Express Root Port 5 [8086:1e18] (rev c4)
> 00:1d.0 USB Controller [0c03]: Intel Corporation Panther Point USB Enhanced Host Controller #1 [8086:1e26] (rev 04)
> 00:1f.0 ISA bridge [0601]: Intel Corporation Panther Point LPC Controller [8086:1e56] (rev 04)
> 00:1f.2 SATA controller [0106]: Intel Corporation Panther Point 6 port SATA AHCI Controller [8086:1e03] (rev 04)
> 00:1f.3 SMBus [0c05]: Intel Corporation Panther Point SMBus Controller [8086:1e22] (rev 04)
> 02:00.0 Network controller [0280]: Broadcom Corporation BCM43224 802.11a/b/g/n [14e4:4353] (rev 01)
>
>
> $ iw wlan0 link
> Connected to 10:8c:cf:b5:f7:4f (on wlan0)
> SSID: Linux Foundation

<snip>

I'm running with the same card in the same environment but haven't had
any problems at all.

> I applied the patches on top of Linus' tree:
>
> 1e207eb1c3f0e8b690401f02fe08e7b53903f010
>
> > I was trying Seth's patches with 4313 and 43224 devices on 3.7-rc3 as
> > well and did not run into anything like this.
>
> What I did was to resume the laptop and told ConnMan me that the automatic
> connect to to connect to 'Linux Foundation' network failed and then I told
> ConnMan to try again to connect. That triggered the panic. I don't have
> any logs for this.

Do you have logs for the failed connection attempt before the panic? If
so I'd be interested in seeing them.

Seth


2012-11-06 12:47:51

by Seth Forshee

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

On Tue, Nov 06, 2012 at 01:16:56PM +0100, Daniel Wagner wrote:
> On 06.11.2012 11:02, Seth Forshee wrote:
> >On Tue, Nov 06, 2012 at 09:19:11AM +0100, Daniel Wagner wrote:
> >>On 06.11.2012 08:12, Daniel Wagner wrote:
> >>>Hi Seth,
> >>>
> >>>I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
> >>>(read broken). Since a few days I am using it and the situation improved
> >>
> >>it = your patch set on top of 3.7-rc3
> >
> >Thanks for the report. I'm currently running these patches on top of
> >3.7-rc3 as well, but I haven't run into this.
> >
> >I'm at a conference and haven't had time to look at this in depth, but
>
> Me too. LinuxCon Europe? :)

Yep :-)

2012-11-14 19:41:24

by Arend van Spriel

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

On 11/14/2012 05:05 PM, Seth Forshee wrote:
> Hi Arend,
>
> I've got v2 patches prepped with your request changes, which I'll send
> as soon as I'm finished testing. I did have a question about one of your
> requests though.
>
> On Sun, Nov 04, 2012 at 09:25:49PM +0100, Seth Forshee wrote:
>> On Sat, Nov 03, 2012 at 06:56:43PM +0100, Arend van Spriel wrote:
>>>> brcmsmac: Add module parameter for setting the debug level
>>>
>>> I would prefer doing this through debugfs.
>
> I mentioned this to you at the wireless summit. If this is moved to
> debugfs it will not allow for setting the debug level at module load
> time. If we leave it a module parameter it can still be set at runtime
> via /sys/module/parameters/brcmsmac/debug, assuming BRCMDBG is enabled.
> I currently don't have this change in my v2 patches, but if you still
> want it changed to debugfs let me know and I'll take care of it.
>
> Thanks,
> Seth

Indeed we discussed it. I do not have a strong preference and having it
set during module init has its perks. So you can leave it as it is. I am
looking forward to your v2 patches ;-)

Gr. AvS



2012-11-06 10:21:07

by Arend van Spriel

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

On 11/06/2012 09:19 AM, Daniel Wagner wrote:
> On 06.11.2012 08:12, Daniel Wagner wrote:
>> Hi Seth,
>>
>> I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
>> (read broken). Since a few days I am using it and the situation improved
>
> it = your patch set on top of 3.7-rc3
>
> (/me should not write emails right after getting up)
>
>

Just looked at the screen shots. Only could read the last one. It seems
to indicate a problem in the receive path.

Gr. AvS


2012-11-06 10:02:18

by Seth Forshee

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

On Tue, Nov 06, 2012 at 09:19:11AM +0100, Daniel Wagner wrote:
> On 06.11.2012 08:12, Daniel Wagner wrote:
> >Hi Seth,
> >
> >I am owner of a MBA 2012 and the mainline driver is kind of 'not fun'
> >(read broken). Since a few days I am using it and the situation improved
>
> it = your patch set on top of 3.7-rc3

Thanks for the report. I'm currently running these patches on top of
3.7-rc3 as well, but I haven't run into this.

I'm at a conference and haven't had time to look at this in depth, but
at a glance I'm not seeing any obvious connection with my changes. If
we're processing a channel switch as suggested by the stack trace then
there aren't any calls back into brcmsmac in this context that I can
find, since brcmsmac isn't providing a channel_switch op. But I'll look
more closely when I get a chance.

Seth

2012-11-04 20:11:39

by Seth Forshee

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

On Sat, Nov 03, 2012 at 02:50:22PM +0100, Karl Beldan wrote:
> On Sat, Nov 03, 2012 at 12:15:57PM +0100, Johannes Berg wrote:
> > On Fri, 2012-11-02 at 11:49 +0100, Karl Beldan wrote:
> >
> > > > The patches also add flow control to stop incoming tx packets when the
> > > > DMA ring is full. In practice I found that we will sometimes receive a
> > > > single frame from mac80211 after stopping the queues, so some headroom
> > > > is reserved when stopping the queues. I also reduced the number of tx
> > > > descriptors per ring to 64 and fixed a bug that prevented having
> > > > differing non-zero numbers of tx and rx descriptors for a given ring.
> > > >
> > > It is strange that you would get one frame after stopping the queues.
> > > Apart from the iface up/down code which I did not look at, it seems the tx
> > > codepaths for queues stop/wake are all properly protected by spin_lock_bhs.
> > > You mention a possible race in your code comments .. are you referring to
> > > mac80211 or the driver itself ?
> >
> > It's generally a race between mac80211 and the driver, if the driver
> > uses ieee80211_stop_queue() outside the TX path, the TX path can be
> > handing it a packet at the exact same time, and therefore there can be
> > one packet (on each queue!) that goes to the driver during the call to
> > stop_queue().

This is what I suspected ...

> Yes, yet in this case, it seems to be another pb.
> The driver performs ieee80211_stop_queue() inside the TX path exept for the
> call within the tx status callback tasklet for ampdu retries - and the latter
> should not trigger the pb since, as the comment puts it:
> {
> /*
> * We shouldn't be out of space in the DMA
> * ring here since we're reinserting a frame
> * that was just pulled out.
> */
> }
> At first sight I would more likely doubt the txavail, though I haven't really
> looked into the code, the potential race caught my attention within the diff
> and I thought it might be useful to follow up.

... but this is also true. The truth is that I need to go back and check
for this situation again, because the extra frame may not actually be
happening any more. The flow control was a little different in earlier
iterations of this patch, and I can't say for sure whether or not I
checked again after it changed.

I did check previously that the queue really was stopped when these
"extra" frames came in, and it always was. That points to some kind of
race.

Seth

2012-11-03 13:50:35

by Karl Beldan

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

On Sat, Nov 03, 2012 at 12:15:57PM +0100, Johannes Berg wrote:
> On Fri, 2012-11-02 at 11:49 +0100, Karl Beldan wrote:
>
> > > The patches also add flow control to stop incoming tx packets when the
> > > DMA ring is full. In practice I found that we will sometimes receive a
> > > single frame from mac80211 after stopping the queues, so some headroom
> > > is reserved when stopping the queues. I also reduced the number of tx
> > > descriptors per ring to 64 and fixed a bug that prevented having
> > > differing non-zero numbers of tx and rx descriptors for a given ring.
> > >
> > It is strange that you would get one frame after stopping the queues.
> > Apart from the iface up/down code which I did not look at, it seems the tx
> > codepaths for queues stop/wake are all properly protected by spin_lock_bhs.
> > You mention a possible race in your code comments .. are you referring to
> > mac80211 or the driver itself ?
>
> It's generally a race between mac80211 and the driver, if the driver
> uses ieee80211_stop_queue() outside the TX path, the TX path can be
> handing it a packet at the exact same time, and therefore there can be
> one packet (on each queue!) that goes to the driver during the call to
> stop_queue().
>
Yes, yet in this case, it seems to be another pb.
The driver performs ieee80211_stop_queue() inside the TX path exept for the
call within the tx status callback tasklet for ampdu retries - and the latter
should not trigger the pb since, as the comment puts it:
{
/*
* We shouldn't be out of space in the DMA
* ring here since we're reinserting a frame
* that was just pulled out.
*/
}
At first sight I would more likely doubt the txavail, though I haven't really
looked into the code, the potential race caught my attention within the diff
and I thought it might be useful to follow up.


Karl

2012-11-03 11:15:22

by Johannes Berg

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

On Fri, 2012-11-02 at 11:49 +0100, Karl Beldan wrote:

> > The patches also add flow control to stop incoming tx packets when the
> > DMA ring is full. In practice I found that we will sometimes receive a
> > single frame from mac80211 after stopping the queues, so some headroom
> > is reserved when stopping the queues. I also reduced the number of tx
> > descriptors per ring to 64 and fixed a bug that prevented having
> > differing non-zero numbers of tx and rx descriptors for a given ring.
> >
> It is strange that you would get one frame after stopping the queues.
> Apart from the iface up/down code which I did not look at, it seems the tx
> codepaths for queues stop/wake are all properly protected by spin_lock_bhs.
> You mention a possible race in your code comments .. are you referring to
> mac80211 or the driver itself ?

It's generally a race between mac80211 and the driver, if the driver
uses ieee80211_stop_queue() outside the TX path, the TX path can be
handing it a packet at the exact same time, and therefore there can be
one packet (on each queue!) that goes to the driver during the call to
stop_queue().

johannes