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;
enum brcmf_bus_state state;
uint maxctl;
unsigned long tx_realloc;
- struct dngl_stats dstats;
u8 align;
struct list_head dcmd_list;
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;
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;
}
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;
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);
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;
}
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;
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) {
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;
}
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;
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]);
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));
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) {
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);
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;