aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2013-02-06 12:40:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-02-08 14:51:33 -0500
commitb1a2a41126fc582a3d5613aa2d3e632b2eb1a2c4 (patch)
treec66939a5ae2c925d7759a0af2f440a877d7baf52
parent659c84ff3f1b979a91b726a65ab7f8091e019f2b (diff)
brcmfmac: Track statistics per ifp.
Statistics were tracked by bus driver while it is to be tracked per ifp/netdev. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c61
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c9
4 files changed, 27 insertions, 66 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 57826dcbe9b9..6af7c9dce0f7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -24,18 +24,6 @@ enum brcmf_bus_state {
24 BRCMF_BUS_DATA /* Ready for frame transfers */ 24 BRCMF_BUS_DATA /* Ready for frame transfers */
25}; 25};
26 26
27struct dngl_stats {
28 unsigned long rx_packets; /* total packets received */
29 unsigned long tx_packets; /* total packets transmitted */
30 unsigned long rx_bytes; /* total bytes received */
31 unsigned long tx_bytes; /* total bytes transmitted */
32 unsigned long rx_errors; /* bad packets received */
33 unsigned long tx_errors; /* packet transmit problems */
34 unsigned long rx_dropped; /* packets dropped by dongle */
35 unsigned long tx_dropped; /* packets dropped by dongle */
36 unsigned long multicast; /* multicast packets received */
37};
38
39struct brcmf_bus_dcmd { 27struct brcmf_bus_dcmd {
40 char *name; 28 char *name;
41 char *param; 29 char *param;
@@ -87,7 +75,6 @@ struct brcmf_bus {
87 enum brcmf_bus_state state; 75 enum brcmf_bus_state state;
88 uint maxctl; 76 uint maxctl;
89 unsigned long tx_realloc; 77 unsigned long tx_realloc;
90 struct dngl_stats dstats;
91 u8 align; 78 u8 align;
92 struct list_head dcmd_list; 79 struct list_head dcmd_list;
93 80
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 9a4494a5b711..05cae3736e50 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -226,10 +226,12 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
226 ret = brcmf_bus_txdata(drvr->bus_if, skb); 226 ret = brcmf_bus_txdata(drvr->bus_if, skb);
227 227
228done: 228done:
229 if (ret) 229 if (ret) {
230 drvr->bus_if->dstats.tx_dropped++; 230 ifp->stats.tx_dropped++;
231 else 231 } else {
232 drvr->bus_if->dstats.tx_packets++; 232 ifp->stats.tx_packets++;
233 ifp->stats.tx_bytes += skb->len;
234 }
233 235
234 /* Return ok: we always eat the packet */ 236 /* Return ok: we always eat the packet */
235 return NETDEV_TX_OK; 237 return NETDEV_TX_OK;
@@ -270,12 +272,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
270 skb_queue_walk_safe(skb_list, skb, pnext) { 272 skb_queue_walk_safe(skb_list, skb, pnext) {
271 skb_unlink(skb, skb_list); 273 skb_unlink(skb, skb_list);
272 274
273 /* process and remove protocol-specific header 275 /* process and remove protocol-specific header */
274 */
275 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); 276 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
276 if (ret < 0) { 277 ifp = drvr->iflist[ifidx];
277 if (ret != -ENODATA) 278
278 bus_if->dstats.rx_errors++; 279 if (ret || !ifp || !ifp->ndev) {
280 if ((ret != -ENODATA) && ifp)
281 ifp->stats.rx_errors++;
279 brcmu_pkt_buf_free_skb(skb); 282 brcmu_pkt_buf_free_skb(skb);
280 continue; 283 continue;
281 } 284 }
@@ -295,21 +298,11 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
295 eth = skb->data; 298 eth = skb->data;
296 len = skb->len; 299 len = skb->len;
297 300
298 ifp = drvr->iflist[ifidx];
299 if (ifp == NULL)
300 ifp = drvr->iflist[0];
301
302 if (!ifp || !ifp->ndev ||
303 ifp->ndev->reg_state != NETREG_REGISTERED) {
304 brcmu_pkt_buf_free_skb(skb);
305 continue;
306 }
307
308 skb->dev = ifp->ndev; 301 skb->dev = ifp->ndev;
309 skb->protocol = eth_type_trans(skb, skb->dev); 302 skb->protocol = eth_type_trans(skb, skb->dev);
310 303
311 if (skb->pkt_type == PACKET_MULTICAST) 304 if (skb->pkt_type == PACKET_MULTICAST)
312 bus_if->dstats.multicast++; 305 ifp->stats.multicast++;
313 306
314 skb->data = eth; 307 skb->data = eth;
315 skb->len = len; 308 skb->len = len;
@@ -325,8 +318,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
325 ifp->ndev->last_rx = jiffies; 318 ifp->ndev->last_rx = jiffies;
326 } 319 }
327 320
328 bus_if->dstats.rx_bytes += skb->len; 321 if (!(ifp->ndev->flags & IFF_UP)) {
329 bus_if->dstats.rx_packets++; /* Local count */ 322 brcmu_pkt_buf_free_skb(skb);
323 continue;
324 }
325
326 ifp->stats.rx_bytes += skb->len;
327 ifp->stats.rx_packets++;
330 328
331 if (in_interrupt()) 329 if (in_interrupt())
332 netif_rx(skb); 330 netif_rx(skb);
@@ -352,35 +350,28 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
352 350
353 brcmf_proto_hdrpull(drvr, &ifidx, txp); 351 brcmf_proto_hdrpull(drvr, &ifidx, txp);
354 352
353 ifp = drvr->iflist[ifidx];
354 if (!ifp)
355 return;
356
355 eh = (struct ethhdr *)(txp->data); 357 eh = (struct ethhdr *)(txp->data);
356 type = ntohs(eh->h_proto); 358 type = ntohs(eh->h_proto);
357 359
358 if (type == ETH_P_PAE) { 360 if (type == ETH_P_PAE) {
359 ifp = drvr->iflist[ifidx];
360 atomic_dec(&ifp->pend_8021x_cnt); 361 atomic_dec(&ifp->pend_8021x_cnt);
361 if (waitqueue_active(&ifp->pend_8021x_wait)) 362 if (waitqueue_active(&ifp->pend_8021x_wait))
362 wake_up(&ifp->pend_8021x_wait); 363 wake_up(&ifp->pend_8021x_wait);
363 } 364 }
365 if (!success)
366 ifp->stats.tx_errors++;
364} 367}
365 368
366static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 369static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
367{ 370{
368 struct brcmf_if *ifp = netdev_priv(ndev); 371 struct brcmf_if *ifp = netdev_priv(ndev);
369 struct brcmf_bus *bus_if = ifp->drvr->bus_if;
370 372
371 brcmf_dbg(TRACE, "Enter\n"); 373 brcmf_dbg(TRACE, "Enter\n");
372 374
373 /* Copy dongle stats to net device stats */
374 ifp->stats.rx_packets = bus_if->dstats.rx_packets;
375 ifp->stats.tx_packets = bus_if->dstats.tx_packets;
376 ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
377 ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
378 ifp->stats.rx_errors = bus_if->dstats.rx_errors;
379 ifp->stats.tx_errors = bus_if->dstats.tx_errors;
380 ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
381 ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
382 ifp->stats.multicast = bus_if->dstats.multicast;
383
384 return &ifp->stats; 375 return &ifp->stats;
385} 376}
386 377
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index df8a18571951..d424dd63077b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1096,7 +1096,6 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1096 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && 1096 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
1097 type != BRCMF_SDIO_FT_SUPER) { 1097 type != BRCMF_SDIO_FT_SUPER) {
1098 brcmf_err("HW header length too long\n"); 1098 brcmf_err("HW header length too long\n");
1099 bus->sdiodev->bus_if->dstats.rx_errors++;
1100 bus->sdcnt.rx_toolong++; 1099 bus->sdcnt.rx_toolong++;
1101 brcmf_sdbrcm_rxfail(bus, false, false); 1100 brcmf_sdbrcm_rxfail(bus, false, false);
1102 rd->len = 0; 1101 rd->len = 0;
@@ -1298,7 +1297,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1298 if (errcode < 0) { 1297 if (errcode < 0) {
1299 brcmf_err("glom read of %d bytes failed: %d\n", 1298 brcmf_err("glom read of %d bytes failed: %d\n",
1300 dlen, errcode); 1299 dlen, errcode);
1301 bus->sdiodev->bus_if->dstats.rx_errors++;
1302 1300
1303 sdio_claim_host(bus->sdiodev->func[1]); 1301 sdio_claim_host(bus->sdiodev->func[1]);
1304 if (bus->glomerr++ < 3) { 1302 if (bus->glomerr++ < 3) {
@@ -1478,7 +1476,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1478 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { 1476 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
1479 brcmf_err("%d-byte control read exceeds %d-byte buffer\n", 1477 brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
1480 rdlen, bus->sdiodev->bus_if->maxctl); 1478 rdlen, bus->sdiodev->bus_if->maxctl);
1481 bus->sdiodev->bus_if->dstats.rx_errors++;
1482 brcmf_sdbrcm_rxfail(bus, false, false); 1479 brcmf_sdbrcm_rxfail(bus, false, false);
1483 goto done; 1480 goto done;
1484 } 1481 }
@@ -1486,7 +1483,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1486 if ((len - doff) > bus->sdiodev->bus_if->maxctl) { 1483 if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
1487 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", 1484 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1488 len, len - doff, bus->sdiodev->bus_if->maxctl); 1485 len, len - doff, bus->sdiodev->bus_if->maxctl);
1489 bus->sdiodev->bus_if->dstats.rx_errors++;
1490 bus->sdcnt.rx_toolong++; 1486 bus->sdcnt.rx_toolong++;
1491 brcmf_sdbrcm_rxfail(bus, false, false); 1487 brcmf_sdbrcm_rxfail(bus, false, false);
1492 goto done; 1488 goto done;
@@ -1634,7 +1630,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1634 if (!pkt) { 1630 if (!pkt) {
1635 /* Give up on data, request rtx of events */ 1631 /* Give up on data, request rtx of events */
1636 brcmf_err("brcmu_pkt_buf_get_skb failed\n"); 1632 brcmf_err("brcmu_pkt_buf_get_skb failed\n");
1637 bus->sdiodev->bus_if->dstats.rx_dropped++;
1638 brcmf_sdbrcm_rxfail(bus, false, 1633 brcmf_sdbrcm_rxfail(bus, false,
1639 RETRYCHAN(rd->channel)); 1634 RETRYCHAN(rd->channel));
1640 sdio_release_host(bus->sdiodev->func[1]); 1635 sdio_release_host(bus->sdiodev->func[1]);
@@ -1652,7 +1647,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1652 brcmf_err("read %d bytes from channel %d failed: %d\n", 1647 brcmf_err("read %d bytes from channel %d failed: %d\n",
1653 rd->len, rd->channel, sdret); 1648 rd->len, rd->channel, sdret);
1654 brcmu_pkt_buf_free_skb(pkt); 1649 brcmu_pkt_buf_free_skb(pkt);
1655 bus->sdiodev->bus_if->dstats.rx_errors++;
1656 sdio_claim_host(bus->sdiodev->func[1]); 1650 sdio_claim_host(bus->sdiodev->func[1]);
1657 brcmf_sdbrcm_rxfail(bus, true, 1651 brcmf_sdbrcm_rxfail(bus, true,
1658 RETRYCHAN(rd->channel)); 1652 RETRYCHAN(rd->channel));
@@ -1940,10 +1934,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
1940 datalen = pkt->len - SDPCM_HDRLEN; 1934 datalen = pkt->len - SDPCM_HDRLEN;
1941 1935
1942 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); 1936 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1943 if (ret)
1944 bus->sdiodev->bus_if->dstats.tx_errors++;
1945 else
1946 bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
1947 1937
1948 /* In poll mode, need to check for other events */ 1938 /* In poll mode, need to check for other events */
1949 if (!bus->intr && cnt) { 1939 if (!bus->intr && cnt) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index e15630cc3889..06f7339b50b4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -421,10 +421,6 @@ static void brcmf_usb_tx_complete(struct urb *urb)
421 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, 421 brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
422 req->skb); 422 req->skb);
423 brcmf_usb_del_fromq(devinfo, req); 423 brcmf_usb_del_fromq(devinfo, req);
424 if (urb->status == 0)
425 devinfo->bus_pub.bus->dstats.tx_packets++;
426 else
427 devinfo->bus_pub.bus->dstats.tx_errors++;
428 424
429 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0); 425 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
430 426
@@ -451,10 +447,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
451 req->skb = NULL; 447 req->skb = NULL;
452 448
453 /* zero lenght packets indicate usb "failure". Do not refill */ 449 /* zero lenght packets indicate usb "failure". Do not refill */
454 if (urb->status == 0 && urb->actual_length) { 450 if (urb->status != 0 || !urb->actual_length) {
455 devinfo->bus_pub.bus->dstats.rx_packets++;
456 } else {
457 devinfo->bus_pub.bus->dstats.rx_errors++;
458 brcmu_pkt_buf_free_skb(skb); 451 brcmu_pkt_buf_free_skb(skb);
459 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL); 452 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
460 return; 453 return;