Merge remote branch 'origin/master'
[deliverable/linux.git] / drivers / net / s2io.c
index 92ae8d3de39be642cccc50321696895bac745f1c..1d37f0c310ca4bd91d715129f24a11356ad41fa1 100644 (file)
@@ -2400,7 +2400,7 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data,
                return NULL;
        }
        pci_unmap_single(nic->pdev, (dma_addr_t)txds->Buffer_Pointer,
-                        skb->len - skb->data_len, PCI_DMA_TODEVICE);
+                        skb_headlen(skb), PCI_DMA_TODEVICE);
        frg_cnt = skb_shinfo(skb)->nr_frags;
        if (frg_cnt) {
                txds++;
@@ -2943,7 +2943,6 @@ static void s2io_netpoll(struct net_device *dev)
                }
        }
        enable_irq(dev->irq);
-       return;
 }
 #endif
 
@@ -3131,7 +3130,6 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
                pkt_cnt++;
 
                /* Updating the statistics block */
-               nic->dev->stats.tx_bytes += skb->len;
                swstats->mem_freed += skb->truesize;
                dev_kfree_skb_irq(skb);
 
@@ -4202,7 +4200,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
        }
 
-       frg_len = skb->len - skb->data_len;
+       frg_len = skb_headlen(skb);
        if (offload_type == SKB_GSO_UDP) {
                int ufo_size;
 
@@ -4756,7 +4754,6 @@ reset:
        s2io_stop_all_tx_queue(sp);
        schedule_work(&sp->rst_timer_task);
        sw_stat->soft_reset_cnt++;
-       return;
 }
 
 /**
@@ -4903,48 +4900,81 @@ static void s2io_updt_stats(struct s2io_nic *sp)
  *  Return value:
  *  pointer to the updated net_device_stats structure.
  */
-
 static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 {
        struct s2io_nic *sp = netdev_priv(dev);
-       struct config_param *config = &sp->config;
        struct mac_info *mac_control = &sp->mac_control;
        struct stat_block *stats = mac_control->stats_info;
-       int i;
+       u64 delta;
 
        /* Configure Stats for immediate updt */
        s2io_updt_stats(sp);
 
-       /* Using sp->stats as a staging area, because reset (due to mtu
-          change, for example) will clear some hardware counters */
-       dev->stats.tx_packets += le32_to_cpu(stats->tmac_frms) -
-               sp->stats.tx_packets;
-       sp->stats.tx_packets = le32_to_cpu(stats->tmac_frms);
-
-       dev->stats.tx_errors += le32_to_cpu(stats->tmac_any_err_frms) -
-               sp->stats.tx_errors;
-       sp->stats.tx_errors = le32_to_cpu(stats->tmac_any_err_frms);
-
-       dev->stats.rx_errors += le64_to_cpu(stats->rmac_drop_frms) -
-               sp->stats.rx_errors;
-       sp->stats.rx_errors = le64_to_cpu(stats->rmac_drop_frms);
-
-       dev->stats.multicast = le32_to_cpu(stats->rmac_vld_mcst_frms) -
-               sp->stats.multicast;
-       sp->stats.multicast = le32_to_cpu(stats->rmac_vld_mcst_frms);
-
-       dev->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms) -
-               sp->stats.rx_length_errors;
-       sp->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms);
+       /* A device reset will cause the on-adapter statistics to be zero'ed.
+        * This can be done while running by changing the MTU.  To prevent the
+        * system from having the stats zero'ed, the driver keeps a copy of the
+        * last update to the system (which is also zero'ed on reset).  This
+        * enables the driver to accurately know the delta between the last
+        * update and the current update.
+        */
+       delta = ((u64) le32_to_cpu(stats->rmac_vld_frms_oflow) << 32 |
+               le32_to_cpu(stats->rmac_vld_frms)) - sp->stats.rx_packets;
+       sp->stats.rx_packets += delta;
+       dev->stats.rx_packets += delta;
+
+       delta = ((u64) le32_to_cpu(stats->tmac_frms_oflow) << 32 |
+               le32_to_cpu(stats->tmac_frms)) - sp->stats.tx_packets;
+       sp->stats.tx_packets += delta;
+       dev->stats.tx_packets += delta;
+
+       delta = ((u64) le32_to_cpu(stats->rmac_data_octets_oflow) << 32 |
+               le32_to_cpu(stats->rmac_data_octets)) - sp->stats.rx_bytes;
+       sp->stats.rx_bytes += delta;
+       dev->stats.rx_bytes += delta;
+
+       delta = ((u64) le32_to_cpu(stats->tmac_data_octets_oflow) << 32 |
+               le32_to_cpu(stats->tmac_data_octets)) - sp->stats.tx_bytes;
+       sp->stats.tx_bytes += delta;
+       dev->stats.tx_bytes += delta;
+
+       delta = le64_to_cpu(stats->rmac_drop_frms) - sp->stats.rx_errors;
+       sp->stats.rx_errors += delta;
+       dev->stats.rx_errors += delta;
+
+       delta = ((u64) le32_to_cpu(stats->tmac_any_err_frms_oflow) << 32 |
+               le32_to_cpu(stats->tmac_any_err_frms)) - sp->stats.tx_errors;
+       sp->stats.tx_errors += delta;
+       dev->stats.tx_errors += delta;
+
+       delta = le64_to_cpu(stats->rmac_drop_frms) - sp->stats.rx_dropped;
+       sp->stats.rx_dropped += delta;
+       dev->stats.rx_dropped += delta;
+
+       delta = le64_to_cpu(stats->tmac_drop_frms) - sp->stats.tx_dropped;
+       sp->stats.tx_dropped += delta;
+       dev->stats.tx_dropped += delta;
+
+       /* The adapter MAC interprets pause frames as multicast packets, but
+        * does not pass them up.  This erroneously increases the multicast
+        * packet count and needs to be deducted when the multicast frame count
+        * is queried.
+        */
+       delta = (u64) le32_to_cpu(stats->rmac_vld_mcst_frms_oflow) << 32 |
+               le32_to_cpu(stats->rmac_vld_mcst_frms);
+       delta -= le64_to_cpu(stats->rmac_pause_ctrl_frms);
+       delta -= sp->stats.multicast;
+       sp->stats.multicast += delta;
+       dev->stats.multicast += delta;
 
