From: Francois Romieu <rom...@fr.zoreil.com>

Signed-off-by: Francois Romieu <rom...@fr.zoreil.com>
Cc: Corinna Vinschen <vinsc...@redhat.com>
Cc: pomidorabelis...@gmail.com
---
 drivers/net/ethernet/realtek/r8169.c | 70 +++++++++++++++++++++---------------
 1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 24dcbe6..73a60a7 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -833,7 +833,7 @@ struct rtl8169_private {
        unsigned features;
 
        struct mii_if_info mii;
-       struct rtl8169_counters counters;
+       struct rtl8169_counters *counters;
        struct rtl8169_tc_offsets tc_offset;
        u32 saved_wolopts;
        u32 opts1_mask;
@@ -2296,6 +2296,8 @@ static bool rtl8169_update_counters(struct net_device 
*dev)
 static bool rtl8169_init_counter_offsets(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
+       struct rtl8169_counters *counters = tp->counters;
+       struct rtl8169_tc_offsets *offset = &tp->tc_offset;
        bool ret = false;
 
        /*
@@ -2313,7 +2315,7 @@ static bool rtl8169_init_counter_offsets(struct 
net_device *dev)
         * set at open time by rtl_hw_start.
         */
 
-       if (tp->tc_offset.inited)
+       if (offset->inited)
                return true;
 
        /* If both, reset and update fail, propagate to caller. */
@@ -2323,10 +2325,10 @@ static bool rtl8169_init_counter_offsets(struct 
net_device *dev)
        if (rtl8169_update_counters(dev))
                ret = true;
 
-       tp->tc_offset.tx_errors = tp->counters.tx_errors;
-       tp->tc_offset.tx_multi_collision = tp->counters.tx_multi_collision;
-       tp->tc_offset.tx_aborted = tp->counters.tx_aborted;
-       tp->tc_offset.inited = true;
+       offset->tx_errors = counters->tx_errors;
+       offset->tx_multi_collision = counters->tx_multi_collision;
+       offset->tx_aborted = counters->tx_aborted;
+       offset->inited = true;
 
        return ret;
 }
@@ -2335,24 +2337,25 @@ static void rtl8169_get_ethtool_stats(struct net_device 
*dev,
                                      struct ethtool_stats *stats, u64 *data)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
+       struct rtl8169_counters *c = tp->counters;
 
        ASSERT_RTNL();
 
        rtl8169_update_counters(dev);
 
-       data[0] = le64_to_cpu(tp->counters.tx_packets);
-       data[1] = le64_to_cpu(tp->counters.rx_packets);
-       data[2] = le64_to_cpu(tp->counters.tx_errors);
-       data[3] = le32_to_cpu(tp->counters.rx_errors);
-       data[4] = le16_to_cpu(tp->counters.rx_missed);
-       data[5] = le16_to_cpu(tp->counters.align_errors);
-       data[6] = le32_to_cpu(tp->counters.tx_one_collision);
-       data[7] = le32_to_cpu(tp->counters.tx_multi_collision);
-       data[8] = le64_to_cpu(tp->counters.rx_unicast);
-       data[9] = le64_to_cpu(tp->counters.rx_broadcast);
-       data[10] = le32_to_cpu(tp->counters.rx_multicast);
-       data[11] = le16_to_cpu(tp->counters.tx_aborted);
-       data[12] = le16_to_cpu(tp->counters.tx_underun);
+       data[ 0] = le64_to_cpu(c->tx_packets);
+       data[ 1] = le64_to_cpu(c->rx_packets);
+       data[ 2] = le64_to_cpu(c->tx_errors);
+       data[ 3] = le32_to_cpu(c->rx_errors);
+       data[ 4] = le16_to_cpu(c->rx_missed);
+       data[ 5] = le16_to_cpu(c->align_errors);
+       data[ 6] = le32_to_cpu(c->tx_one_collision);
+       data[ 7] = le32_to_cpu(c->tx_multi_collision);
+       data[ 8] = le64_to_cpu(c->rx_unicast);
+       data[ 9] = le64_to_cpu(c->rx_broadcast);
+       data[10] = le32_to_cpu(c->rx_multicast);
+       data[11] = le16_to_cpu(c->tx_aborted);
+       data[12] = le16_to_cpu(c->tx_underun);
 }
 
 static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 
*data)
@@ -7671,6 +7674,8 @@ static int rtl8169_close(struct net_device *dev)
 
        free_irq(pdev->irq, dev);
 
+       kfree(tp->counters);
+
        dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
                          tp->RxPhyAddr);
        dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
@@ -7715,9 +7720,13 @@ static int rtl_open(struct net_device *dev)
        if (!tp->RxDescArray)
                goto err_free_tx_0;
 
+       tp->counters = kmalloc(sizeof(*tp->counters), GFP_KERNEL);
+       if (!tp->counters)
+               goto err_free_rx_1;
+
        retval = rtl8169_init_ring(dev);
        if (retval < 0)
-               goto err_free_rx_1;
+               goto err_free_counters_2;
 
        INIT_WORK(&tp->wk.work, rtl_task);
 
@@ -7729,7 +7738,7 @@ static int rtl_open(struct net_device *dev)
                             (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED,
                             dev->name, dev);
        if (retval < 0)
-               goto err_release_fw_2;
+               goto err_release_fw_3;
 
        rtl_lock_work(tp);
 
@@ -7759,9 +7768,12 @@ static int rtl_open(struct net_device *dev)
 out:
        return retval;
 
-err_release_fw_2:
+err_release_fw_3:
        rtl_release_firmware(tp);
        rtl8169_rx_clear(tp);
+err_free_counters_2:
+       kfree(tp->counters);
+       tp->counters = NULL;
 err_free_rx_1:
        dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
                          tp->RxPhyAddr);
@@ -7779,6 +7791,8 @@ static struct rtnl_link_stats64 *
 rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
+       struct rtl8169_tc_offsets *offset = &tp->tc_offset;
+       struct rtl8169_counters *counters = tp->counters;
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned int start;
 
@@ -7816,12 +7830,12 @@ rtl8169_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
         * Subtract values fetched during initalization.
         * See rtl8169_init_counter_offsets for a description why we do that.
         */
-       stats->tx_errors = le64_to_cpu(tp->counters.tx_errors) -
-               le64_to_cpu(tp->tc_offset.tx_errors);
-       stats->collisions = le32_to_cpu(tp->counters.tx_multi_collision) -
-               le32_to_cpu(tp->tc_offset.tx_multi_collision);
-       stats->tx_aborted_errors = le16_to_cpu(tp->counters.tx_aborted) -
-               le16_to_cpu(tp->tc_offset.tx_aborted);
+       stats->tx_errors = le64_to_cpu(counters->tx_errors) -
+                          le64_to_cpu(offset->tx_errors);
+       stats->collisions = le32_to_cpu(counters->tx_multi_collision) -
+                           le32_to_cpu(offset->tx_multi_collision);
+       stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) -
+                                  le16_to_cpu(offset->tx_aborted);
 
        return stats;
 }
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to