Since the VLAN hash filter of ENETC v1 and v4 is the basically same, the only difference is the offset of the VLAN hash filter registers. So, the .set_si_vlan_hash_filter() hook is added to struct enetc_pf_ops to set the registers of the corresponding platform. In addition, the common VLAN hash filter functions enetc_vlan_rx_add_vid() and enetc_vlan_rx_del_vid() are moved to enetc_pf_common.c.
Signed-off-by: Wei Fang <wei.f...@nxp.com> --- .../net/ethernet/freescale/enetc/enetc_pf.c | 34 ++----------------- .../net/ethernet/freescale/enetc/enetc_pf.h | 1 + .../freescale/enetc/enetc_pf_common.c | 34 +++++++++++++++++++ .../freescale/enetc/enetc_pf_common.h | 2 ++ 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index c0aaf6349b0b..d9c1ebd180db 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -215,43 +215,12 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev) enetc_port_wr(hw, ENETC_PSIPMR, psipmr); } -static void enetc_set_vlan_ht_filter(struct enetc_hw *hw, int si_idx, - unsigned long hash) +static void enetc_set_vlan_ht_filter(struct enetc_hw *hw, int si_idx, u64 hash) { enetc_port_wr(hw, ENETC_PSIVHFR0(si_idx), lower_32_bits(hash)); enetc_port_wr(hw, ENETC_PSIVHFR1(si_idx), upper_32_bits(hash)); } -static int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid) -{ - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct enetc_si *si = priv->si; - struct enetc_hw *hw = &si->hw; - int idx; - - __set_bit(vid, si->active_vlans); - - idx = enetc_vid_hash_idx(vid); - if (!__test_and_set_bit(idx, si->vlan_ht_filter)) - enetc_set_vlan_ht_filter(hw, 0, *si->vlan_ht_filter); - - return 0; -} - -static int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid) -{ - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct enetc_si *si = priv->si; - struct enetc_hw *hw = &si->hw; - - if (__test_and_clear_bit(vid, si->active_vlans)) { - enetc_refresh_vlan_ht_filter(si); - enetc_set_vlan_ht_filter(hw, 0, *si->vlan_ht_filter); - } - - return 0; -} - static void enetc_set_loopback(struct net_device *ndev, bool en) { struct enetc_ndev_priv *priv = netdev_priv(ndev); @@ -971,6 +940,7 @@ static const struct enetc_pf_ops enetc_pf_ops = { .enable_psfp = enetc_psfp_enable, .set_rss_key = enetc_set_rss_key, .get_rss_key = enetc_get_rss_key, + .set_si_vlan_hash_filter = enetc_set_vlan_ht_filter, }; 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 d56b381b9da9..7a0fa5fba8bf 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h @@ -39,6 +39,7 @@ struct enetc_pf_ops { 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); + void (*set_si_vlan_hash_filter)(struct enetc_hw *hw, int si, u64 hash); }; struct enetc_pf { diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c index a737a7f8c79e..9f812c1af7a3 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c @@ -343,5 +343,39 @@ void enetc_phylink_destroy(struct enetc_ndev_priv *priv) } EXPORT_SYMBOL_GPL(enetc_phylink_destroy); +int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid) +{ + struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_pf *pf = enetc_si_priv(priv->si); + struct enetc_si *si = priv->si; + struct enetc_hw *hw = &si->hw; + int idx; + + __set_bit(vid, si->active_vlans); + + idx = enetc_vid_hash_idx(vid); + if (!__test_and_set_bit(idx, si->vlan_ht_filter)) + pf->ops->set_si_vlan_hash_filter(hw, 0, *si->vlan_ht_filter); + + return 0; +} +EXPORT_SYMBOL_GPL(enetc_vlan_rx_add_vid); + +int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid) +{ + struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_pf *pf = enetc_si_priv(priv->si); + struct enetc_si *si = priv->si; + struct enetc_hw *hw = &si->hw; + + if (__test_and_clear_bit(vid, si->active_vlans)) { + enetc_refresh_vlan_ht_filter(si); + pf->ops->set_si_vlan_hash_filter(hw, 0, *si->vlan_ht_filter); + } + + return 0; +} +EXPORT_SYMBOL_GPL(enetc_vlan_rx_del_vid); + MODULE_DESCRIPTION("NXP ENETC PF common functionality driver"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h index 48f55ee743ad..253310859ca1 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h @@ -12,6 +12,8 @@ void enetc_mdiobus_destroy(struct enetc_pf *pf); int enetc_phylink_create(struct enetc_ndev_priv *priv, struct device_node *node, const struct phylink_mac_ops *ops); void enetc_phylink_destroy(struct enetc_ndev_priv *priv); +int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid); +int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid); static inline u16 enetc_get_ip_revision(struct enetc_hw *hw) { -- 2.34.1