Commit e4cf544e authored by Arend van Spriel's avatar Arend van Spriel Committed by Greg Kroah-Hartman

staging: brcm80211: enable driver counter functionality

The 802.11 core in the chipsets provides counters that are now
used to provide counter values to mac80211 through get_stats
callback. Counters related to ampdu and wmm (aka. wme) are not
yet incorporated.
Reviewed-by: default avatarRoland Vossen <rvossen@broadcom.com>
Reviewed-by: default avatarBrett Rudley <brudley@broadcom.com>
Reviewed-by: default avatarHenry Ptasinski <henryp@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 8746e2ba
...@@ -3568,7 +3568,7 @@ int ...@@ -3568,7 +3568,7 @@ int
wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
{ {
int res = 0; int res = 0;
wl_cnt_t cnt; struct wl_cnt cnt;
int phy_noise; int phy_noise;
int rssi; int rssi;
scb_val_t scb_val; scb_val_t scb_val;
...@@ -3611,11 +3611,13 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) ...@@ -3611,11 +3611,13 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
#endif #endif
#if WIRELESS_EXT > 11 #if WIRELESS_EXT > 11
WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n", sizeof(wl_cnt_t)); WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n",
sizeof(struct wl_cnt));
memset(&cnt, 0, sizeof(wl_cnt_t)); memset(&cnt, 0, sizeof(struct wl_cnt));
res = res =
dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); dev_wlc_bufvar_get(dev, "counters", (char *)&cnt,
sizeof(struct wl_cnt));
if (res) { if (res) {
WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n", WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n",
res); res);
...@@ -3624,7 +3626,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) ...@@ -3624,7 +3626,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
cnt.version = dtoh16(cnt.version); cnt.version = dtoh16(cnt.version);
if (cnt.version != WL_CNT_T_VERSION) { if (cnt.version != WL_CNT_T_VERSION) {
WL_TRACE("\tIncorrect version of counters struct: expected %d; got %d\n", WL_TRACE("\tIncorrect counter version: expected %d; got %d\n",
WL_CNT_T_VERSION, cnt.version); WL_CNT_T_VERSION, cnt.version);
goto done; goto done;
} }
......
...@@ -461,7 +461,16 @@ static int ...@@ -461,7 +461,16 @@ static int
wl_ops_get_stats(struct ieee80211_hw *hw, wl_ops_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats) struct ieee80211_low_level_stats *stats)
{ {
WL_ERROR("%s: Enter\n", __func__); struct wl_info *wl = hw->priv;
struct wl_cnt *cnt;
WL_LOCK(wl);
cnt = wl->pub->_cnt;
stats->dot11ACKFailureCount = cnt->txnoack;
stats->dot11RTSFailureCount = cnt->txnocts;
stats->dot11FCSErrorCount = cnt->rxcrc;
stats->dot11RTSSuccessCount = cnt->txrts;
WL_UNLOCK(wl);
return 0; return 0;
} }
...@@ -1648,34 +1657,34 @@ void wl_free_timer(struct wl_info *wl, wl_timer_t *t) ...@@ -1648,34 +1657,34 @@ void wl_free_timer(struct wl_info *wl, wl_timer_t *t)
static int wl_linux_watchdog(void *ctx) static int wl_linux_watchdog(void *ctx)
{ {
struct wl_info *wl = (struct wl_info *) ctx; struct wl_info *wl = (struct wl_info *) ctx;
struct wl_cnt *cnt;
struct net_device_stats *stats = NULL; struct net_device_stats *stats = NULL;
uint id; uint id;
/* refresh stats */ /* refresh stats */
if (wl->pub->up) { if (wl->pub->up) {
ASSERT(wl->stats_id < 2); ASSERT(wl->stats_id < 2);
cnt = wl->pub->_cnt;
id = 1 - wl->stats_id; id = 1 - wl->stats_id;
stats = &wl->stats_watchdog[id]; stats = &wl->stats_watchdog[id];
stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe); stats->rx_packets = cnt->rxframe;
stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe); stats->tx_packets = cnt->txframe;
stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte); stats->rx_bytes = cnt->rxbyte;
stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte); stats->tx_bytes = cnt->txbyte;
stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror); stats->rx_errors = cnt->rxerror;
stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror); stats->tx_errors = cnt->txerror;
stats->collisions = 0; stats->collisions = 0;
stats->rx_length_errors = 0; stats->rx_length_errors = 0;
stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); stats->rx_over_errors = cnt->rxoflo;
stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc); stats->rx_crc_errors = cnt->rxcrc;
stats->rx_frame_errors = 0; stats->rx_frame_errors = 0;
stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); stats->rx_fifo_errors = cnt->rxoflo;
stats->rx_missed_errors = 0; stats->rx_missed_errors = 0;
stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo); stats->tx_fifo_errors = cnt->txuflo;
wl->stats_id = id; wl->stats_id = id;
} }
return 0; return 0;
......
...@@ -70,13 +70,13 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, ...@@ -70,13 +70,13 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit,
{ {
struct wlc_pub *pub; struct wlc_pub *pub;
pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); pub = wlc_calloc(osh, unit, sizeof(struct wlc_pub));
if (pub == NULL) { if (pub == NULL) {
*err = 1001; *err = 1001;
goto fail; goto fail;
} }
pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit, pub->tunables = wlc_calloc(osh, unit,
sizeof(wlc_tunables_t)); sizeof(wlc_tunables_t));
if (pub->tunables == NULL) { if (pub->tunables == NULL) {
*err = 1028; *err = 1028;
...@@ -86,6 +86,10 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, ...@@ -86,6 +86,10 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit,
/* need to init the tunables now */ /* need to init the tunables now */
wlc_tunables_init(pub->tunables, devid); wlc_tunables_init(pub->tunables, devid);
pub->_cnt = wlc_calloc(osh, unit, sizeof(struct wl_cnt));
if (pub->_cnt == NULL)
goto fail;
pub->multicast = (u8 *)wlc_calloc(osh, unit, pub->multicast = (u8 *)wlc_calloc(osh, unit,
(ETH_ALEN * MAXMULTILIST)); (ETH_ALEN * MAXMULTILIST));
if (pub->multicast == NULL) { if (pub->multicast == NULL) {
...@@ -105,13 +109,9 @@ static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) ...@@ -105,13 +109,9 @@ static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub)
if (pub == NULL) if (pub == NULL)
return; return;
if (pub->multicast)
kfree(pub->multicast); kfree(pub->multicast);
if (pub->tunables) { kfree(pub->_cnt);
kfree(pub->tunables); kfree(pub->tunables);
pub->tunables = NULL;
}
kfree(pub); kfree(pub);
} }
......
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
#include <wl_export.h> #include <wl_export.h>
#include <wl_dbg.h> #include <wl_dbg.h>
/*
* Disable AMPDU statistics counters for now
*/
#define WLCNTINCR(a)
#define WLCNTADD(a, b)
#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ #define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */
#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ #define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */
...@@ -1043,10 +1048,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ...@@ -1043,10 +1048,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
if (supr_status == TX_STATUS_SUPR_BADCH || if (supr_status == TX_STATUS_SUPR_BADCH ||
supr_status == TX_STATUS_SUPR_EXPTIME) { supr_status == TX_STATUS_SUPR_EXPTIME) {
retry = false; retry = false;
WLCNTINCR(wlc->pub->_cnt->txchanrej); wlc->pub->_cnt->txchanrej++;
} else if (supr_status == TX_STATUS_SUPR_EXPTIME) { } else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
WLCNTINCR(wlc->pub->_cnt->txexptime); wlc->pub->_cnt->txexptime++;
/* TX underflow : try tuning pre-loading or ampdu size */ /* TX underflow : try tuning pre-loading or ampdu size */
} else if (supr_status == TX_STATUS_SUPR_FRAG) { } else if (supr_status == TX_STATUS_SUPR_FRAG) {
...@@ -1060,7 +1065,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ...@@ -1060,7 +1065,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
} }
} else if (txs->phyerr) { } else if (txs->phyerr) {
update_rate = false; update_rate = false;
WLCNTINCR(wlc->pub->_cnt->txphyerr); wlc->pub->_cnt->txphyerr++;
WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n",
wlc->pub->unit, txs->phyerr); wlc->pub->unit, txs->phyerr);
......
...@@ -383,7 +383,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) ...@@ -383,7 +383,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
/* phy tx error */ /* phy tx error */
if (macintstatus & MI_PHYTXERR) { if (macintstatus & MI_PHYTXERR) {
WLCNTINCR(wlc->pub->_cnt->txphyerr); wlc->pub->_cnt->txphyerr++;
} }
/* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */
...@@ -413,7 +413,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) ...@@ -413,7 +413,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
__func__, wlc_hw->sih->chip, __func__, wlc_hw->sih->chip,
wlc_hw->sih->chiprev); wlc_hw->sih->chiprev);
WLCNTINCR(wlc->pub->_cnt->psmwds); wlc->pub->_cnt->psmwds++;
/* big hammer */ /* big hammer */
wl_init(wlc->wl); wl_init(wlc->wl);
...@@ -427,7 +427,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) ...@@ -427,7 +427,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
if (macintstatus & MI_RFDISABLE) { if (macintstatus & MI_RFDISABLE) {
WL_TRACE("wl%d: BMAC Detected a change on the RF Disable Input\n", wlc_hw->unit); WL_TRACE("wl%d: BMAC Detected a change on the RF Disable Input\n", wlc_hw->unit);
WLCNTINCR(wlc->pub->_cnt->rfdisable); wlc->pub->_cnt->rfdisable++;
wl_rfkill_set_hw_state(wlc->wl); wl_rfkill_set_hw_state(wlc->wl);
} }
...@@ -1088,7 +1088,7 @@ void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) ...@@ -1088,7 +1088,7 @@ void wlc_bmac_reset(struct wlc_hw_info *wlc_hw)
{ {
WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); wlc_hw->wlc->pub->_cnt->reset++;
/* reset the core */ /* reset the core */
if (!DEVICEREMOVED(wlc_hw->wlc)) if (!DEVICEREMOVED(wlc_hw->wlc))
...@@ -2877,40 +2877,40 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) ...@@ -2877,40 +2877,40 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw)
if (intstatus & I_RO) { if (intstatus & I_RO) {
WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", WL_ERROR("wl%d: fifo %d: receive fifo overflow\n",
unit, idx); unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); wlc_hw->wlc->pub->_cnt->rxoflo++;
fatal = true; fatal = true;
} }
if (intstatus & I_PC) { if (intstatus & I_PC) {
WL_ERROR("wl%d: fifo %d: descriptor error\n", WL_ERROR("wl%d: fifo %d: descriptor error\n",
unit, idx); unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); wlc_hw->wlc->pub->_cnt->dmade++;
fatal = true; fatal = true;
} }
if (intstatus & I_PD) { if (intstatus & I_PD) {
WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); WL_ERROR("wl%d: fifo %d: data error\n", unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); wlc_hw->wlc->pub->_cnt->dmada++;
fatal = true; fatal = true;
} }
if (intstatus & I_DE) { if (intstatus & I_DE) {
WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", WL_ERROR("wl%d: fifo %d: descriptor protocol error\n",
unit, idx); unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); wlc_hw->wlc->pub->_cnt->dmape++;
fatal = true; fatal = true;
} }
if (intstatus & I_RU) { if (intstatus & I_RU) {
WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n",
idx, unit); idx, unit);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); wlc_hw->wlc->pub->_cnt->rxuflo[idx]++;
} }
if (intstatus & I_XU) { if (intstatus & I_XU) {
WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n",
idx, unit); idx, unit);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); wlc_hw->wlc->pub->_cnt->txuflo++;
fatal = true; fatal = true;
} }
......
...@@ -53,6 +53,12 @@ ...@@ -53,6 +53,12 @@
#include <net/mac80211.h> #include <net/mac80211.h>
#include <wl_dbg.h> #include <wl_dbg.h>
/*
* Disable statistics counting for WME
*/
#define WLCNTSET(a, b)
#define WLCNTINCR(a)
#define WLCNTADD(a, b)
/* /*
* WPA(2) definitions * WPA(2) definitions
...@@ -379,13 +385,11 @@ void wlc_reset(struct wlc_info *wlc) ...@@ -379,13 +385,11 @@ void wlc_reset(struct wlc_info *wlc)
wlc->check_for_unaligned_tbtt = false; wlc->check_for_unaligned_tbtt = false;
/* slurp up hw mac counters before core reset */ /* slurp up hw mac counters before core reset */
if (WLC_UPDATE_STATS(wlc)) {
wlc_statsupd(wlc); wlc_statsupd(wlc);
/* reset our snapshot of macstat counters */ /* reset our snapshot of macstat counters */
memset((char *)wlc->core->macstat_snapshot, 0, memset((char *)wlc->core->macstat_snapshot, 0,
sizeof(macstat_t)); sizeof(macstat_t));
}
wlc_bmac_reset(wlc->hw); wlc_bmac_reset(wlc->hw);
wlc_ampdu_reset(wlc->ampdu); wlc_ampdu_reset(wlc->ampdu);
...@@ -1947,8 +1951,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ...@@ -1947,8 +1951,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode,
wlc->cfg->wlc = wlc; wlc->cfg->wlc = wlc;
pub->txmaxpkts = MAXTXPKTS; pub->txmaxpkts = MAXTXPKTS;
WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION); pub->_cnt->version = WL_CNT_T_VERSION;
WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t)); pub->_cnt->length = sizeof(struct wl_cnt);
WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION);
WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t));
...@@ -2501,8 +2505,7 @@ static void wlc_watchdog(void *arg) ...@@ -2501,8 +2505,7 @@ static void wlc_watchdog(void *arg)
wlc_bmac_watchdog(wlc); wlc_bmac_watchdog(wlc);
/* occasionally sample mac stat counters to detect 16-bit counter wrap */ /* occasionally sample mac stat counters to detect 16-bit counter wrap */
if ((WLC_UPDATE_STATS(wlc)) if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
&& (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD)))
wlc_statsupd(wlc); wlc_statsupd(wlc);
/* Manage TKIP countermeasures timers */ /* Manage TKIP countermeasures timers */
...@@ -3855,19 +3858,18 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, ...@@ -3855,19 +3858,18 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
case WLC_GET_PKTCNTS:{ case WLC_GET_PKTCNTS:{
get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval;
if (WLC_UPDATE_STATS(wlc))
wlc_statsupd(wlc); wlc_statsupd(wlc);
pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe); pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe;
pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror); pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror;
pktcnt->tx_good_pkt = pktcnt->tx_good_pkt =
WLCNTVAL(wlc->pub->_cnt->txfrmsnt); wlc->pub->_cnt->txfrmsnt;
pktcnt->tx_bad_pkt = pktcnt->tx_bad_pkt =
WLCNTVAL(wlc->pub->_cnt->txerror) + wlc->pub->_cnt->txerror +
WLCNTVAL(wlc->pub->_cnt->txfail); wlc->pub->_cnt->txfail;
if (len >= (int)sizeof(get_pktcnt_t)) { if (len >= (int)sizeof(get_pktcnt_t)) {
/* Be backward compatible - only if buffer is large enough */ /* Be backward compatible - only if buffer is large enough */
pktcnt->rx_ocast_good_pkt = pktcnt->rx_ocast_good_pkt =
WLCNTVAL(wlc->pub->_cnt->rxmfrmocast); wlc->pub->_cnt->rxmfrmocast;
} }
break; break;
} }
...@@ -4746,12 +4748,28 @@ void wlc_print_txstatus(tx_status_t *txs) ...@@ -4746,12 +4748,28 @@ void wlc_print_txstatus(tx_status_t *txs)
#endif /* defined(BCMDBG) */ #endif /* defined(BCMDBG) */
} }
static void
wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat)
{
u16 v;
u16 delta;
v = ltoh16(cur_stat);
delta = (u16)(v - *macstat_snapshot);
if (delta != 0) {
*macstat += delta;
*macstat_snapshot = v;
}
}
#define MACSTATUPD(name) \ #define MACSTATUPD(name) \
wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name)
void wlc_statsupd(struct wlc_info *wlc) void wlc_statsupd(struct wlc_info *wlc)
{ {
int i; int i;
macstat_t macstats;
#ifdef BCMDBG #ifdef BCMDBG
u16 delta; u16 delta;
u16 rxf0ovfl; u16 rxf0ovfl;
...@@ -4771,6 +4789,66 @@ void wlc_statsupd(struct wlc_info *wlc) ...@@ -4771,6 +4789,66 @@ void wlc_statsupd(struct wlc_info *wlc)
txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
#endif /* BCMDBG */ #endif /* BCMDBG */
/* Read mac stats from contiguous shared memory */
wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
&macstats, sizeof(macstat_t));
/* update mac stats */
MACSTATUPD(txallfrm);
MACSTATUPD(txrtsfrm);
MACSTATUPD(txctsfrm);
MACSTATUPD(txackfrm);
MACSTATUPD(txdnlfrm);
MACSTATUPD(txbcnfrm);
for (i = 0; i < NFIFO; i++)
MACSTATUPD(txfunfl[i]);
MACSTATUPD(txtplunfl);
MACSTATUPD(txphyerr);
MACSTATUPD(rxfrmtoolong);
MACSTATUPD(rxfrmtooshrt);
MACSTATUPD(rxinvmachdr);
MACSTATUPD(rxbadfcs);
MACSTATUPD(rxbadplcp);
MACSTATUPD(rxcrsglitch);
MACSTATUPD(rxstrt);
MACSTATUPD(rxdfrmucastmbss);
MACSTATUPD(rxmfrmucastmbss);
MACSTATUPD(rxcfrmucast);
MACSTATUPD(rxrtsucast);
MACSTATUPD(rxctsucast);
MACSTATUPD(rxackucast);
MACSTATUPD(rxdfrmocast);
MACSTATUPD(rxmfrmocast);
MACSTATUPD(rxcfrmocast);
MACSTATUPD(rxrtsocast);
MACSTATUPD(rxctsocast);
MACSTATUPD(rxdfrmmcast);
MACSTATUPD(rxmfrmmcast);
MACSTATUPD(rxcfrmmcast);
MACSTATUPD(rxbeaconmbss);
MACSTATUPD(rxdfrmucastobss);
MACSTATUPD(rxbeaconobss);
MACSTATUPD(rxrsptmout);
MACSTATUPD(bcntxcancl);
MACSTATUPD(rxf0ovfl);
MACSTATUPD(rxf1ovfl);
MACSTATUPD(rxf2ovfl);
MACSTATUPD(txsfovfl);
MACSTATUPD(pmqovfl);
MACSTATUPD(rxcgprqfrm);
MACSTATUPD(rxcgprsqovfl);
MACSTATUPD(txcgprsfail);
MACSTATUPD(txcgprssuc);
MACSTATUPD(prs_timeout);
MACSTATUPD(rxnack);
MACSTATUPD(frmscons);
MACSTATUPD(txnack);
MACSTATUPD(txglitch_nack);
MACSTATUPD(txburst);
MACSTATUPD(phywatchdog);
MACSTATUPD(pktengrxducast);
MACSTATUPD(pktengrxdmcast);
#ifdef BCMDBG #ifdef BCMDBG
/* check for rx fifo 0 overflow */ /* check for rx fifo 0 overflow */
delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
...@@ -4828,7 +4906,7 @@ void wlc_statsupd(struct wlc_info *wlc) ...@@ -4828,7 +4906,7 @@ void wlc_statsupd(struct wlc_info *wlc)
wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb +
wlc->pub->_cnt->rxbadsrcmac); wlc->pub->_cnt->rxbadsrcmac);
for (i = 0; i < NFIFO; i++) for (i = 0; i < NFIFO; i++)
WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]); wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i];
} }
bool wlc_chipmatch(u16 vendor, u16 device) bool wlc_chipmatch(u16 vendor, u16 device)
...@@ -5075,7 +5153,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, ...@@ -5075,7 +5153,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt,
ASSERT(0); ASSERT(0);
pkt_buf_free_skb(wlc->osh, p, true); pkt_buf_free_skb(wlc->osh, p, true);
WLCNTINCR(wlc->pub->_cnt->txnobuf); wlc->pub->_cnt->txnobuf++;
} }
/* Enqueue */ /* Enqueue */
...@@ -5108,7 +5186,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, ...@@ -5108,7 +5186,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
/* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */
pkt_buf_free_skb(wlc->osh, sdu, true); pkt_buf_free_skb(wlc->osh, sdu, true);
WLCNTINCR(wlc->pub->_cnt->txnobuf); wlc->pub->_cnt->txnobuf++;
} }
/* Check if flow control needs to be turned on after enqueuing the packet /* Check if flow control needs to be turned on after enqueuing the packet
...@@ -5160,7 +5238,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, ...@@ -5160,7 +5238,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
wlc_send_q(wlc, wlc->active_queue); wlc_send_q(wlc, wlc->active_queue);
WLCNTINCR(wlc->pub->_cnt->ieee_tx); wlc->pub->_cnt->ieee_tx++;
return 0; return 0;
} }
...@@ -6207,7 +6285,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, ...@@ -6207,7 +6285,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw,
|| !IS_MCS(rspec[0])); || !IS_MCS(rspec[0]));
if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M)
phyctl |= PHY_TXC_SHORT_HDR; phyctl |= PHY_TXC_SHORT_HDR;
WLCNTINCR(wlc->pub->_cnt->txprshort); wlc->pub->_cnt->txprshort++;
} }
/* phytxant is properly bit shifted */ /* phytxant is properly bit shifted */
...@@ -6355,7 +6433,7 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) ...@@ -6355,7 +6433,7 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs)
{ {
wlc_bsscfg_t *cfg = wlc->cfg; wlc_bsscfg_t *cfg = wlc->cfg;
WLCNTINCR(wlc->pub->_cnt->tbtt); wlc->pub->_cnt->tbtt++;
if (BSSCFG_STA(cfg)) { if (BSSCFG_STA(cfg)) {
/* run watchdog here if the watchdog timer is not armed */ /* run watchdog here if the watchdog timer is not armed */
...@@ -6473,7 +6551,7 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) ...@@ -6473,7 +6551,7 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus)
__func__, wlc->pub->sih->chip, __func__, wlc->pub->sih->chip,
wlc->pub->sih->chiprev); wlc->pub->sih->chiprev);
WLCNTINCR(wlc->pub->_cnt->psmwds); wlc->pub->_cnt->psmwds++;
/* big hammer */ /* big hammer */
wl_init(wlc->wl); wl_init(wlc->wl);
...@@ -6531,7 +6609,7 @@ static void *wlc_15420war(struct wlc_info *wlc, uint queue) ...@@ -6531,7 +6609,7 @@ static void *wlc_15420war(struct wlc_info *wlc, uint queue)
/* if tx ring is now empty, reset and re-init the tx dma channel */ /* if tx ring is now empty, reset and re-init the tx dma channel */
if (dma_txactive(wlc->hw->di[queue]) == 0) { if (dma_txactive(wlc->hw->di[queue]) == 0) {
WLCNTINCR(wlc->pub->_cnt->txdmawar); wlc->pub->_cnt->txdmawar++;
if (!dma_txreset(di)) if (!dma_txreset(di))
WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n",
wlc->pub->unit, __func__, queue); wlc->pub->unit, __func__, queue);
...@@ -6633,9 +6711,9 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) ...@@ -6633,9 +6711,9 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2)
if (N_ENAB(wlc->pub)) { if (N_ENAB(wlc->pub)) {
u8 *plcp = (u8 *) (txh + 1); u8 *plcp = (u8 *) (txh + 1);
if (PLCP3_ISSGI(plcp[3])) if (PLCP3_ISSGI(plcp[3]))
WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi); wlc->pub->_cnt->txmpdu_sgi++;
if (PLCP3_ISSTBC(plcp[3])) if (PLCP3_ISSTBC(plcp[3]))
WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc); wlc->pub->_cnt->txmpdu_stbc++;
} }
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
...@@ -6707,7 +6785,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) ...@@ -6707,7 +6785,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2)
skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_PHY_HDR_LEN);
skb_pull(p, D11_TXH_LEN); skb_pull(p, D11_TXH_LEN);
ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); wlc->pub->_cnt->ieee_tx_status++;
} else { } else {
WL_ERROR("%s: Not last frame => not calling tx_status\n", WL_ERROR("%s: Not last frame => not calling tx_status\n",
__func__); __func__);
...@@ -6985,7 +7063,7 @@ wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, ...@@ -6985,7 +7063,7 @@ wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh,
memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
WLCNTINCR(wlc->pub->_cnt->ieee_rx); wlc->pub->_cnt->ieee_rx++;
osh->pktalloced--; osh->pktalloced--;
return; return;
} }
...@@ -7041,7 +7119,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) ...@@ -7041,7 +7119,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
if (rxh->RxStatus1 & RXS_PBPRES) { if (rxh->RxStatus1 & RXS_PBPRES) {
if (p->len < 2) { if (p->len < 2) {
WLCNTINCR(wlc->pub->_cnt->rxrunt); wlc->pub->_cnt->rxrunt++;
WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n",
wlc->pub->unit, p->len); wlc->pub->unit, p->len);
goto toss; goto toss;
...@@ -7066,7 +7144,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) ...@@ -7066,7 +7144,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
fc = ltoh16(h->frame_control); fc = ltoh16(h->frame_control);
} else { } else {
WLCNTINCR(wlc->pub->_cnt->rxrunt); wlc->pub->_cnt->rxrunt++;
goto toss; goto toss;
} }
...@@ -7082,10 +7160,10 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) ...@@ -7082,10 +7160,10 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
WL_ERROR("wl%d: %s: dropping a frame with " WL_ERROR("wl%d: %s: dropping a frame with "
"invalid src mac address, a2: %pM\n", "invalid src mac address, a2: %pM\n",
wlc->pub->unit, __func__, h->addr2); wlc->pub->unit, __func__, h->addr2);
WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); wlc->pub->_cnt->rxbadsrcmac++;
goto toss; goto toss;
} }
WLCNTINCR(wlc->pub->_cnt->rxfrag); wlc->pub->_cnt->rxfrag++;
} }
} }
...@@ -7884,7 +7962,7 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) ...@@ -7884,7 +7962,7 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop)
if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) !=
IEEE80211_FTYPE_DATA) IEEE80211_FTYPE_DATA)
WLCNTINCR(wlc->pub->_cnt->txctl); wlc->pub->_cnt->txctl++;
return 0; return 0;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#ifndef _wlc_pub_h_ #ifndef _wlc_pub_h_
#define _wlc_pub_h_ #define _wlc_pub_h_
#include <wlioctl.h>
#include <wlc_types.h> #include <wlc_types.h>
#include <wlc_scb.h> #include <wlc_scb.h>
...@@ -326,6 +327,8 @@ struct wlc_pub { ...@@ -326,6 +327,8 @@ struct wlc_pub {
bool _lmacproto; /* lmac protocol module included and enabled */ bool _lmacproto; /* lmac protocol module included and enabled */
bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
bool _ampdumac; /* mac assist ampdu enabled or not */ bool _ampdumac; /* mac assist ampdu enabled or not */
struct wl_cnt *_cnt; /* low-level counters in driver */
}; };
/* wl_monitor rx status per packet */ /* wl_monitor rx status per packet */
...@@ -477,12 +480,6 @@ extern const u8 wme_fifo2ac[]; ...@@ -477,12 +480,6 @@ extern const u8 wme_fifo2ac[];
#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ #define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */
#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */
#define WLCNTINCR(a) /* No stats support */
#define WLCNTDECR(a) /* No stats support */
#define WLCNTADD(a, delta) /* No stats support */
#define WLCNTSET(a, value) /* No stats support */
#define WLCNTVAL(a) 0 /* No stats support */
/* common functions for every port */ /* common functions for every port */
extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit,
......
...@@ -1262,7 +1262,7 @@ struct tsinfo_arg { ...@@ -1262,7 +1262,7 @@ struct tsinfo_arg {
#define WL_CNT_T_VERSION 7 /* current version of wl_cnt_t struct */ #define WL_CNT_T_VERSION 7 /* current version of wl_cnt_t struct */
typedef struct { struct wl_cnt {
u16 version; /* see definition of WL_CNT_T_VERSION */ u16 version; /* see definition of WL_CNT_T_VERSION */
u16 length; /* length of entire structure */ u16 length; /* length of entire structure */
...@@ -1492,7 +1492,7 @@ typedef struct { ...@@ -1492,7 +1492,7 @@ typedef struct {
u32 rxmpdu_sgi; /* count for sgi received */ u32 rxmpdu_sgi; /* count for sgi received */
u32 txmpdu_stbc; /* count for stbc transmit */ u32 txmpdu_stbc; /* count for stbc transmit */
u32 rxmpdu_stbc; /* count for stbc received */ u32 rxmpdu_stbc; /* count for stbc received */
} wl_cnt_t; };
#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ #define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment