Skip to content

Commit

Permalink
staging: brcm80211: enable driver counter functionality
Browse files Browse the repository at this point in the history
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: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Brett Rudley <brudley@broadcom.com>
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Arend van Spriel authored and Greg Kroah-Hartman committed Feb 18, 2011
1 parent 8746e2b commit e4cf544
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 83 deletions.
12 changes: 7 additions & 5 deletions drivers/staging/brcm80211/brcmfmac/wl_iw.c
Original file line number Diff line number Diff line change
Expand Up @@ -3568,7 +3568,7 @@ int
wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
{
int res = 0;
wl_cnt_t cnt;
struct wl_cnt cnt;
int phy_noise;
int rssi;
scb_val_t scb_val;
Expand Down Expand Up @@ -3611,11 +3611,13 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
#endif

#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 =
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) {
WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n",
res);
Expand All @@ -3624,7 +3626,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)

cnt.version = dtoh16(cnt.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);
goto done;
}
Expand Down
35 changes: 22 additions & 13 deletions drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,16 @@ static int
wl_ops_get_stats(struct ieee80211_hw *hw,
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;
}

Expand Down Expand Up @@ -1648,34 +1657,34 @@ void wl_free_timer(struct wl_info *wl, wl_timer_t *t)
static int wl_linux_watchdog(void *ctx)
{
struct wl_info *wl = (struct wl_info *) ctx;
struct wl_cnt *cnt;
struct net_device_stats *stats = NULL;
uint id;
/* refresh stats */
if (wl->pub->up) {
ASSERT(wl->stats_id < 2);

cnt = wl->pub->_cnt;
id = 1 - wl->stats_id;

stats = &wl->stats_watchdog[id];
stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe);
stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe);
stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte);
stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte);
stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror);
stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror);
stats->rx_packets = cnt->rxframe;
stats->tx_packets = cnt->txframe;
stats->rx_bytes = cnt->rxbyte;
stats->tx_bytes = cnt->txbyte;
stats->rx_errors = cnt->rxerror;
stats->tx_errors = cnt->txerror;
stats->collisions = 0;

stats->rx_length_errors = 0;
stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc);
stats->rx_over_errors = cnt->rxoflo;
stats->rx_crc_errors = cnt->rxcrc;
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->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo);
stats->tx_fifo_errors = cnt->txuflo;

wl->stats_id = id;

}

return 0;
Expand Down
18 changes: 9 additions & 9 deletions drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit,
{
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) {
*err = 1001;
goto fail;
}

pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit,
pub->tunables = wlc_calloc(osh, unit,
sizeof(wlc_tunables_t));
if (pub->tunables == NULL) {
*err = 1028;
Expand All @@ -86,6 +86,10 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit,
/* need to init the tunables now */
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,
(ETH_ALEN * MAXMULTILIST));
if (pub->multicast == NULL) {
Expand All @@ -105,13 +109,9 @@ static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub)
if (pub == NULL)
return;

if (pub->multicast)
kfree(pub->multicast);
if (pub->tunables) {
kfree(pub->tunables);
pub->tunables = NULL;
}

kfree(pub->multicast);
kfree(pub->_cnt);
kfree(pub->tunables);
kfree(pub);
}

Expand Down
11 changes: 8 additions & 3 deletions drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
#include <wl_export.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_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */
Expand Down Expand Up @@ -1043,10 +1048,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
if (supr_status == TX_STATUS_SUPR_BADCH ||
supr_status == TX_STATUS_SUPR_EXPTIME) {
retry = false;
WLCNTINCR(wlc->pub->_cnt->txchanrej);
wlc->pub->_cnt->txchanrej++;
} 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 */
} else if (supr_status == TX_STATUS_SUPR_FRAG) {
Expand All @@ -1060,7 +1065,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
}
} else if (txs->phyerr) {
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",
wlc->pub->unit, txs->phyerr);

Expand Down
20 changes: 10 additions & 10 deletions drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)

/* phy tx error */
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 */
Expand Down Expand Up @@ -413,7 +413,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
__func__, wlc_hw->sih->chip,
wlc_hw->sih->chiprev);

WLCNTINCR(wlc->pub->_cnt->psmwds);
wlc->pub->_cnt->psmwds++;

/* big hammer */
wl_init(wlc->wl);
Expand All @@ -427,7 +427,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
if (macintstatus & MI_RFDISABLE) {
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);
}

Expand Down Expand Up @@ -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);

WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset);
wlc_hw->wlc->pub->_cnt->reset++;

/* reset the core */
if (!DEVICEREMOVED(wlc_hw->wlc))
Expand Down Expand Up @@ -2877,40 +2877,40 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw)
if (intstatus & I_RO) {
WL_ERROR("wl%d: fifo %d: receive fifo overflow\n",
unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo);
wlc_hw->wlc->pub->_cnt->rxoflo++;
fatal = true;
}

if (intstatus & I_PC) {
WL_ERROR("wl%d: fifo %d: descriptor error\n",
unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade);
wlc_hw->wlc->pub->_cnt->dmade++;
fatal = true;
}

if (intstatus & I_PD) {
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;
}

if (intstatus & I_DE) {
WL_ERROR("wl%d: fifo %d: descriptor protocol error\n",
unit, idx);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape);
wlc_hw->wlc->pub->_cnt->dmape++;
fatal = true;
}

if (intstatus & I_RU) {
WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n",
idx, unit);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]);
wlc_hw->wlc->pub->_cnt->rxuflo[idx]++;
}

if (intstatus & I_XU) {
WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n",
idx, unit);
WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo);
wlc_hw->wlc->pub->_cnt->txuflo++;
fatal = true;
}

Expand Down
Loading

0 comments on commit e4cf544

Please sign in to comment.