stmmac: do not discard frame on dribbling bit assert
[linux-2.6.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_ethtool.c
index aedff9a..f98e151 100644 (file)
@@ -47,23 +47,25 @@ struct stmmac_stats {
        offsetof(struct stmmac_priv, xstats.m)}
 
 static const struct stmmac_stats stmmac_gstrings_stats[] = {
+       /* Transmit errors */
        STMMAC_STAT(tx_underflow),
        STMMAC_STAT(tx_carrier),
        STMMAC_STAT(tx_losscarrier),
-       STMMAC_STAT(tx_heartbeat),
+       STMMAC_STAT(vlan_tag),
        STMMAC_STAT(tx_deferred),
        STMMAC_STAT(tx_vlan),
-       STMMAC_STAT(rx_vlan),
        STMMAC_STAT(tx_jabber),
        STMMAC_STAT(tx_frame_flushed),
        STMMAC_STAT(tx_payload_error),
        STMMAC_STAT(tx_ip_header_error),
+       /* Receive errors */
        STMMAC_STAT(rx_desc),
-       STMMAC_STAT(rx_partial),
-       STMMAC_STAT(rx_runt),
-       STMMAC_STAT(rx_toolong),
+       STMMAC_STAT(sa_filter_fail),
+       STMMAC_STAT(overflow_error),
+       STMMAC_STAT(ipc_csum_error),
        STMMAC_STAT(rx_collision),
        STMMAC_STAT(rx_crc),
+       STMMAC_STAT(dribbling_bit),
        STMMAC_STAT(rx_length),
        STMMAC_STAT(rx_mii),
        STMMAC_STAT(rx_multicast),
@@ -73,6 +75,8 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
        STMMAC_STAT(sa_rx_filter_fail),
        STMMAC_STAT(rx_missed_cntr),
        STMMAC_STAT(rx_overflow_cntr),
+       STMMAC_STAT(rx_vlan),
+       /* Tx/Rx IRQ errors */
        STMMAC_STAT(tx_undeflow_irq),
        STMMAC_STAT(tx_process_stopped_irq),
        STMMAC_STAT(tx_jabber_irq),
@@ -82,6 +86,7 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
        STMMAC_STAT(rx_watchdog_irq),
        STMMAC_STAT(tx_early_irq),
        STMMAC_STAT(fatal_bus_error_irq),
+       /* Extra info */
        STMMAC_STAT(threshold),
        STMMAC_STAT(tx_pkt_n),
        STMMAC_STAT(rx_pkt_n),
@@ -96,7 +101,7 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
        { #m, FIELD_SIZEOF(struct stmmac_counters, m),  \
        offsetof(struct stmmac_priv, mmc.m)}
 
-static const struct stmmac_stats stmmac_gstr_mmc[] = {
+static const struct stmmac_stats stmmac_mmc[] = {
        STMMAC_MMC_STAT(mmc_tx_octetcount_gb),
        STMMAC_MMC_STAT(mmc_tx_framecount_gb),
        STMMAC_MMC_STAT(mmc_tx_broadcastframe_g),
@@ -177,7 +182,7 @@ static const struct stmmac_stats stmmac_gstr_mmc[] = {
        STMMAC_MMC_STAT(mmc_rx_icmp_gd_octets),
        STMMAC_MMC_STAT(mmc_rx_icmp_err_octets),
 };
-#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_gstr_mmc)
+#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc)
 
 static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
                                      struct ethtool_drvinfo *info)
@@ -185,9 +190,10 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
        struct stmmac_priv *priv = netdev_priv(dev);
 
        if (priv->plat->has_gmac)
-               strcpy(info->driver, GMAC_ETHTOOL_NAME);
+               strlcpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver));
        else
-               strcpy(info->driver, MAC100_ETHTOOL_NAME);
+               strlcpy(info->driver, MAC100_ETHTOOL_NAME,
+                       sizeof(info->driver));
 
        strcpy(info->version, DRV_MODULE_VERSION);
        info->fw_version[0] = '\0';
@@ -348,13 +354,17 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
                                                 priv->ioaddr);
        else {
                /* If supported, for new GMAC chips expose the MMC counters */
-               dwmac_mmc_read(priv->ioaddr, &priv->mmc);
+               if (priv->dma_cap.rmon) {
+                       dwmac_mmc_read(priv->ioaddr, &priv->mmc);
 
-               for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
-                       char *p = (char *)priv + stmmac_gstr_mmc[i].stat_offset;
+                       for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
+                               char *p;
+                               p = (char *)priv + stmmac_mmc[i].stat_offset;
 
-                       data[j++] = (stmmac_gstr_mmc[i].sizeof_stat ==
-                                    sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
+                               data[j++] = (stmmac_mmc[i].sizeof_stat ==
+                                            sizeof(u64)) ? (*(u64 *)p) :
+                                            (*(u32 *)p);
+                       }
                }
        }
        for (i = 0; i < STMMAC_STATS_LEN; i++) {
@@ -373,7 +383,7 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)
        case ETH_SS_STATS:
                len = STMMAC_STATS_LEN;
 
-               if (priv->plat->has_gmac)
+               if (priv->dma_cap.rmon)
                        len += STMMAC_MMC_STATS_LEN;
 
                return len;
@@ -390,9 +400,9 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 
        switch (stringset) {
        case ETH_SS_STATS:
-               if (priv->plat->has_gmac)
+               if (priv->dma_cap.rmon)
                        for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
-                               memcpy(p, stmmac_gstr_mmc[i].stat_string,
+                               memcpy(p, stmmac_mmc[i].stat_string,
                                       ETH_GSTRING_LEN);
                                p += ETH_GSTRING_LEN;
                        }
@@ -426,6 +436,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        struct stmmac_priv *priv = netdev_priv(dev);
        u32 support = WAKE_MAGIC | WAKE_UCAST;
 
+       /* By default almost all GMAC devices support the WoL via
+        * magic frame but we can disable it if the HW capability
+        * register shows no support for pmt_magic_frame. */
+       if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
+               wol->wolopts &= ~WAKE_MAGIC;
+
        if (!device_can_wakeup(priv->device))
                return -EINVAL;
 
@@ -448,7 +464,7 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        return 0;
 }
 
-static struct ethtool_ops stmmac_ethtool_ops = {
+static const struct ethtool_ops stmmac_ethtool_ops = {
        .begin = stmmac_check_if_running,
        .get_drvinfo = stmmac_ethtool_getdrvinfo,
        .get_settings = stmmac_ethtool_getsettings,