summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmsmac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-01-11 13:28:19 -0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-11 13:28:19 -0200
commit734d1ece37fbf3d2ddfc71bc6c69e0fe35f02542 (patch)
treec4805dd7e746b1feb9e09e9849f3245d0b2c0c6b /drivers/net/wireless/brcm80211/brcmsmac
parent216c82c6aba63eeb49d7654b448e0d47bea255bb (diff)
parent9931faca02c604c22335f5a935a501bb2ace6e20 (diff)
Merge tag 'v3.8-rc3' into v4l_for_linus
Linux 3.8-rc3 * tag 'v3.8-rc3': (11110 commits) Linux 3.8-rc3 mm: reinstante dropped pmd_trans_splitting() check cred: Remove tgcred pointer from struct cred drm/ttm: fix fence locking in ttm_buffer_object_transfer ARM: clps711x: Fix bad merge of clockevents setup ARM: highbank: save and restore L2 cache and GIC on suspend ARM: highbank: add a power request clear ARM: highbank: fix secondary boot and hotplug ARM: highbank: fix typos with hignbank in power request functions ARM: dts: fix highbank cpu mpidr values ARM: dts: add device_type prop to cpu nodes on Calxeda platforms drm/prime: drop reference on imported dma-buf come from gem xen/netfront: improve truesize tracking ARM: mx5: Fix MX53 flexcan2 clock ARM: OMAP2+: am33xx-hwmod: Fix wrongly terminated am33xx_usbss_mpu_irqs array sctp: fix Kconfig bug in default cookie hmac selection EDAC: Cleanup device deregistering path EDAC: Fix EDAC Kconfig menu EDAC: Fix kernel panic on module unloading ALSA: hda - add mute LED for HP Pavilion 17 (Realtek codec) ...
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmsmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c723
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.h29
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h175
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.c156
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.h76
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c345
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.h11
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c157
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c1261
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.h48
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c471
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c64
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h42
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/types.h3
19 files changed, 1803 insertions, 1789 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
index e227c4c68ef..d3d4151c3ed 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -40,7 +40,8 @@ BRCMSMAC_OFILES := \
phy/phytbl_n.o \
phy/phy_qmath.o \
dma.o \
- brcms_trace_events.o
+ brcms_trace_events.o \
+ debug.o
MODULEPFX := brcmsmac
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index b89f1272b93..f0888a9ee32 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -692,7 +692,7 @@ void ai_pci_up(struct si_pub *sih)
sii = container_of(sih, struct si_info, pub);
if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
- bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
+ bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true);
}
/* Unconfigure and/or apply various WARs when going down */
@@ -703,7 +703,7 @@ void ai_pci_down(struct si_pub *sih)
sii = container_of(sih, struct si_info, pub);
if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
- bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
+ bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false);
}
/* Enable BT-COEX & Ex-PA for 4313 */
@@ -721,7 +721,7 @@ void ai_epa_4313war(struct si_pub *sih)
/* check if the device is removed */
bool ai_deviceremoved(struct si_pub *sih)
{
- u32 w;
+ u32 w = 0;
struct si_info *sii;
sii = container_of(sih, struct si_info, pub);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index be5bcfb9153..1de94f30564 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -21,6 +21,8 @@
#include "antsel.h"
#include "main.h"
#include "ampdu.h"
+#include "debug.h"
+#include "brcms_trace_events.h"
/* max number of mpdus in an ampdu */
#define AMPDU_MAX_MPDU 32
@@ -40,8 +42,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 +114,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 +135,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];
@@ -183,18 +181,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;
@@ -247,7 +246,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;
/*
@@ -374,7 +372,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;
@@ -396,8 +395,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.
@@ -450,9 +449,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 */
@@ -486,7 +486,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;
}
@@ -498,378 +498,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;
-
- tid = (u8) (p->priority);
+ bool rr;
- f = ampdu->fifo_tb + prio2fifo[tid];
+ 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;
- scb = &wlc->pri_scb;
- scb_ampdu = &scb->scb_ampdu;
- ini = &scb_ampdu->ini[tid];
+ ampdu_frames = skb_queue_len(&session->skb_list);
+ if (ampdu_frames != 0) {
+ struct sk_buff *first;
- /* 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;
+ if (ampdu_frames + 1 > session->max_ampdu_frames ||
+ session->ampdu_len + len > session->max_ampdu_len)
+ return -ENOSPC;
- /* 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);
-
- /* retrieve null delimiter count */
- ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
- seg_cnt += 1;
+ plcp0 = txh->FragPLCPFallback[0];
+ plcp3 = txh->FragPLCPFallback[3];
- 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;
+
+ 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
@@ -909,7 +855,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];
@@ -955,13 +900,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 */
@@ -977,20 +923,14 @@ 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) {
update_rate = false;
- wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
+ brcms_err(wlc->hw->d11core,
+ "%s: ampdu tx phy error (0x%x)\n",
__func__, txs->phyerr);
-
- if (brcm_msg_level & LOG_ERROR_VAL) {
- brcmu_prpkt("txpkt (AMPDU)", p);
- brcms_c_print_txdesc((struct d11txh *) p->data);
- }
- brcms_c_print_txstatus(txs);
}
}
@@ -1003,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);
@@ -1012,10 +954,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)) {
@@ -1046,14 +988,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--;
@@ -1064,9 +1008,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);
}
@@ -1080,12 +1024,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
@@ -1133,6 +1074,8 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
while (p) {
tx_info = IEEE80211_SKB_CB(p);
txh = (struct d11txh *) p->data;
+ trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
+ sizeof(*txh));
mcl = le16_to_cpu(txh->MacTxControlLow);
brcmu_pkt_buf_free_skb(p);
/* break out if last packet of ampdu */
@@ -1142,7 +1085,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 +1124,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 +1143,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 421f4ba7c63..73d01e58610 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/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
index 55e12c32791..54c61691959 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
@@ -21,6 +21,7 @@
#include "main.h"
#include "phy_shim.h"
#include "antsel.h"
+#include "debug.h"
#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
@@ -137,7 +138,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
asi->antsel_avail = false;
} else {
asi->antsel_avail = false;
- wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
+ brcms_err(wlc->hw->d11core,
+ "antsel_attach: 2o3 "
"board cfg invalid\n");
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
index 27dd73eef56..871781e6a71 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -14,22 +14,29 @@
* 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
+#include <linux/types.h>
+#include <linux/device.h>
#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) {}
+#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,9 +85,165 @@ 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
+
+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)
+);
+
+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
+
+#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_BRCMDBG
+#ifdef CONFIG_BRCM_TRACING
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
@@ -89,4 +252,4 @@ TRACE_EVENT(brcms_dpc,
#include <trace/define_trace.h>
-#endif /* CONFIG_BRCMDBG */
+#endif /* CONFIG_BRCM_TRACING */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index 64a48f06d68..a90b72202ec 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -26,6 +26,7 @@
#include "stf.h"
#include "channel.h"
#include "mac80211_if.h"
+#include "debug.h"
/* QDB() macro takes a dB value and converts to a quarter dB value */
#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
@@ -336,8 +337,6 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
const char *ccode = sprom->alpha2;
int ccode_len = sizeof(sprom->alpha2);
- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
-
wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
if (wlc_cm == NULL)
return NULL;
@@ -615,8 +614,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec)
/* check the chanspec */
if (brcms_c_chspec_malformed(chspec)) {
- wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
- wlc->pub->unit, chspec);
+ brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n",
+ wlc->pub->unit, chspec);
return false;
}
@@ -738,7 +737,8 @@ static int brcms_reg_notifier(struct wiphy *wiphy,
mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
} else {
mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
- wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n",
+ brcms_err(wlc->hw->d11core,
+ "wl%d: %s: no valid channel for \"%s\"\n",
wlc->pub->unit, __func__, request->alpha2);
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
new file mode 100644
index 00000000000..9761deb4620
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2012 Broadcom Corporation
+ * Copyright (c) 2012 Canonical Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <linux/debugfs.h>
+#include <linux/if_ether.h>
+#include <linux/if.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/ieee80211.h>
+#include <linux/module.h>
+#include <net/mac80211.h>
+
+#include <defs.h>
+#include <brcmu_wifi.h>
+#include <brcmu_utils.h>
+#include "types.h"
+#include "main.h"
+#include "debug.h"
+#include "brcms_trace_events.h"
+
+static struct dentry *root_folder;
+
+void brcms_debugfs_init(void)
+{
+ root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ if (IS_ERR(root_folder))
+ root_folder = NULL;
+}
+
+void brcms_debugfs_exit(void)
+{
+ if (!root_folder)
+ return;
+
+ debugfs_remove_recursive(root_folder);
+ root_folder = NULL;
+}
+
+int brcms_debugfs_attach(struct brcms_pub *drvr)
+{
+ if (!root_folder)
+ return -ENODEV;
+
+ drvr->dbgfs_dir = debugfs_create_dir(
+ dev_name(&drvr->wlc->hw->d11core->dev), root_folder);
+ return PTR_RET(drvr->dbgfs_dir);
+}
+
+void brcms_debugfs_detach(struct brcms_pub *drvr)
+{
+ if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
+ debugfs_remove_recursive(drvr->dbgfs_dir);
+}
+
+struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
+{
+ return drvr->dbgfs_dir;
+}
+
+static
+ssize_t brcms_debugfs_hardware_read(struct file *f, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ char buf[128];
+ int res;
+ struct brcms_pub *drvr = f->private_data;
+
+ /* only allow read from start */
+ if (*ppos > 0)
+ return 0;
+
+ res = scnprintf(buf, sizeof(buf),
+ "board vendor: %x\n"
+ "board type: %x\n"
+ "board revision: %x\n"
+ "board flags: %x\n"
+ "board flags2: %x\n"
+ "firmware revision: %x\n",
+ drvr->wlc->hw->d11core->bus->boardinfo.vendor,
+ drvr->wlc->hw->d11core->bus->boardinfo.type,
+ drvr->wlc->hw->boardrev,
+ drvr->wlc->hw->boardflags,
+ drvr->wlc->hw->boardflags2,
+ drvr->wlc->ucode_rev
+ );
+
+ return simple_read_from_buffer(data, count, ppos, buf, res);
+}
+
+static const struct file_operations brcms_debugfs_hardware_ops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = brcms_debugfs_hardware_read
+};
+
+void brcms_debugfs_create_files(struct brcms_pub *drvr)
+{
+ struct dentry *dentry = drvr->dbgfs_dir;
+
+ if (!IS_ERR_OR_NULL(dentry))
+ debugfs_create_file("hardware", S_IRUGO, dentry,
+ drvr, &brcms_debugfs_hardware_ops);
+}
+
+#define __brcms_fn(fn) \
+void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
+{ \
+ struct va_format vaf = { \
+ .fmt = fmt, \
+ }; \
+ va_list args; \
+ \
+ va_start(args, fmt); \
+ vaf.va = &args; \
+ dev_ ##fn(dev, "%pV", &vaf); \
+ trace_brcms_ ##fn(&vaf); \
+ va_end(args); \
+}
+
+__brcms_fn(info)
+__brcms_fn(warn)
+__brcms_fn(err)
+__brcms_fn(crit)
+
+#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
+void __brcms_dbg(struct device *dev, u32 level, const char *func,
+ const char *fmt, ...)
+{
+ struct va_format vaf = {
+ .fmt = fmt,
+ };
+ va_list args;
+
+ va_start(args, fmt);
+ vaf.va = &args;
+#ifdef CONFIG_BRCMDBG
+ if ((brcm_msg_level & level) && net_ratelimit())
+ dev_err(dev, "%s %pV", func, &vaf);
+#endif
+ trace_brcms_dbg(level, func, &vaf);
+ va_end(args);
+}
+#endif
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
new file mode 100644
index 00000000000..822781cf15d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 Broadcom Corporation
+ * Copyright (c) 2012 Canonical Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#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"
+
+__printf(2, 3)
+void __brcms_info(struct device *dev, const char *fmt, ...);
+__printf(2, 3)
+void __brcms_warn(struct device *dev, const char *fmt, ...);
+__printf(2, 3)
+void __brcms_err(struct device *dev, const char *fmt, ...);
+__printf(2, 3)
+void __brcms_crit(struct device *dev, const char *fmt, ...);
+
+#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
+__printf(4, 5)
+void __brcms_dbg(struct device *dev, u32 level, const char *func,
+ const char *fmt, ...);
+#else
+static inline __printf(4, 5)
+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)
+#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)
+#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)
+
+struct brcms_pub;
+void brcms_debugfs_init(void);
+void brcms_debugfs_exit(void);
+int brcms_debugfs_attach(struct brcms_pub *drvr);
+void brcms_debugfs_detach(struct brcms_pub *drvr);
+struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr);
+void brcms_debugfs_create_files(struct brcms_pub *drvr);
+
+#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 5e53305bd9a..1860c572b3c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -14,17 +14,22 @@
* 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>
+#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"
+#include "debug.h"
+#include "brcms_trace_events.h"
/*
* dma register field offset calculation
@@ -176,28 +181,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 */
@@ -224,12 +207,14 @@ 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;
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 */
@@ -298,12 +283,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)
{
@@ -353,7 +332,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)
@@ -370,10 +349,8 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
{
uint dmactrlflags;
- if (di == NULL) {
- DMA_ERROR("NULL dma handle\n");
+ if (di == NULL)
return 0;
- }
dmactrlflags = di->dma.dmactrlflags;
dmactrlflags &= ~mask;
@@ -423,13 +400,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;
}
@@ -530,8 +509,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);
@@ -544,8 +524,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);
@@ -564,12 +545,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)
+ uint nrxpost, uint rxoffset)
{
+ 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;
@@ -580,9 +562,6 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
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);
@@ -598,11 +577,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
*/
_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);
@@ -664,8 +643,8 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
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) {
@@ -703,21 +682,27 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
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;
}
}
- 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);
+ /* Initialize AMPDU session */
+ brcms_c_ampdu_reset_session(&di->ampdu_session, wlc);
+
+ 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;
@@ -763,7 +748,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)
@@ -839,7 +824,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)) &
@@ -859,7 +844,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;
@@ -954,7 +939,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 */
@@ -981,14 +966,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);
@@ -1005,7 +991,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;
@@ -1016,6 +1002,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
@@ -1047,7 +1044,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;
@@ -1060,9 +1057,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++;
@@ -1107,7 +1106,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);
@@ -1138,7 +1137,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;
@@ -1170,7 +1169,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;
@@ -1182,7 +1181,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;
@@ -1205,11 +1204,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;
@@ -1264,39 +1263,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,23 +1303,147 @@ 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;
+
+ 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;
+
+ 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;
+
+ /* 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;
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++;
- 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);
}
/*
@@ -1354,11 +1463,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;
@@ -1412,13 +1521,13 @@ 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;
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 cc269ee5c49..ff5b80b0904 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
@@ -74,12 +74,11 @@ 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,
- 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);
@@ -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/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index a744ea5a955..1fbd8ecbe2e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -33,6 +33,7 @@
#include "ucode_loader.h"
#include "mac80211_if.h"
#include "main.h"
+#include "debug.h"
#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
@@ -92,16 +93,21 @@ MODULE_FIRMWARE("brcm/bcm43xx_hdr-0.fw");
/* recognized BCMA Core IDs */
static struct bcma_device_id brcms_coreid_table[] = {
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
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),
@@ -276,12 +282,12 @@ 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;
}
- brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
- tx_info->rate_driver_data[0] = control->sta;
+ if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw))
+ tx_info->rate_driver_data[0] = control->sta;
done:
spin_unlock_bh(&wl->lock);
}
@@ -313,8 +319,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;
}
@@ -332,7 +338,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;
}
@@ -350,8 +356,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;
}
@@ -370,9 +377,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) {
@@ -380,25 +387,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) {
@@ -425,13 +433,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);
@@ -491,7 +499,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) {
@@ -508,30 +516,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);
}
@@ -541,8 +549,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;
}
@@ -553,25 +561,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, "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);
@@ -653,8 +661,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);
@@ -681,8 +689,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;
@@ -839,8 +847,10 @@ static void brcms_free(struct brcms_info *wl)
/* kill dpc */
tasklet_kill(&wl->tasklet);
- if (wl->pub)
+ if (wl->pub) {
+ brcms_debugfs_detach(wl->pub);
brcms_c_module_unregister(wl->pub, "linux", wl);
+ }
/* free common resources */
if (wl->wlc) {
@@ -889,27 +899,22 @@ static void brcms_remove(struct bcma_device *pdev)
static irqreturn_t brcms_isr(int irq, void *dev_id)
{
struct brcms_info *wl;
- bool ours, wantdpc;
+ irqreturn_t ret = IRQ_NONE;
wl = (struct brcms_info *) dev_id;
spin_lock(&wl->isr_lock);
/* call common first level interrupt handler */
- ours = brcms_c_isr(wl->wlc, &wantdpc);
- if (ours) {
- /* if more to do... */
- if (wantdpc) {
-
- /* ...and call the second level interrupt handler */
- /* schedule dpc */
- tasklet_schedule(&wl->tasklet);
- }
+ if (brcms_c_isr(wl->wlc)) {
+ /* schedule second level handler */
+ tasklet_schedule(&wl->tasklet);
+ ret = IRQ_HANDLED;
}
spin_unlock(&wl->isr_lock);
- return IRQ_RETVAL(ours);
+ return ret;
}
/*
@@ -1075,6 +1080,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
regulatory_hint(wl->wiphy, wl->pub->srom_ccode))
wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__);
+ brcms_debugfs_attach(wl->pub);
+ brcms_debugfs_create_files(wl->pub);
n_adapters_found++;
return wl;
@@ -1093,7 +1100,7 @@ fail:
*
* Perimeter lock is initialized in the course of this function.
*/
-static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
+static int brcms_bcma_probe(struct bcma_device *pdev)
{
struct brcms_info *wl;
struct ieee80211_hw *hw;
@@ -1144,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;
}
@@ -1160,7 +1166,7 @@ static struct bcma_driver brcms_bcma_driver = {
.probe = brcms_bcma_probe,
.suspend = brcms_suspend,
.resume = brcms_resume,
- .remove = __devexit_p(brcms_remove),
+ .remove = brcms_remove,
.id_table = brcms_coreid_table,
};
@@ -1184,10 +1190,7 @@ 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
+ brcms_debugfs_init();
if (!schedule_work(&brcms_driver_work))
return -EBUSY;
@@ -1205,6 +1208,7 @@ static void __exit brcms_module_exit(void)
{
cancel_work_sync(&brcms_driver_work);
bcma_driver_unregister(&brcms_bcma_driver);
+ brcms_debugfs_exit();
}
module_init(brcms_module_init);
@@ -1216,7 +1220,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 +1228,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 +1239,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 +1253,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 +1401,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 +1492,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 +1516,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 +1525,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 +1567,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 75086b37c81..17594de4199 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -34,12 +34,9 @@
#include "ucode_loader.h"
#include "main.h"
#include "soc.h"
-
-/*
- * Indication for txflowcontrol that all priority bits in
- * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
- */
-#define ALLPRIO -1
+#include "dma.h"
+#include "debug.h"
+#include "brcms_trace_events.h"
/* watchdog timer, in unit of ms */
#define TIMER_INTERVAL_WATCHDOG 1000
@@ -126,21 +123,6 @@
#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */
-/* precedences numbers for wlc queues. These are twice as may levels as
- * 802.1D priorities.
- * Odd numbers are used for HI priority traffic at same precedence levels
- * These constants are used ONLY by wlc_prio2prec_map. Do not use them
- * elsewhere.
- */
-#define _BRCMS_PREC_NONE 0 /* None = - */
-#define _BRCMS_PREC_BK 2 /* BK - Background */
-#define _BRCMS_PREC_BE 4 /* BE - Best-effort */
-#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */
-#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */
-#define _BRCMS_PREC_VI 10 /* Vi - Video */
-#define _BRCMS_PREC_VO 12 /* Vo - Voice */
-#define _BRCMS_PREC_NC 14 /* NC - Network Control */
-
/* synthpu_dly times in us */
#define SYNTHPU_DLY_APHY_US 3700
#define SYNTHPU_DLY_BPHY_US 1050
@@ -237,17 +219,17 @@
#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
+/* 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,24 +265,8 @@ 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)
- LOG_ERROR_VAL;
-#else
- 0;
-#endif /* DEBUG */
+uint brcm_msg_level;
/* TX FIFO number to WME/802.1E Access Category */
static const u8 wme_fifo2ac[] = {
@@ -320,18 +286,6 @@ static const u8 wme_ac2fifo[] = {
TX_AC_BK_FIFO
};
-/* 802.1D Priority to precedence queue mapping */
-const u8 wlc_prio2prec_map[] = {
- _BRCMS_PREC_BE, /* 0 BE - Best-effort */
- _BRCMS_PREC_BK, /* 1 BK - Background */
- _BRCMS_PREC_NONE, /* 2 None = - */
- _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
- _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
- _BRCMS_PREC_VI, /* 5 Vi - Video */
- _BRCMS_PREC_VO, /* 6 Vo - Voice */
- _BRCMS_PREC_NC, /* 7 NC - Network Control */
-};
-
static const u16 xmtfifo_sz[][NFIFO] = {
/* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */
{20, 192, 192, 21, 17, 5},
@@ -371,6 +325,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 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = {
+ [IEEE80211_AC_VO] = TX_AC_VO_FIFO,
+ [IEEE80211_AC_VI] = TX_AC_VI_FIFO,
+ [IEEE80211_AC_BE] = TX_AC_BE_FIFO,
+ [IEEE80211_AC_BK] = TX_AC_BK_FIFO,
+};
+
+/* Mapping of tx fifos to ieee80211 AC numbers */
+static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = {
+ [TX_AC_BK_FIFO] = IEEE80211_AC_BK,
+ [TX_AC_BE_FIFO] = IEEE80211_AC_BE,
+ [TX_AC_VI_FIFO] = IEEE80211_AC_VI,
+ [TX_AC_VO_FIFO] = IEEE80211_AC_VO,
+};
+
+static u8 brcms_ac_to_fifo(u8 ac)
+{
+ if (ac >= ARRAY_SIZE(ac_to_fifo_mapping))
+ return TX_AC_BE_FIFO;
+ return ac_to_fifo_mapping[ac];
+}
+
+static u8 brcms_fifo_to_ac(u8 fifo)
+{
+ if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping))
+ return IEEE80211_AC_BE;
+ return fifo_to_ac_mapping[fifo];
+}
+
/* Find basic rate for a given rate */
static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
{
@@ -415,10 +399,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)
@@ -626,14 +615,11 @@ 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;
}
- BCMMSG(wlc->wiphy, "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);
@@ -696,7 +682,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);
@@ -725,19 +711,19 @@ 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 */
brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
/* do band-specific ucode IHR, SHM, and SCR inits */
- if (D11REV_IS(wlc_hw->corerev, 23)) {
+ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
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)) {
@@ -745,12 +731,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);
}
}
}
@@ -765,7 +753,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;
@@ -790,8 +778,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];
@@ -819,7 +807,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);
@@ -841,9 +829,10 @@ 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 d11txh *txh;
+ struct sk_buff *p = NULL;
+ uint queue = NFIFO;
+ struct dma_pub *dma = NULL;
+ struct d11txh *txh = NULL;
struct scb *scb = NULL;
bool free_pdu;
int tx_rts, tx_frame_count, tx_rts_count;
@@ -854,6 +843,11 @@ 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;
+
+ 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,
@@ -862,34 +856,36 @@ 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;
+ brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n");
+ fatal = false;
+ goto out;
}
queue = txs->frameid & TXFID_QUEUE_MASK;
if (queue >= NFIFO) {
- p = NULL;
- goto fatal;
+ 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)
- goto fatal;
+ if (p == NULL) {
+ brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n");
+ goto out;
+ }
txh = (struct d11txh *) (p->data);
mcl = le16_to_cpu(txh->MacTxControlLow);
- if (txs->phyerr) {
- if (brcm_msg_level & LOG_ERROR_VAL) {
- wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
- txs->phyerr, txh->MainRates);
- brcms_c_print_txdesc(txh);
- }
- brcms_c_print_txstatus(txs);
- }
+ if (txs->phyerr)
+ brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n",
+ txs->phyerr, txh->MainRates);
- if (txs->frameid != le16_to_cpu(txh->TxFrameID))
- goto fatal;
+ 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);
@@ -898,14 +894,24 @@ 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;
}
+ /*
+ * 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)
- BCMMSG(wlc->wiphy,
- "%s: Pkt tx suppressed, possibly channel %d\n",
- __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+ if (supr_status == TX_STATUS_SUPR_BADCH) {
+ unsigned xfts = le16_to_cpu(txh->XtraFrameTypes);
+ brcms_dbg_tx(wlc->hw->d11core,
+ "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 =
@@ -916,7 +922,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.
@@ -982,26 +988,37 @@ 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);
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__);
}
- return false;
+ fatal = false;
- fatal:
- if (p)
- brcmu_pkt_buf_free_skb(p);
+ out:
+ if (fatal) {
+ if (txh)
+ trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
+ sizeof(*txh));
+ if (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
@@ -1011,7 +1028,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;
@@ -1022,19 +1038,23 @@ 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);
-
txs = &txstatus;
core = wlc_hw->d11core;
*fatal = false;
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
while (!(*fatal)
&& (s1 & TXS_V)) {
+ /* !give others some time to run! */
+ if (n >= max_tx_num) {
+ morepending = true;
+ break;
+ }
if (s1 == 0xffffffff) {
- wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
- wlc_hw->unit, __func__);
- return morepending;
+ brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ __func__);
+ *fatal = true;
+ return false;
}
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
@@ -1046,20 +1066,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
- /* !give others some time to run! */
- if (++n >= max_tx_num)
- break;
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
+ n++;
}
if (*fatal)
- return 0;
-
- if (n >= max_tx_num)
- morepending = true;
-
- if (!pktq_empty(&wlc->pkt_queue->q))
- brcms_c_send_q(wlc);
+ return false;
return morepending;
}
@@ -1112,7 +1124,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);
@@ -1125,12 +1136,12 @@ 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,
RXBUFSZ, -1, NRXBUFPOST,
- BRCMS_HWRXOFF, &brcm_msg_level);
+ BRCMS_HWRXOFF);
dma_attach_err |= (NULL == wlc_hw->di[0]);
/*
@@ -1139,10 +1150,9 @@ 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);
+ NTXD, 0, 0, -1, 0, 0);
dma_attach_err |= (NULL == wlc_hw->di[1]);
/*
@@ -1150,26 +1160,26 @@ 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);
+ NTXD, 0, 0, -1, 0, 0);
dma_attach_err |= (NULL == wlc_hw->di[2]);
/*
* FIFO 3
* 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);
+ 0, 0);
dma_attach_err |= (NULL == wlc_hw->di[3]);
/* 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;
}
@@ -1503,8 +1513,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);
@@ -1527,7 +1536,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);
@@ -1700,8 +1709,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);
@@ -1736,8 +1745,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);
@@ -1782,7 +1789,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;
@@ -1916,7 +1923,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
@@ -2005,7 +2012,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;
@@ -2016,13 +2023,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);
}
@@ -2235,7 +2242,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));
@@ -2257,14 +2264,14 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
if (wlc_hw->ucode_loaded)
return;
- if (D11REV_IS(wlc_hw->corerev, 23)) {
+ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
if (BRCMS_ISNPHY(wlc_hw->band)) {
brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
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)) {
@@ -2272,8 +2279,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);
}
}
@@ -2310,7 +2317,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;
@@ -2323,39 +2329,39 @@ 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) {
- 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;
}
@@ -2516,13 +2522,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;
- BCMMSG(wlc->wiphy, "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))
@@ -2535,16 +2541,12 @@ 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)
return 0;
- /* interrupts are already turned off for CFE build
- * Caution: For CFE Turning off the interrupts again has some undesired
- * consequences
- */
/* turn off the interrupts */
bcma_write32(core, D11REGOFFS(macintmask), 0);
(void)bcma_read32(core, D11REGOFFS(macintmask));
@@ -2587,33 +2589,31 @@ bool brcms_c_intrsupd(struct brcms_c_info *wlc)
/*
* First-level interrupt processing.
- * Return true if this was our interrupt, false otherwise.
- * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
+ * Return true if this was our interrupt
+ * and if further brcms_c_dpc() processing is required,
* false otherwise.
*/
-bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
+bool brcms_c_isr(struct brcms_c_info *wlc)
{
struct brcms_hardware *wlc_hw = wlc->hw;
u32 macintstatus;
- *wantdpc = false;
-
if (!wlc_hw->up || !wlc->macintmask)
return false;
/* read and clear macintstatus and intstatus registers */
macintstatus = wlc_intstatus(wlc, true);
- if (macintstatus == 0xffffffff)
- wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
- " path\n");
+ if (macintstatus == 0xffffffff) {
+ brcms_err(wlc_hw->d11core,
+ "DEVICEREMOVED detected in the ISR code path\n");
+ return false;
+ }
/* it is not for us */
if (macintstatus == 0)
return false;
- *wantdpc = true;
-
/* save interrupt status bits */
wlc->macintstatus = macintstatus;
@@ -2626,10 +2626,9 @@ 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);
+ brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit,
+ wlc_hw->band->bandunit);
/*
* Track overlapping suspend requests
@@ -2644,7 +2643,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;
@@ -2655,7 +2654,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;
@@ -2668,10 +2667,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)),
@@ -2680,7 +2679,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;
@@ -2696,8 +2695,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
@@ -2740,8 +2739,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);
@@ -2802,7 +2799,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;
@@ -2818,8 +2815,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 |
@@ -2835,8 +2832,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 {
/*
@@ -2854,7 +2851,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);
@@ -2884,12 +2881,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]);
@@ -2921,7 +2920,7 @@ brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
if (offset & 2)
objoff += 2;
- bcma_write16(core, objoff, v);
+ bcma_wflush16(core, objoff, v);
}
/*
@@ -3109,7 +3108,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 */
@@ -3118,8 +3117,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 */
@@ -3132,8 +3132,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);
@@ -3144,7 +3142,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);
@@ -3189,10 +3187,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));
@@ -3212,29 +3209,29 @@ 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);
sflags = bcma_aread32(core, BCMA_IOST);
- if (D11REV_IS(wlc_hw->corerev, 23)) {
+ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) {
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);
}
@@ -3276,7 +3273,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);
@@ -3359,8 +3356,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)
@@ -3453,7 +3448,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;
@@ -3529,7 +3524,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
@@ -3710,8 +3704,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);
@@ -3734,7 +3728,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;
}
@@ -3752,40 +3747,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)
{
@@ -3795,7 +3756,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;
@@ -3881,7 +3843,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;
@@ -3942,7 +3905,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;
}
@@ -3953,8 +3916,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;
@@ -4018,6 +3981,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) {
@@ -4090,8 +4057,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;
}
@@ -4109,7 +4076,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;
@@ -4224,8 +4191,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;
}
@@ -4238,8 +4205,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;
@@ -4258,14 +4223,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;
}
@@ -4437,13 +4402,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;
@@ -4535,7 +4500,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
/* check device id(srom, nvram etc.) to set bands */
if (wlc_hw->deviceid == BCM43224_D11N_ID ||
- wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
+ wlc_hw->deviceid == BCM43224_D11N_ID_VEN1 ||
+ wlc_hw->deviceid == BCM43224_CHIP_ID)
/* Dualband boards */
wlc_hw->_nbands = 2;
else
@@ -4715,8 +4681,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;
@@ -4836,56 +4803,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;
@@ -4991,8 +4908,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 */
@@ -5005,10 +4920,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;
}
@@ -5026,7 +4937,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,
@@ -5063,7 +4974,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,
@@ -5077,7 +4988,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
* Configure pci/pcmcia here instead of in brcms_c_attach()
* to allow mfg hotswap: down, hotswap (chip power cycle), up.
*/
- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
+ bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core,
true);
/*
@@ -5102,8 +5013,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);
@@ -5135,7 +5044,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))
@@ -5176,8 +5085,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);
}
@@ -5237,8 +5146,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;
@@ -5265,8 +5172,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;
@@ -5314,14 +5219,14 @@ 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);
+ 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)
@@ -5353,13 +5258,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 */
@@ -5441,7 +5339,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;
}
@@ -5745,45 +5643,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;
@@ -5795,7 +5654,7 @@ static bool brcms_c_chipmatch_pci(struct bcma_device *core)
return false;
}
- if (device == BCM43224_D11N_ID_VEN1)
+ if (device == BCM43224_D11N_ID_VEN1 || device == BCM43224_CHIP_ID)
return true;
if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
return true;
@@ -5832,184 +5691,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;
@@ -6033,86 +5714,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
@@ -6140,8 +5741,6 @@ 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);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -6159,8 +5758,6 @@ 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);
return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
}
@@ -6168,8 +5765,6 @@ 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);
/*
* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
* is less than or equal to the rate of the immediately previous
@@ -6223,9 +5818,6 @@ 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);
-
if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
@@ -6292,7 +5884,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;
@@ -6302,6 +5894,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;
@@ -6318,7 +5911,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;
@@ -6329,8 +5922,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;
}
@@ -6338,9 +5931,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 {
@@ -6351,15 +5944,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;
@@ -6367,20 +5960,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;
@@ -6449,7 +6042,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;
@@ -6582,7 +6175,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;
}
@@ -6609,7 +6202,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;
}
@@ -6689,8 +6282,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 */
@@ -6860,7 +6454,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__);
}
@@ -7254,14 +6849,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],
@@ -7273,79 +6870,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.
+ */
+ 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)));
+ 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 +6904,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 +6913,55 @@ 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;
+}
+
+bool 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));
+ brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);
+ if (!brcms_c_tx(wlc, sdu))
+ return true;
+
+ /* packet discarded */
+ dev_kfree_skb_any(sdu);
+ return false;
+}
+
+int
+brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p)
+{
+ struct dma_pub *dma = wlc->hw->di[fifo];
+ int ret;
+ u16 queue;
+
+ ret = dma_txfast(wlc, dma, p);
+ if (ret < 0)
wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
+
+ /*
+ * Stop queue if DMA ring is full. Reserve some free descriptors,
+ * as we sometimes receive a frame from mac80211 after the queues
+ * are stopped.
+ */
+ queue = skb_get_queue_mapping(p);
+ if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO &&
+ !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue))
+ ieee80211_stop_queue(wlc->pub->ieee_hw, queue);
+
+ return ret;
}
u32
@@ -7423,19 +7011,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)
{
@@ -7508,7 +7083,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
/* fill in TSF and flag its presence */
rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
- rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+ rx_status->flag |= RX_FLAG_MACTIME_START;
channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
@@ -7571,7 +7146,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__);
}
/*
@@ -7590,7 +7166,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__);
}
}
@@ -7600,12 +7176,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__);
}
}
@@ -7649,9 +7225,6 @@ 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);
-
if (is_mcs_rate(ratespec)) {
uint mcs = ratespec & RSPEC_RATE_MASK;
int tot_streams = (mcs_2_txstreams(mcs) + 1) +
@@ -7883,35 +7456,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 +7521,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)
@@ -8032,8 +7578,6 @@ 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);
-
/* frame starts with rxhdr */
rxh = (struct d11rxhdr *) (p->data);
@@ -8043,8 +7587,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);
@@ -8088,17 +7633,19 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
uint n = 0;
uint bound_limit = bound ? RXBND : -1;
+ bool morepending;
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
skb_queue_head_init(&recv_frames);
/* gather received frames */
- while (dma_rx(wlc_hw->di[fifo], &recv_frames)) {
-
+ do {
/* !give others some time to run! */
- if (++n >= bound_limit)
+ if (n >= bound_limit)
break;
- }
+
+ morepending = dma_rx(wlc_hw->di[fifo], &recv_frames);
+ n++;
+ } while (morepending);
/* post more rbufs */
dma_rxfill(wlc_hw->di[fifo]);
@@ -8128,7 +7675,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
brcms_c_recv(wlc_hw->wlc, p);
}
- return n >= bound_limit;
+ return morepending;
}
/* second-level interrupt processing
@@ -8140,10 +7687,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;
@@ -8153,8 +7699,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 */
@@ -8164,7 +7710,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;
}
}
@@ -8174,7 +7720,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;
}
@@ -8192,7 +7738,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",
@@ -8206,15 +7752,11 @@ 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);
}
- /* 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;
@@ -8229,7 +7771,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);
@@ -8286,9 +7828,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 +7842,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 +8000,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 8debc74c54e..fb447747c2c 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,30 +610,13 @@ 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 void brcms_c_print_txstatus(struct tx_status *txs);
+extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
+ struct sk_buff *p);
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 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/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index abfd78822fb..21a82423247 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
gain0_15 = ((biq1 & 0xf) << 12) |
((tia & 0xf) << 8) |
((lna2 & 0x3) << 6) |
- ((lna2 &
- 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+ ((lna2 & 0x3) << 4) |
+ ((lna1 & 0x3) << 2) |
+ ((lna1 & 0x3) << 0);
mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
}
mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
+ mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+ mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
}
@@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
}
+static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
+ u16 tia_gain, u16 lna2_gain)
+{
+ u32 i_thresh_l, q_thresh_l;
+ u32 i_thresh_h, q_thresh_h;
+ struct lcnphy_iq_est iq_est_h, iq_est_l;
+
+ wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
+ lna2_gain, 0);
+
+ wlc_lcnphy_rx_gain_override_enable(pi, true);
+ wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
+ udelay(500);
+ write_radio_reg(pi, RADIO_2064_REG112, 0);
+ if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
+ return false;
+
+ wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
+ udelay(500);
+ write_radio_reg(pi, RADIO_2064_REG112, 0);
+ if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
+ return false;
+
+ i_thresh_l = (iq_est_l.i_pwr << 1);
+ i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
+
+ q_thresh_l = (iq_est_l.q_pwr << 1);
+ q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
+ if ((iq_est_h.i_pwr > i_thresh_l) &&
+ (iq_est_h.i_pwr < i_thresh_h) &&
+ (iq_est_h.q_pwr > q_thresh_l) &&
+ (iq_est_h.q_pwr < q_thresh_h))
+ return true;
+
+ return false;
+}
+
static bool
wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
rfoverride3_old, rfoverride3val_old, rfoverride4_old,
rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
- int tia_gain;
- u32 received_power, rx_pwr_threshold;
+ int tia_gain, lna2_gain, biq1_gain;
+ bool set_gain;
u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
u16 values_to_save[11];
s16 *ptr;
@@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
goto cal_done;
}
- if (module == 1) {
+ WARN_ON(module != 1);
+ tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
- tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
- wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+ for (i = 0; i < 11; i++)
+ values_to_save[i] =
+ read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+ Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+ or_phy_reg(pi, 0x631, 0x0015);
+
+ RFOverride0_old = read_phy_reg(pi, 0x44c);
+ RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+ rfoverride2_old = read_phy_reg(pi, 0x4b0);
+ rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+ rfoverride3_old = read_phy_reg(pi, 0x4f9);
+ rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+ rfoverride4_old = read_phy_reg(pi, 0x938);
+ rfoverride4val_old = read_phy_reg(pi, 0x939);
+ afectrlovr_old = read_phy_reg(pi, 0x43b);
+ afectrlovrval_old = read_phy_reg(pi, 0x43c);
+ old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+ old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
- for (i = 0; i < 11; i++)
- values_to_save[i] =
- read_radio_reg(pi, rxiq_cal_rf_reg[i]);
- Core1TxControl_old = read_phy_reg(pi, 0x631);
-
- or_phy_reg(pi, 0x631, 0x0015);
-
- RFOverride0_old = read_phy_reg(pi, 0x44c);
- RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
- rfoverride2_old = read_phy_reg(pi, 0x4b0);
- rfoverride2val_old = read_phy_reg(pi, 0x4b1);
- rfoverride3_old = read_phy_reg(pi, 0x4f9);
- rfoverride3val_old = read_phy_reg(pi, 0x4fa);
- rfoverride4_old = read_phy_reg(pi, 0x938);
- rfoverride4val_old = read_phy_reg(pi, 0x939);
- afectrlovr_old = read_phy_reg(pi, 0x43b);
- afectrlovrval_old = read_phy_reg(pi, 0x43c);
- old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
- old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
-
- tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
- if (tx_gain_override_old) {
- wlc_lcnphy_get_tx_gain(pi, &old_gains);
- tx_gain_index_old = pi_lcn->lcnphy_current_index;
- }
+ tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+ if (tx_gain_override_old) {
+ wlc_lcnphy_get_tx_gain(pi, &old_gains);
+ tx_gain_index_old = pi_lcn->lcnphy_current_index;
+ }
- wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+ wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
- mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
- mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+ mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
- mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
- mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+ mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
- write_radio_reg(pi, RADIO_2064_REG116, 0x06);
- write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
- write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
- write_radio_reg(pi, RADIO_2064_REG098, 0x03);
- write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
- mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
- write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
- write_radio_reg(pi, RADIO_2064_REG114, 0x01);
- write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
- write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
-
- mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
- mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
- mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
- mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
- mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
- mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
- mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
- mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
- mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
- mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
-
- mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
- mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
-
- wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
- write_phy_reg(pi, 0x6da, 0xffff);
- or_phy_reg(pi, 0x6db, 0x3);
- wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
- wlc_lcnphy_rx_gain_override_enable(pi, true);
-
- tia_gain = 8;
- rx_pwr_threshold = 950;
- while (tia_gain > 0) {
- tia_gain -= 1;
- wlc_lcnphy_set_rx_gain_by_distribution(pi,
- 0, 0, 2, 2,
- (u16)
- tia_gain, 1, 0);
- udelay(500);
+ write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+ write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+ write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+ write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+ write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+ mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+ write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+ write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+ write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+ write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+ mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+ mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+ mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
- received_power =
- wlc_lcnphy_measure_digital_power(pi, 2000);
- if (received_power < rx_pwr_threshold)
- break;
+ mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+
+ write_phy_reg(pi, 0x6da, 0xffff);
+ or_phy_reg(pi, 0x6db, 0x3);
+
+ wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+ set_gain = false;
+
+ lna2_gain = 3;
+ while ((lna2_gain >= 0) && !set_gain) {
+ tia_gain = 4;
+
+ while ((tia_gain >= 0) && !set_gain) {
+ biq1_gain = 6;
+
+ while ((biq1_gain >= 0) && !set_gain) {
+ set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
+ (u16)
+ biq1_gain,
+ (u16)
+ tia_gain,
+ (u16)
+ lna2_gain);
+ biq1_gain -= 1;
+ }
+ tia_gain -= 1;
}
- result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+ lna2_gain -= 1;
+ }
- wlc_lcnphy_stop_tx_tone(pi);
+ if (set_gain)
+ result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
+ else
+ result = false;
- write_phy_reg(pi, 0x631, Core1TxControl_old);
+ wlc_lcnphy_stop_tx_tone(pi);
- write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
- write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
- write_phy_reg(pi, 0x4b0, rfoverride2_old);
- write_phy_reg(pi, 0x4b1, rfoverride2val_old);
- write_phy_reg(pi, 0x4f9, rfoverride3_old);
- write_phy_reg(pi, 0x4fa, rfoverride3val_old);
- write_phy_reg(pi, 0x938, rfoverride4_old);
- write_phy_reg(pi, 0x939, rfoverride4val_old);
- write_phy_reg(pi, 0x43b, afectrlovr_old);
- write_phy_reg(pi, 0x43c, afectrlovrval_old);
- write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
- write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+ write_phy_reg(pi, 0x631, Core1TxControl_old);
+
+ write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+ write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+ write_phy_reg(pi, 0x4b0, rfoverride2_old);
+ write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+ write_phy_reg(pi, 0x4f9, rfoverride3_old);
+ write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+ write_phy_reg(pi, 0x938, rfoverride4_old);
+ write_phy_reg(pi, 0x939, rfoverride4val_old);
+ write_phy_reg(pi, 0x43b, afectrlovr_old);
+ write_phy_reg(pi, 0x43c, afectrlovrval_old);
+ write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+ write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
- wlc_lcnphy_clear_trsw_override(pi);
+ wlc_lcnphy_clear_trsw_override(pi);
- mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+ mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
- for (i = 0; i < 11; i++)
- write_radio_reg(pi, rxiq_cal_rf_reg[i],
- values_to_save[i]);
+ for (i = 0; i < 11; i++)
+ write_radio_reg(pi, rxiq_cal_rf_reg[i],
+ values_to_save[i]);
- if (tx_gain_override_old)
- wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
- else
- wlc_lcnphy_disable_tx_gain_override(pi);
+ if (tx_gain_override_old)
+ wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+ else
+ wlc_lcnphy_disable_tx_gain_override(pi);
- wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
- wlc_lcnphy_rx_gain_override_enable(pi, false);
- }
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+ wlc_lcnphy_rx_gain_override_enable(pi, false);
cal_done:
kfree(ptr);
@@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
write_radio_reg(pi, RADIO_2064_REG038, 3);
write_radio_reg(pi, RADIO_2064_REG091, 7);
}
+
+ if (!(pi->sh->boardflags & BFL_FEM)) {
+ u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
+ 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
+
+ write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
+ write_radio_reg(pi, RADIO_2064_REG091, 0x3);
+ write_radio_reg(pi, RADIO_2064_REG038, 0x3);
+
+ write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
+ }
}
static int
@@ -1860,41 +1919,6 @@ wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
return (filt_index != -1) ? 0 : -1;
}
-void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
-{
- u8 channel = CHSPEC_CHANNEL(chanspec);
-
- wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
-
- wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
-
- or_phy_reg(pi, 0x44a, 0x44);
- write_phy_reg(pi, 0x44a, 0x80);
-
- wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
- udelay(1000);
-
- wlc_lcnphy_toggle_afe_pwdn(pi);
-
- write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
- write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
-
- if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
- mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
-
- wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
- } else {
- mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
-
- wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
- }
-
- wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
-
- mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
-
-}
-
static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
{
u16 pa_gain;
@@ -1936,6 +1960,21 @@ static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
wlc_lcnphy_enable_tx_gain_override(pi);
}
+static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
+{
+ u16 m0m1;
+ struct phytbl_info tab;
+
+ tab.tbl_ptr = &m0m1;
+ tab.tbl_len = 1;
+ tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+ tab.tbl_offset = 87;
+ tab.tbl_width = 16;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ return (u8) ((m0m1 & 0xff00) >> 8);
+}
+
static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
{
u16 m0m1 = (u16) m0 << 8;
@@ -1995,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
} else {
mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
+ mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
+ mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
+ mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
+ mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
+ mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
}
} else {
mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2081,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
(auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+ mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
}
static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
{
struct phytbl_info tab;
u32 rfseq, ind;
+ u8 tssi_sel;
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32;
@@ -2108,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
- wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+ if (pi->sh->boardflags & BFL_FEM) {
+ tssi_sel = 0x1;
+ wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+ } else {
+ tssi_sel = 0xe;
+ wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
+ }
mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2144,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
- mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
} else {
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
}
@@ -2193,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
+ mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+
wlc_lcnphy_pwrctrl_rssiparams(pi);
}
@@ -2811,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
read_radio_reg(pi, RADIO_2064_REG007) & 1;
u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+ u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
+
idleTssi = read_phy_reg(pi, 0x4ab);
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
MCTL_EN_MAC));
@@ -2828,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
wlc_lcnphy_tssi_setup(pi);
+
+ mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
+ mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
+
+ wlc_lcnphy_set_bbmult(pi, 0x0);
+
wlc_phy_do_dummy_tx(pi, true, OFF);
idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
>> 0);
@@ -2849,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
+ wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
wlc_lcnphy_set_tx_gain(pi, &old_gains);
wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3062,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
wlc_lcnphy_write_table(pi, &tab);
tab.tbl_offset++;
}
+ mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
+ mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
+ mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
+ mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
+ mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
@@ -3075,21 +3151,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
wlapi_enable_mac(pi->sh->physhim);
}
-static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
-{
- u16 m0m1;
- struct phytbl_info tab;
-
- tab.tbl_ptr = &m0m1;
- tab.tbl_len = 1;
- tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
- tab.tbl_offset = 87;
- tab.tbl_width = 16;
- wlc_lcnphy_read_table(pi, &tab);
-
- return (u8) ((m0m1 & 0xff00) >> 8);
-}
-
static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
{
mod_phy_reg(pi, 0x4fb,
@@ -3878,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
target_gains.pad_gain = 21;
target_gains.dac_gain = 0;
wlc_lcnphy_set_tx_gain(pi, &target_gains);
- wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
@@ -3889,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
lcnphy_recal ? LCNPHY_CAL_RECAL :
LCNPHY_CAL_FULL), false);
} else {
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
}
@@ -4313,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
if (CHSPEC_IS5G(pi->radio_chanspec))
pa_gain = 0x70;
else
- pa_gain = 0x70;
+ pa_gain = 0x60;
if (pi->sh->boardflags & BFL_FEM)
pa_gain = 0x10;
+
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32;
tab.tbl_len = 1;
tab.tbl_ptr = &val;
for (j = 0; j < 128; j++) {
- gm_gain = gain_table[j].gm;
+ if (pi->sh->boardflags & BFL_FEM)
+ gm_gain = gain_table[j].gm;
+ else
+ gm_gain = 15;
+
val = (((u32) pa_gain << 24) |
(gain_table[j].pad << 16) |
(gain_table[j].pga << 8) | gm_gain);
@@ -4534,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
write_phy_reg(pi, 0x4ea, 0x4688);
- mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+ if (pi->sh->boardflags & BFL_FEM)
+ mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+ else
+ mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
@@ -4545,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
wlc_lcnphy_rcal(pi);
wlc_lcnphy_rc_cal(pi);
+
+ if (!(pi->sh->boardflags & BFL_FEM)) {
+ write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
+ write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+ write_radio_reg(pi, RADIO_2064_REG039, 0xe);
+ }
+
}
static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4574,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
wlc_lcnphy_write_table(pi, &tab);
}
- tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
- tab.tbl_width = 16;
- tab.tbl_ptr = &val;
- tab.tbl_len = 1;
-
- val = 114;
- tab.tbl_offset = 0;
- wlc_lcnphy_write_table(pi, &tab);
+ if (!(pi->sh->boardflags & BFL_FEM)) {
+ tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &val;
+ tab.tbl_len = 1;
- val = 130;
- tab.tbl_offset = 1;
- wlc_lcnphy_write_table(pi, &tab);
+ val = 150;
+ tab.tbl_offset = 0;
+ wlc_lcnphy_write_table(pi, &tab);
- val = 6;
- tab.tbl_offset = 8;
- wlc_lcnphy_write_table(pi, &tab);
+ val = 220;
+ tab.tbl_offset = 1;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
if (CHSPEC_IS2G(pi->radio_chanspec)) {
if (pi->sh->boardflags & BFL_FEM)
@@ -4946,6 +5020,44 @@ void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
}
}
+void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
+{
+ u8 channel = CHSPEC_CHANNEL(chanspec);
+
+ wlc_phy_chanspec_radio_set((struct brcms_phy_pub *)pi, chanspec);
+
+ wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
+
+ or_phy_reg(pi, 0x44a, 0x44);
+ write_phy_reg(pi, 0x44a, 0x80);
+
+ wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
+ udelay(1000);
+
+ wlc_lcnphy_toggle_afe_pwdn(pi);
+
+ write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
+ write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
+
+ if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+ mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+
+ wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
+ } else {
+ mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+
+ wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
+ }
+
+ if (pi->sh->boardflags & BFL_FEM)
+ wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
+ else
+ wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
+
+ mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+ wlc_lcnphy_tssi_setup(pi);
+}
+
void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
{
kfree(pi->u.pi_lcnphy);
@@ -4982,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
return false;
- if ((pi->sh->boardflags & BFL_FEM) &&
- (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
if (pi_lcn->lcnphy_tempsense_option == 3) {
pi->hwpwrctrl = true;
pi->hwpwrctrl_capable = true;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index 622c01ca72c..b7e95acc208 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
};
static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
};
static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 5855f4fd16d..4fb2834f4e6 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -176,6 +176,7 @@ struct brcms_pub {
bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
struct wl_cnt *_cnt; /* low-level counters in driver */
+ struct dentry *dbgfs_dir;
};
enum wlc_par_id {
@@ -200,43 +201,6 @@ enum wlc_par_id {
/* WL11N Support */
#define AMPDU_AGG_HOST 1
-/* pri is priority encoded in the packet. This maps the Packet priority to
- * enqueue precedence as defined in wlc_prec_map
- */
-extern const u8 wlc_prio2prec_map[];
-#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
-
-#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
-
-/* Mask to describe all precedence levels */
-#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
-
-/*
- * This maps priority to one precedence higher - Used by PS-Poll response
- * packets to simulate enqueue-at-head operation, but still maintain the
- * order on the queue
- */
-#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
- BRCMS_PREC_COUNT - 1)
-
-/* Define a bitmap of precedences comprised by each AC */
-#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
-#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
-#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
-#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
- NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
- NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
-
/* network protection config */
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
@@ -319,9 +283,9 @@ extern void brcms_c_intrson(struct brcms_c_info *wlc);
extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
-extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
+extern bool brcms_c_isr(struct brcms_c_info *wlc);
extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
-extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
+extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
struct sk_buff *sdu,
struct ieee80211_hw *hw);
extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
index ed1d1aa71d2..dd916272249 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -23,6 +23,7 @@
#include "channel.h"
#include "main.h"
#include "stf.h"
+#include "debug.h"
#define MIN_SPATIAL_EXPANSION 0
#define MAX_SPATIAL_EXPANSION 1
@@ -160,8 +161,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
u8 core_mask)
{
- BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
- wlc->pub->unit, Nsts, core_mask);
+ brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n",
+ wlc->pub->unit, Nsts, core_mask);
if (hweight8(core_mask) > wlc->stf->txstreams)
core_mask = 0;
@@ -194,7 +195,8 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
int i;
u8 core_mask = 0;
- BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
+ brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit,
+ val);
wlc->stf->spatial_policy = (s8) val;
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
index e11ae83111e..ae1f3ad40d4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -246,7 +246,7 @@
#define BCMMSG(dev, fmt, args...) \
do { \
- if (brcm_msg_level & LOG_TRACE_VAL) \
+ if (brcm_msg_level & BRCM_DL_INFO) \
wiphy_err(dev, "%s: " fmt, __func__, ##args); \
} while (0)
@@ -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;