brcmfmac: Track statistics per ifp.
authorHante Meuleman <meuleman@broadcom.com>
Wed, 6 Feb 2013 17:40:41 +0000 (18:40 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 8 Feb 2013 19:51:33 +0000 (14:51 -0500)
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>
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c

index 57826dcbe9b9acac1a22869e014185e2a8debb3d..6af7c9dce0f7ef31078beefe1ebf60df0e30e44f 100644 (file)
@@ -24,18 +24,6 @@ enum brcmf_bus_state {
        BRCMF_BUS_DATA          /* Ready for frame transfers */
 };
 
-struct dngl_stats {
-       unsigned long rx_packets;       /* total packets received */
-       unsigned long tx_packets;       /* total packets transmitted */
-       unsigned long rx_bytes; /* total bytes received */
-       unsigned long tx_bytes; /* total bytes transmitted */
-       unsigned long rx_errors;        /* bad packets received */
-       unsigned long tx_errors;        /* packet transmit problems */
-       unsigned long rx_dropped;       /* packets dropped by dongle */
-       unsigned long tx_dropped;       /* packets dropped by dongle */
-       unsigned long multicast;        /* multicast packets received */
-};
-
 struct brcmf_bus_dcmd {
        char *name;
        char *param;
@@ -87,7 +75,6 @@ struct brcmf_bus {
        enum brcmf_bus_state state;
        uint maxctl;
        unsigned long tx_realloc;
-       struct dngl_stats dstats;
        u8 align;
        struct list_head dcmd_list;
 
index 9a4494a5b711a87018b6d2aae5187d1c549c78a6..05cae3736e50a0505cc18de80866d58cef500d80 100644 (file)
@@ -226,10 +226,12 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
        ret =  brcmf_bus_txdata(drvr->bus_if, skb);
 
 done:
-       if (ret)
-               drvr->bus_if->dstats.tx_dropped++;
-       else
-               drvr->bus_if->dstats.tx_packets++;
+       if (ret) {
+               ifp->stats.tx_dropped++;
+       } else {
+               ifp->stats.tx_packets++;
+               ifp->stats.tx_bytes += skb->len;
+       }
 
        /* Return ok: we always eat the packet */
        return NETDEV_TX_OK;
@@ -270,12 +272,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
        skb_queue_walk_safe(skb_list, skb, pnext) {
                skb_unlink(skb, skb_list);
 
-               /* process and remove protocol-specific header
-                */
+               /* process and remove protocol-specific header */
                ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
-               if (ret < 0) {
-                       if (ret != -ENODATA)
-                               bus_if->dstats.rx_errors++;
+               ifp = drvr->iflist[ifidx];
+
+               if (ret || !ifp || !ifp->ndev) {
+                       if ((ret != -ENODATA) && ifp)
+                               ifp->stats.rx_errors++;
                        brcmu_pkt_buf_free_skb(skb);
                        continue;
                }
@@ -295,21 +298,11 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
                eth = skb->data;
                len = skb->len;
 
-               ifp = drvr->iflist[ifidx];
-               if (ifp == NULL)
-                       ifp = drvr->iflist[0];
-
-               if (!ifp || !ifp->ndev ||
-                   ifp->ndev->reg_state != NETREG_REGISTERED) {
-                       brcmu_pkt_buf_free_skb(skb);
-                       continue;
-               }
-
                skb->dev = ifp->ndev;
                skb->protocol = eth_type_trans(skb, skb->dev);
 
                if (skb->pkt_type == PACKET_MULTICAST)
-                       bus_if->dstats.multicast++;
+                       ifp->stats.multicast++;
 
                skb->data = eth;
                skb->len = len;
@@ -325,8 +318,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
                        ifp->ndev->last_rx = jiffies;
                }
 
-               bus_if->dstats.rx_bytes += skb->len;
-               bus_if->dstats.rx_packets++;    /* Local count */
+               if (!(ifp->ndev->flags & IFF_UP)) {
+                       brcmu_pkt_buf_free_skb(skb);
+                       continue;
+               }
+
+               ifp->stats.rx_bytes += skb->len;
+               ifp->stats.rx_packets++;
 
                if (in_interrupt())
                        netif_rx(skb);
@@ -352,35 +350,28 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
 
        brcmf_proto_hdrpull(drvr, &ifidx, txp);
 
+       ifp = drvr->iflist[ifidx];
+       if (!ifp)
+               return;
+
        eh = (struct ethhdr *)(txp->data);
        type = ntohs(eh->h_proto);
 
        if (type == ETH_P_PAE) {
-               ifp = drvr->iflist[ifidx];
                atomic_dec(&ifp->pend_8021x_cnt);
                if (waitqueue_active(&ifp->pend_8021x_wait))
                        wake_up(&ifp->pend_8021x_wait);
        }
+       if (!success)
+               ifp->stats.tx_errors++;
 }
 
 static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
 {
        struct brcmf_if *ifp = netdev_priv(ndev);
-       struct brcmf_bus *bus_if = ifp->drvr->bus_if;
 
        brcmf_dbg(TRACE, "Enter\n");
 
-       /* Copy dongle stats to net device stats */
-       ifp->stats.rx_packets = bus_if->dstats.rx_packets;
-       ifp->stats.tx_packets = bus_if->dstats.tx_packets;
-       ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
-       ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
-       ifp->stats.rx_errors = bus_if->dstats.rx_errors;
-       ifp->stats.tx_errors = bus_if->dstats.tx_errors;
-       ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
-       ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
-       ifp->stats.multicast = bus_if->dstats.multicast;
-
        return &ifp->stats;
 }
 
index df8a185719514a09615e20693ba3a3dc048a503e..d424dd63077b98c83afee7c4a61773afe6e1139c 100644 (file)
@@ -1096,7 +1096,6 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
        if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
            type != BRCMF_SDIO_FT_SUPER) {
                brcmf_err("HW header length too long\n");
-               bus->sdiodev->bus_if->dstats.rx_errors++;
                bus->sdcnt.rx_toolong++;
                brcmf_sdbrcm_rxfail(bus, false, false);
                rd->len = 0;
@@ -1298,7 +1297,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                if (errcode < 0) {
                        brcmf_err("glom read of %d bytes failed: %d\n",
                                  dlen, errcode);
-                       bus->sdiodev->bus_if->dstats.rx_errors++;
 
                        sdio_claim_host(bus->sdiodev->func[1]);
                        if (bus->glomerr++ < 3) {
@@ -1478,7 +1476,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
        if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
                brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
                          rdlen, bus->sdiodev->bus_if->maxctl);
-               bus->sdiodev->bus_if->dstats.rx_errors++;
                brcmf_sdbrcm_rxfail(bus, false, false);
                goto done;
        }
@@ -1486,7 +1483,6 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
        if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
                brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
                          len, len - doff, bus->sdiodev->bus_if->maxctl);
-               bus->sdiodev->bus_if->dstats.rx_errors++;
                bus->sdcnt.rx_toolong++;
                brcmf_sdbrcm_rxfail(bus, false, false);
                goto done;
@@ -1634,7 +1630,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
                if (!pkt) {
                        /* Give up on data, request rtx of events */
                        brcmf_err("brcmu_pkt_buf_get_skb failed\n");
-                       bus->sdiodev->bus_if->dstats.rx_dropped++;
                        brcmf_sdbrcm_rxfail(bus, false,
                                            RETRYCHAN(rd->channel));
                        sdio_release_host(bus->sdiodev->func[1]);
@@ -1652,7 +1647,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
                        brcmf_err("read %d bytes from channel %d failed: %d\n",
                                  rd->len, rd->channel, sdret);
                        brcmu_pkt_buf_free_skb(pkt);
-                       bus->sdiodev->bus_if->dstats.rx_errors++;
                        sdio_claim_host(bus->sdiodev->func[1]);
                        brcmf_sdbrcm_rxfail(bus, true,
                                            RETRYCHAN(rd->channel));
@@ -1940,10 +1934,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
                datalen = pkt->len - SDPCM_HDRLEN;
 
                ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
-               if (ret)
-                       bus->sdiodev->bus_if->dstats.tx_errors++;
-               else
-                       bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
 
                /* In poll mode, need to check for other events */
                if (!bus->intr && cnt) {
index e15630cc3889fcb5f4644e9332ad60ecb68d679f..06f7339b50b4ade1212e3e8cc080c7307f4dfe93 100644 (file)
@@ -421,10 +421,6 @@ static void brcmf_usb_tx_complete(struct urb *urb)
        brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
                  req->skb);
        brcmf_usb_del_fromq(devinfo, req);
-       if (urb->status == 0)
-               devinfo->bus_pub.bus->dstats.tx_packets++;
-       else
-               devinfo->bus_pub.bus->dstats.tx_errors++;
 
        brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
 
@@ -451,10 +447,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
        req->skb = NULL;
 
        /* zero lenght packets indicate usb "failure". Do not refill */
-       if (urb->status == 0 && urb->actual_length) {
-               devinfo->bus_pub.bus->dstats.rx_packets++;
-       } else {
-               devinfo->bus_pub.bus->dstats.rx_errors++;
+       if (urb->status != 0 || !urb->actual_length) {
                brcmu_pkt_buf_free_skb(skb);
                brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
                return;