These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / ethernet / amd / xgbe / xgbe-ethtool.c
index 5f149e8..6040293 100644 (file)
@@ -133,6 +133,12 @@ struct xgbe_stats {
          offsetof(struct xgbe_prv_data, mmc_stats._var),       \
        }
 
+#define XGMAC_EXT_STAT(_string, _var)                          \
+       { _string,                                              \
+         FIELD_SIZEOF(struct xgbe_ext_stats, _var),            \
+         offsetof(struct xgbe_prv_data, ext_stats._var),       \
+       }
+
 static const struct xgbe_stats xgbe_gstring_stats[] = {
        XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
        XGMAC_MMC_STAT("tx_packets", txframecount_gb),
@@ -140,6 +146,7 @@ static const struct xgbe_stats xgbe_gstring_stats[] = {
        XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
        XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
        XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
+       XGMAC_EXT_STAT("tx_tso_packets", tx_tso_packets),
        XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
        XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
        XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
@@ -171,6 +178,8 @@ static const struct xgbe_stats xgbe_gstring_stats[] = {
        XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
        XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
        XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
+       XGMAC_EXT_STAT("rx_split_header_packets", rx_split_header_packets),
+       XGMAC_EXT_STAT("rx_buffer_unavailable", rx_buffer_unavailable),
 };
 
 #define XGBE_STATS_COUNT       ARRAY_SIZE(xgbe_gstring_stats)
@@ -179,8 +188,6 @@ static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 {
        int i;
 
-       DBGPR("-->%s\n", __func__);
-
        switch (stringset) {
        case ETH_SS_STATS:
                for (i = 0; i < XGBE_STATS_COUNT; i++) {
@@ -190,8 +197,6 @@ static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                }
                break;
        }
-
-       DBGPR("<--%s\n", __func__);
 }
 
 static void xgbe_get_ethtool_stats(struct net_device *netdev,
@@ -201,23 +206,17 @@ static void xgbe_get_ethtool_stats(struct net_device *netdev,
        u8 *stat;
        int i;
 
-       DBGPR("-->%s\n", __func__);
-
        pdata->hw_if.read_mmc_stats(pdata);
        for (i = 0; i < XGBE_STATS_COUNT; i++) {
                stat = (u8 *)pdata + xgbe_gstring_stats[i].stat_offset;
                *data++ = *(u64 *)stat;
        }
-
-       DBGPR("<--%s\n", __func__);
 }
 
 static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
 {
        int ret;
 
-       DBGPR("-->%s\n", __func__);
-
        switch (stringset) {
        case ETH_SS_STATS:
                ret = XGBE_STATS_COUNT;
@@ -227,8 +226,6 @@ static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
                ret = -EOPNOTSUPP;
        }
 
-       DBGPR("<--%s\n", __func__);
-
        return ret;
 }
 
@@ -237,44 +234,40 @@ static void xgbe_get_pauseparam(struct net_device *netdev,
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
 
-       DBGPR("-->xgbe_get_pauseparam\n");
-
-       pause->autoneg = pdata->pause_autoneg;
-       pause->tx_pause = pdata->tx_pause;
-       pause->rx_pause = pdata->rx_pause;
-
-       DBGPR("<--xgbe_get_pauseparam\n");
+       pause->autoneg = pdata->phy.pause_autoneg;
+       pause->tx_pause = pdata->phy.tx_pause;
+       pause->rx_pause = pdata->phy.rx_pause;
 }
 
 static int xgbe_set_pauseparam(struct net_device *netdev,
                               struct ethtool_pauseparam *pause)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
-       struct phy_device *phydev = pdata->phydev;
        int ret = 0;
 
-       DBGPR("-->xgbe_set_pauseparam\n");
-
-       DBGPR("  autoneg = %d, tx_pause = %d, rx_pause = %d\n",
-             pause->autoneg, pause->tx_pause, pause->rx_pause);
+       if (pause->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) {
+               netdev_err(netdev,
+                          "autoneg disabled, pause autoneg not avialable\n");
+               return -EINVAL;
+       }
 
-       pdata->pause_autoneg = pause->autoneg;
-       if (pause->autoneg) {
-               phydev->advertising |= ADVERTISED_Pause;
-               phydev->advertising |= ADVERTISED_Asym_Pause;
+       pdata->phy.pause_autoneg = pause->autoneg;
+       pdata->phy.tx_pause = pause->tx_pause;
+       pdata->phy.rx_pause = pause->rx_pause;
 
-       } else {
-               phydev->advertising &= ~ADVERTISED_Pause;
-               phydev->advertising &= ~ADVERTISED_Asym_Pause;
+       pdata->phy.advertising &= ~ADVERTISED_Pause;
+       pdata->phy.advertising &= ~ADVERTISED_Asym_Pause;
 
-               pdata->tx_pause = pause->tx_pause;
-               pdata->rx_pause = pause->rx_pause;
+       if (pause->rx_pause) {
+               pdata->phy.advertising |= ADVERTISED_Pause;
+               pdata->phy.advertising |= ADVERTISED_Asym_Pause;
        }
 
-       if (netif_running(netdev))
-               ret = phy_start_aneg(phydev);
+       if (pause->tx_pause)
+               pdata->phy.advertising ^= ADVERTISED_Asym_Pause;
 
-       DBGPR("<--xgbe_set_pauseparam\n");
+       if (netif_running(netdev))
+               ret = pdata->phy_if.phy_config_aneg(pdata);
 
        return ret;
 }
@@ -283,41 +276,44 @@ static int xgbe_get_settings(struct net_device *netdev,
                             struct ethtool_cmd *cmd)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
-       int ret;
 
-       DBGPR("-->xgbe_get_settings\n");
+       cmd->phy_address = pdata->phy.address;
 
-       if (!pdata->phydev)
-               return -ENODEV;
+       cmd->supported = pdata->phy.supported;
+       cmd->advertising = pdata->phy.advertising;
+       cmd->lp_advertising = pdata->phy.lp_advertising;
 
-       ret = phy_ethtool_gset(pdata->phydev, cmd);
+       cmd->autoneg = pdata->phy.autoneg;
+       ethtool_cmd_speed_set(cmd, pdata->phy.speed);
+       cmd->duplex = pdata->phy.duplex;
 
-       DBGPR("<--xgbe_get_settings\n");
+       cmd->port = PORT_NONE;
+       cmd->transceiver = XCVR_INTERNAL;
 
-       return ret;
+       return 0;
 }
 
 static int xgbe_set_settings(struct net_device *netdev,
                             struct ethtool_cmd *cmd)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
-       struct phy_device *phydev = pdata->phydev;
        u32 speed;
        int ret;
 
-       DBGPR("-->xgbe_set_settings\n");
-
-       if (!pdata->phydev)
-               return -ENODEV;
-
        speed = ethtool_cmd_speed(cmd);
 
-       if (cmd->phy_address != phydev->addr)
+       if (cmd->phy_address != pdata->phy.address) {
+               netdev_err(netdev, "invalid phy address %hhu\n",
+                          cmd->phy_address);
                return -EINVAL;
+       }
 
        if ((cmd->autoneg != AUTONEG_ENABLE) &&
-           (cmd->autoneg != AUTONEG_DISABLE))
+           (cmd->autoneg != AUTONEG_DISABLE)) {
+               netdev_err(netdev, "unsupported autoneg %hhu\n",
+                          cmd->autoneg);
                return -EINVAL;
+       }
 
        if (cmd->autoneg == AUTONEG_DISABLE) {
                switch (speed) {
@@ -326,32 +322,41 @@ static int xgbe_set_settings(struct net_device *netdev,
                case SPEED_1000:
                        break;
                default:
+                       netdev_err(netdev, "unsupported speed %u\n", speed);
                        return -EINVAL;
                }
 
-               if (cmd->duplex != DUPLEX_FULL)
+               if (cmd->duplex != DUPLEX_FULL) {
+                       netdev_err(netdev, "unsupported duplex %hhu\n",
+                                  cmd->duplex);
                        return -EINVAL;
+               }
        }
 
-       cmd->advertising &= phydev->supported;
-       if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising)
+       netif_dbg(pdata, link, netdev,
+                 "requested advertisement %#x, phy supported %#x\n",
+                 cmd->advertising, pdata->phy.supported);
+
+       cmd->advertising &= pdata->phy.supported;
+       if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising) {
+               netdev_err(netdev,
+                          "unsupported requested advertisement\n");
                return -EINVAL;
+       }
 
        ret = 0;
