Both ENETC v1 and v4 support Receive Side Scaling (RSS), but the offset of the RSS key registers is different. In order to make enetc_get_rxfh() and enetc_set_rxfh() be reused by ENETC v4, the .set_rss_key() and .get_rss_key() interfaces are added to enect_pf_ops.
Signed-off-by: Wei Fang <wei.f...@nxp.com> --- drivers/net/ethernet/freescale/enetc/enetc.h | 1 - .../ethernet/freescale/enetc/enetc_ethtool.c | 42 +++++++++---------- .../net/ethernet/freescale/enetc/enetc_pf.c | 18 ++++++++ .../net/ethernet/freescale/enetc/enetc_pf.h | 2 + 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h index ca1bc85c0ac9..fb53fb961364 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -537,7 +537,6 @@ int enetc_set_mac_flt_entry(struct enetc_si *si, int index, int enetc_clear_mac_flt_entry(struct enetc_si *si, int index); int enetc_set_fs_entry(struct enetc_si *si, struct enetc_cmd_rfse *rfse, int index); -void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes); int enetc_get_rss_table(struct enetc_si *si, u32 *table, int count); int enetc_set_rss_table(struct enetc_si *si, const u32 *table, int count); int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd); diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c index bf34b5bb1e35..56ba82830279 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c @@ -4,7 +4,8 @@ #include <linux/ethtool_netlink.h> #include <linux/net_tstamp.h> #include <linux/module.h> -#include "enetc.h" + +#include "enetc_pf.h" static const u32 enetc_si_regs[] = { ENETC_SIMR, ENETC_SIPMAR0, ENETC_SIPMAR1, ENETC_SICBDRMR, @@ -681,51 +682,46 @@ static int enetc_get_rxfh(struct net_device *ndev, struct ethtool_rxfh_param *rxfh) { struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct enetc_hw *hw = &priv->si->hw; - int err = 0, i; + struct enetc_si *si = priv->si; + struct enetc_hw *hw = &si->hw; + int err = 0; /* return hash function */ rxfh->hfunc = ETH_RSS_HASH_TOP; /* return hash key */ - if (rxfh->key && hw->port) - for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++) - ((u32 *)rxfh->key)[i] = enetc_port_rd(hw, - ENETC_PRSSK(i)); + if (rxfh->key && enetc_si_is_pf(si)) { + struct enetc_pf *pf = enetc_si_priv(si); + + pf->ops->get_rss_key(hw, rxfh->key); + } /* return RSS table */ if (rxfh->indir) - err = enetc_get_rss_table(priv->si, rxfh->indir, - priv->si->num_rss); + err = enetc_get_rss_table(si, rxfh->indir, si->num_rss); return err; } -void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes) -{ - int i; - - for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++) - enetc_port_wr(hw, ENETC_PRSSK(i), ((u32 *)bytes)[i]); -} -EXPORT_SYMBOL_GPL(enetc_set_rss_key); - static int enetc_set_rxfh(struct net_device *ndev, struct ethtool_rxfh_param *rxfh, struct netlink_ext_ack *extack) { struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct enetc_hw *hw = &priv->si->hw; + struct enetc_si *si = priv->si; + struct enetc_hw *hw = &si->hw; int err = 0; /* set hash key, if PF */ - if (rxfh->key && hw->port) - enetc_set_rss_key(hw, rxfh->key); + if (rxfh->key && enetc_si_is_pf(si)) { + struct enetc_pf *pf = enetc_si_priv(si); + + pf->ops->set_rss_key(hw, rxfh->key); + } /* set RSS table */ if (rxfh->indir) - err = enetc_set_rss_table(priv->si, rxfh->indir, - priv->si->num_rss); + err = enetc_set_rss_table(si, rxfh->indir, si->num_rss); return err; } diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index cc3e52bd3096..f050cf039733 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -512,6 +512,22 @@ static void enetc_mac_enable(struct enetc_si *si, bool en) enetc_port_mac_wr(si, ENETC_PM0_CMD_CFG, val); } +static void enetc_set_rss_key(struct enetc_hw *hw, const u8 *key) +{ + int i; + + for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++) + enetc_port_wr(hw, ENETC_PRSSK(i), ((u32 *)key)[i]); +} + +static void enetc_get_rss_key(struct enetc_hw *hw, u8 *key) +{ + int i; + + for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++) + ((u32 *)key)[i] = enetc_port_rd(hw, ENETC_PRSSK(i)); +} + static void enetc_configure_port(struct enetc_pf *pf) { u8 hash_key[ENETC_RSSHASH_KEY_SIZE]; @@ -975,6 +991,8 @@ static const struct enetc_pf_ops enetc_pf_ops = { .create_pcs = enetc_pf_create_pcs, .destroy_pcs = enetc_pf_destroy_pcs, .enable_psfp = enetc_psfp_enable, + .set_rss_key = enetc_set_rss_key, + .get_rss_key = enetc_get_rss_key, }; static int enetc_pf_probe(struct pci_dev *pdev, diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h index 3b0cb0d8bf48..916818d2fdb5 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h @@ -39,6 +39,8 @@ struct enetc_pf_ops { struct phylink_pcs *(*create_pcs)(struct enetc_pf *pf, struct mii_bus *bus); void (*destroy_pcs)(struct phylink_pcs *pcs); int (*enable_psfp)(struct enetc_ndev_priv *priv); + void (*set_rss_key)(struct enetc_hw *hw, const u8 *key); + void (*get_rss_key)(struct enetc_hw *hw, u8 *key); }; struct enetc_pf { -- 2.34.1