-       /* collect per-ring rx_packets and rx_bytes */
-       dev->stats.rx_packets = dev->stats.rx_bytes = 0;
-       for (i = 0; i < config->rx_ring_num; i++) {
-               struct ring_info *ring = &mac_control->rings[i];
+       delta = ((u64) le32_to_cpu(stats->rmac_usized_frms_oflow) << 32 |
+               le32_to_cpu(stats->rmac_usized_frms)) +
+               le64_to_cpu(stats->rmac_long_frms) - sp->stats.rx_length_errors;
+       sp->stats.rx_length_errors += delta;
+       dev->stats.rx_length_errors += delta;
 
-               dev->stats.rx_packets += ring->rx_packets;
-               dev->stats.rx_bytes += ring->rx_bytes;
-       }
+       delta = le64_to_cpu(stats->rmac_fcs_err_frms) - sp->stats.rx_crc_errors;
+       sp->stats.rx_crc_errors += delta;
+       dev->stats.rx_crc_errors += delta;
 
        return &dev->stats;
 }
@@ -4965,7 +4995,7 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 static void s2io_set_multicast(struct net_device *dev)
 {
        int i, j, prev_cnt;
-       struct dev_mc_list *mclist;
+       struct netdev_hw_addr *ha;
        struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
@@ -5094,12 +5124,12 @@ static void s2io_set_multicast(struct net_device *dev)
 
                /* Create the new Rx filter list and update the same in H/W. */
                i = 0;
-               netdev_for_each_mc_addr(mclist, dev) {
-                       memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr,
+               netdev_for_each_mc_addr(ha, dev) {
+                       memcpy(sp->usr_addrs[i].addr, ha->addr,
                               ETH_ALEN);
                        mac_addr = 0;
                        for (j = 0; j < ETH_ALEN; j++) {
-                               mac_addr |= mclist->dmi_addr[j];
+                               mac_addr |= ha->addr[j];
                                mac_addr <<= 8;
                        }
                        mac_addr >>= 8;
@@ -7457,15 +7487,11 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                }
        }
 
-       /* Updating statistics */
-       ring_data->rx_packets++;
        rxdp->Host_Control = 0;
        if (sp->rxd_mode == RXD_MODE_1) {
                int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
 
-               ring_data->rx_bytes += len;
                skb_put(skb, len);
-
        } else if (sp->rxd_mode == RXD_MODE_3B) {
                int get_block = ring_data->rx_curr_get_info.block_index;
                int get_off = ring_data->rx_curr_get_info.offset;
@@ -7474,7 +7500,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                unsigned char *buff = skb_push(skb, buf0_len);
 
                struct buffAdd *ba = &ring_data->ba[get_block][get_off];
-               ring_data->rx_bytes += buf0_len + buf2_len;
                memcpy(buff, ba->ba_0, buf0_len);
                skb_put(skb, buf2_len);
        }
@@ -8645,7 +8670,6 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
        first->truesize += skb->truesize;
        lro->last_frag = skb;
        swstats->clubbed_frms_cnt++;
-       return;
 }
 
 /**
This page took 0.027019 seconds and 5 git commands to generate.