-       phydev->autoneg = cmd->autoneg;
-       phydev->speed = speed;
-       phydev->duplex = cmd->duplex;
-       phydev->advertising = cmd->advertising;
+       pdata->phy.autoneg = cmd->autoneg;
+       pdata->phy.speed = speed;
+       pdata->phy.duplex = cmd->duplex;
+       pdata->phy.advertising = cmd->advertising;
 
        if (cmd->autoneg == AUTONEG_ENABLE)
-               phydev->advertising |= ADVERTISED_Autoneg;
+               pdata->phy.advertising |= ADVERTISED_Autoneg;
        else
-               phydev->advertising &= ~ADVERTISED_Autoneg;
+               pdata->phy.advertising &= ~ADVERTISED_Autoneg;
 
        if (netif_running(netdev))
-               ret = phy_start_aneg(phydev);
-
-       DBGPR("<--xgbe_set_settings\n");
+               ret = pdata->phy_if.phy_config_aneg(pdata);
 
        return ret;
 }
@@ -370,7 +375,20 @@ static void xgbe_get_drvinfo(struct net_device *netdev,
                 XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
                 XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
                 XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
-       drvinfo->n_stats = XGBE_STATS_COUNT;
+}
+
+static u32 xgbe_get_msglevel(struct net_device *netdev)
+{
+       struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+       return pdata->msg_enable;
+}
+
+static void xgbe_set_msglevel(struct net_device *netdev, u32 msglevel)
+{
+       struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+       pdata->msg_enable = msglevel;
 }
 
 static int xgbe_get_coalesce(struct net_device *netdev,
@@ -378,8 +396,6 @@ static int xgbe_get_coalesce(struct net_device *netdev,
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
 
-       DBGPR("-->xgbe_get_coalesce\n");
-
        memset(ec, 0, sizeof(struct ethtool_coalesce));
 
        ec->rx_coalesce_usecs = pdata->rx_usecs;
@@ -387,8 +403,6 @@ static int xgbe_get_coalesce(struct net_device *netdev,
 
        ec->tx_max_coalesced_frames = pdata->tx_frames;
 
-       DBGPR("<--xgbe_get_coalesce\n");
-
        return 0;
 }
 
@@ -400,8 +414,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
        unsigned int rx_frames, rx_riwt, rx_usecs;
        unsigned int tx_frames;
 
-       DBGPR("-->xgbe_set_coalesce\n");
-
        /* Check for not supported parameters  */
        if ((ec->rx_coalesce_usecs_irq) ||
            (ec->rx_max_coalesced_frames_irq) ||
@@ -421,8 +433,10 @@ static int xgbe_set_coalesce(struct net_device *netdev,
            (ec->rx_max_coalesced_frames_high) ||
            (ec->tx_coalesce_usecs_high) ||
            (ec->tx_max_coalesced_frames_high) ||
-           (ec->rate_sample_interval))
+           (ec->rate_sample_interval)) {
+               netdev_err(netdev, "unsupported coalescing parameter\n");
                return -EOPNOTSUPP;
+       }
 
        rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
        rx_usecs = ec->rx_coalesce_usecs;
@@ -434,13 +448,13 @@ static int xgbe_set_coalesce(struct net_device *netdev,
 
        /* Check the bounds of values for Rx */
        if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
-               netdev_alert(netdev, "rx-usec is limited to %d usecs\n",
-                            hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
+               netdev_err(netdev, "rx-usec is limited to %d usecs\n",
+                          hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
                return -EINVAL;
        }
        if (rx_frames > pdata->rx_desc_count) {
-               netdev_alert(netdev, "rx-frames is limited to %d frames\n",
-                            pdata->rx_desc_count);
+               netdev_err(netdev, "rx-frames is limited to %d frames\n",
+                          pdata->rx_desc_count);
                return -EINVAL;
        }
 
@@ -448,8 +462,8 @@ static int xgbe_set_coalesce(struct net_device *netdev,
 
        /* Check the bounds of values for Tx */
        if (tx_frames > pdata->tx_desc_count) {
-               netdev_alert(netdev, "tx-frames is limited to %d frames\n",
-                            pdata->tx_desc_count);
+               netdev_err(netdev, "tx-frames is limited to %d frames\n",
+                          pdata->tx_desc_count);
                return -EINVAL;
        }
 
@@ -461,8 +475,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
        pdata->tx_frames = tx_frames;
        hw_if->config_tx_coalesce(pdata);
 
-       DBGPR("<--xgbe_set_coalesce\n");
-
        return 0;
 }
 
@@ -524,8 +536,10 @@ static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
        unsigned int ret;
 
-       if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
+       if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) {
+               netdev_err(netdev, "unsupported hash function\n");
                return -EOPNOTSUPP;
+       }
 
        if (indir) {
                ret = hw_if->set_rss_lookup_table(pdata, indir);
@@ -579,6 +593,8 @@ static const struct ethtool_ops xgbe_ethtool_ops = {
        .get_settings = xgbe_get_settings,
        .set_settings = xgbe_set_settings,
        .get_drvinfo = xgbe_get_drvinfo,
+       .get_msglevel = xgbe_get_msglevel,
+       .set_msglevel = xgbe_set_msglevel,
        .get_link = ethtool_op_get_link,
        .get_coalesce = xgbe_get_coalesce,
        .set_coalesce = xgbe_set_coalesce,