Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c10d4c82 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

net: stmmac: Switch stmmac_ops to generic HW Interface Helpers



Switch stmmac_ops to generic Hardware Interface Helpers instead of using
hard-coded callbacks. This makes the code more readable and more
flexible.

No functional change.

Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a4e887fa
Loading
Loading
Loading
Loading
+0 −70
Original line number Diff line number Diff line
@@ -383,76 +383,6 @@ extern const struct stmmac_desc_ops ndesc_ops;

struct mac_device_info;

/* Helpers to program the MAC core */
struct stmmac_ops {
	/* MAC core initialization */
	void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
	/* Enable the MAC RX/TX */
	void (*set_mac)(void __iomem *ioaddr, bool enable);
	/* Enable and verify that the IPC module is supported */
	int (*rx_ipc)(struct mac_device_info *hw);
	/* Enable RX Queues */
	void (*rx_queue_enable)(struct mac_device_info *hw, u8 mode, u32 queue);
	/* RX Queues Priority */
	void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
	/* TX Queues Priority */
	void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
	/* RX Queues Routing */
	void (*rx_queue_routing)(struct mac_device_info *hw, u8 packet,
				 u32 queue);
	/* Program RX Algorithms */
	void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
	/* Program TX Algorithms */
	void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg);
	/* Set MTL TX queues weight */
	void (*set_mtl_tx_queue_weight)(struct mac_device_info *hw,
					u32 weight, u32 queue);
	/* RX MTL queue to RX dma mapping */
	void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan);
	/* Configure AV Algorithm */
	void (*config_cbs)(struct mac_device_info *hw, u32 send_slope,
			   u32 idle_slope, u32 high_credit, u32 low_credit,
			   u32 queue);
	/* Dump MAC registers */
	void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space);
	/* Handle extra events on specific interrupts hw dependent */
	int (*host_irq_status)(struct mac_device_info *hw,
			       struct stmmac_extra_stats *x);
	/* Handle MTL interrupts */
	int (*host_mtl_irq_status)(struct mac_device_info *hw, u32 chan);
	/* Multicast filter setting */
	void (*set_filter)(struct mac_device_info *hw, struct net_device *dev);
	/* Flow control setting */
	void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex,
			  unsigned int fc, unsigned int pause_time, u32 tx_cnt);
	/* Set power management mode (e.g. magic frame) */
	void (*pmt)(struct mac_device_info *hw, unsigned long mode);
	/* Set/Get Unicast MAC addresses */
	void (*set_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
			      unsigned int reg_n);
	void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
			      unsigned int reg_n);
	void (*set_eee_mode)(struct mac_device_info *hw,
			     bool en_tx_lpi_clockgating);
	void (*reset_eee_mode)(struct mac_device_info *hw);
	void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
	void (*set_eee_pls)(struct mac_device_info *hw, int link);
	void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x,
		      u32 rx_queues, u32 tx_queues);
	/* PCS calls */
	void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral,
			     bool loopback);
	void (*pcs_rane)(void __iomem *ioaddr, bool restart);
	void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv);
	/* Safety Features */
	int (*safety_feat_config)(void __iomem *ioaddr, unsigned int asp);
	bool (*safety_feat_irq_status)(struct net_device *ndev,
			void __iomem *ioaddr, unsigned int asp,
			struct stmmac_safety_stats *stats);
	const char *(*safety_feat_dump)(struct stmmac_safety_stats *stats,
			int index, unsigned long *count);
};

/* PTP and HW Timer helpers */
struct stmmac_hwtimestamp {
	void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
+11 −8
Original line number Diff line number Diff line
@@ -237,15 +237,16 @@ int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp)
	return 0;
}

bool dwmac5_safety_feat_irq_status(struct net_device *ndev,
int dwmac5_safety_feat_irq_status(struct net_device *ndev,
		void __iomem *ioaddr, unsigned int asp,
		struct stmmac_safety_stats *stats)
{
	bool ret = false, err, corr;
	bool err, corr;
	u32 mtl, dma;
	int ret = 0;

	if (!asp)
		return false;
		return -EINVAL;

	mtl = readl(ioaddr + MTL_SAFETY_INT_STATUS);
	dma = readl(ioaddr + DMA_SAFETY_INT_STATUS);
@@ -282,17 +283,19 @@ static const struct dwmac5_error {
	{ dwmac5_dma_errors },
};

const char *dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
			int index, unsigned long *count)
int dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
			int index, unsigned long *count, const char **desc)
{
	int module = index / 32, offset = index % 32;
	unsigned long *ptr = (unsigned long *)stats;

	if (module >= ARRAY_SIZE(dwmac5_all_errors))
		return NULL;
		return -EINVAL;
	if (!dwmac5_all_errors[module].desc[offset].valid)
		return NULL;
		return -EINVAL;
	if (count)
		*count = *(ptr + index);
	return dwmac5_all_errors[module].desc[offset].desc;
	if (desc)
		*desc = dwmac5_all_errors[module].desc[offset].desc;
	return 0;
}
+3 −3
Original line number Diff line number Diff line
@@ -43,10 +43,10 @@
#define DMA_ECC_INT_STATUS		0x00001088

int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp);
bool dwmac5_safety_feat_irq_status(struct net_device *ndev,
int dwmac5_safety_feat_irq_status(struct net_device *ndev,
		void __iomem *ioaddr, unsigned int asp,
		struct stmmac_safety_stats *stats);
const char *dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
			int index, unsigned long *count);
int dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
			int index, unsigned long *count, const char **desc);

#endif /* __DWMAC5_H__ */
+138 −0
Original line number Diff line number Diff line
@@ -228,4 +228,142 @@ struct stmmac_dma_ops {
#define stmmac_enable_tso(__priv, __args...) \
	stmmac_do_void_callback(__priv, dma, enable_tso, __args)

struct mac_device_info;
struct net_device;
struct rgmii_adv;
struct stmmac_safety_stats;

/* Helpers to program the MAC core */
struct stmmac_ops {
	/* MAC core initialization */
	void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
	/* Enable the MAC RX/TX */
	void (*set_mac)(void __iomem *ioaddr, bool enable);
	/* Enable and verify that the IPC module is supported */
	int (*rx_ipc)(struct mac_device_info *hw);
	/* Enable RX Queues */
	void (*rx_queue_enable)(struct mac_device_info *hw, u8 mode, u32 queue);
	/* RX Queues Priority */
	void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
	/* TX Queues Priority */
	void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
	/* RX Queues Routing */
	void (*rx_queue_routing)(struct mac_device_info *hw, u8 packet,
				 u32 queue);
	/* Program RX Algorithms */
	void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
	/* Program TX Algorithms */
	void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg);
	/* Set MTL TX queues weight */
	void (*set_mtl_tx_queue_weight)(struct mac_device_info *hw,
					u32 weight, u32 queue);
	/* RX MTL queue to RX dma mapping */
	void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan);
	/* Configure AV Algorithm */
	void (*config_cbs)(struct mac_device_info *hw, u32 send_slope,
			   u32 idle_slope, u32 high_credit, u32 low_credit,
			   u32 queue);
	/* Dump MAC registers */
	void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space);
	/* Handle extra events on specific interrupts hw dependent */
	int (*host_irq_status)(struct mac_device_info *hw,
			       struct stmmac_extra_stats *x);
	/* Handle MTL interrupts */
	int (*host_mtl_irq_status)(struct mac_device_info *hw, u32 chan);
	/* Multicast filter setting */
	void (*set_filter)(struct mac_device_info *hw, struct net_device *dev);
	/* Flow control setting */
	void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex,
			  unsigned int fc, unsigned int pause_time, u32 tx_cnt);
	/* Set power management mode (e.g. magic frame) */
	void (*pmt)(struct mac_device_info *hw, unsigned long mode);
	/* Set/Get Unicast MAC addresses */
	void (*set_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
			      unsigned int reg_n);
	void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
			      unsigned int reg_n);
	void (*set_eee_mode)(struct mac_device_info *hw,
			     bool en_tx_lpi_clockgating);
	void (*reset_eee_mode)(struct mac_device_info *hw);
	void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
	void (*set_eee_pls)(struct mac_device_info *hw, int link);
	void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x,
		      u32 rx_queues, u32 tx_queues);
	/* PCS calls */
	void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral,
			     bool loopback);
	void (*pcs_rane)(void __iomem *ioaddr, bool restart);
	void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv);
	/* Safety Features */
	int (*safety_feat_config)(void __iomem *ioaddr, unsigned int asp);
	int (*safety_feat_irq_status)(struct net_device *ndev,
			void __iomem *ioaddr, unsigned int asp,
			struct stmmac_safety_stats *stats);
	int (*safety_feat_dump)(struct stmmac_safety_stats *stats,
			int index, unsigned long *count, const char **desc);
};

#define stmmac_core_init(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, core_init, __args)
#define stmmac_mac_set(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_mac, __args)
#define stmmac_rx_ipc(__priv, __args...) \
	stmmac_do_callback(__priv, mac, rx_ipc, __args)
#define stmmac_rx_queue_enable(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, rx_queue_enable, __args)
#define stmmac_rx_queue_prio(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, rx_queue_prio, __args)
#define stmmac_tx_queue_prio(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, tx_queue_prio, __args)
#define stmmac_rx_queue_routing(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, rx_queue_routing, __args)
#define stmmac_prog_mtl_rx_algorithms(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, prog_mtl_rx_algorithms, __args)
#define stmmac_prog_mtl_tx_algorithms(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, prog_mtl_tx_algorithms, __args)
#define stmmac_set_mtl_tx_queue_weight(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_mtl_tx_queue_weight, __args)
#define stmmac_map_mtl_to_dma(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, map_mtl_to_dma, __args)
#define stmmac_config_cbs(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, config_cbs, __args)
#define stmmac_dump_mac_regs(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, dump_regs, __args)
#define stmmac_host_irq_status(__priv, __args...) \
	stmmac_do_callback(__priv, mac, host_irq_status, __args)
#define stmmac_host_mtl_irq_status(__priv, __args...) \
	stmmac_do_callback(__priv, mac, host_mtl_irq_status, __args)
#define stmmac_set_filter(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_filter, __args)
#define stmmac_flow_ctrl(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, flow_ctrl, __args)
#define stmmac_pmt(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, pmt, __args)
#define stmmac_set_umac_addr(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_umac_addr, __args)
#define stmmac_get_umac_addr(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, get_umac_addr, __args)
#define stmmac_set_eee_mode(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_eee_mode, __args)
#define stmmac_reset_eee_mode(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, reset_eee_mode, __args)
#define stmmac_set_eee_timer(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_eee_timer, __args)
#define stmmac_set_eee_pls(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, set_eee_pls, __args)
#define stmmac_mac_debug(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, debug, __args)
#define stmmac_pcs_ctrl_ane(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, pcs_ctrl_ane, __args)
#define stmmac_pcs_rane(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, pcs_rane, __args)
#define stmmac_pcs_get_adv_lp(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, pcs_get_adv_lp, __args)
#define stmmac_safety_feat_config(__priv, __args...) \
	stmmac_do_callback(__priv, mac, safety_feat_config, __args)
#define stmmac_safety_feat_irq_status(__priv, __args...) \
	stmmac_do_callback(__priv, mac, safety_feat_irq_status, __args)
#define stmmac_safety_feat_dump(__priv, __args...) \
	stmmac_do_callback(__priv, mac, safety_feat_dump, __args)

#endif /* __STMMAC_HWIF_H__ */
+25 −43
Original line number Diff line number Diff line
@@ -291,11 +291,9 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,
		cmd->base.speed = priv->xstats.pcs_speed;

		/* Get and convert ADV/LP_ADV from the HW AN registers */
		if (!priv->hw->mac->pcs_get_adv_lp)
		if (stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv))
			return -EOPNOTSUPP;	/* should never happen indeed */

		priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv);

		/* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */

		ethtool_convert_link_mode_to_legacy_u32(
@@ -393,11 +391,7 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
			ADVERTISED_10baseT_Full);

		spin_lock(&priv->lock);

		if (priv->hw->mac->pcs_ctrl_ane)
			priv->hw->mac->pcs_ctrl_ane(priv->ioaddr, 1,
						    priv->hw->ps, 0);

		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0);
		spin_unlock(&priv->lock);

		return 0;
@@ -442,7 +436,7 @@ static void stmmac_ethtool_gregs(struct net_device *dev,

	memset(reg_space, 0x0, REG_SPACE_SIZE);

	priv->hw->mac->dump_regs(priv->hw, reg_space);
	stmmac_dump_mac_regs(priv, priv->hw, reg_space);
	stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
	/* Copy DMA registers to where ethtool expects them */
	memcpy(&reg_space[ETHTOOL_DMA_OFFSET], &reg_space[DMA_BUS_MODE / 4],
@@ -454,15 +448,13 @@ stmmac_get_pauseparam(struct net_device *netdev,
		      struct ethtool_pauseparam *pause)
{
	struct stmmac_priv *priv = netdev_priv(netdev);
	struct rgmii_adv adv_lp;

	pause->rx_pause = 0;
	pause->tx_pause = 0;

	if (priv->hw->pcs && priv->hw->mac->pcs_get_adv_lp) {
		struct rgmii_adv adv_lp;

	if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {
		pause->autoneg = 1;
		priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv_lp);
		if (!adv_lp.pause)
			return;
	} else {
@@ -488,12 +480,10 @@ stmmac_set_pauseparam(struct net_device *netdev,
	u32 tx_cnt = priv->plat->tx_queues_to_use;
	struct phy_device *phy = netdev->phydev;
	int new_pause = FLOW_OFF;

	if (priv->hw->pcs && priv->hw->mac->pcs_get_adv_lp) {
	struct rgmii_adv adv_lp;

	if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {
		pause->autoneg = 1;
		priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv_lp);
		if (!adv_lp.pause)
			return -EOPNOTSUPP;
	} else {
@@ -515,7 +505,7 @@ stmmac_set_pauseparam(struct net_device *netdev,
			return phy_start_aneg(phy);
	}

	priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, priv->flow_ctrl,
	stmmac_flow_ctrl(priv, priv->hw, phy->duplex, priv->flow_ctrl,
			priv->pause, tx_cnt);
	return 0;
}
@@ -523,19 +513,16 @@ stmmac_set_pauseparam(struct net_device *netdev,
static void stmmac_get_ethtool_stats(struct net_device *dev,
				 struct ethtool_stats *dummy, u64 *data)
{
	const char *(*dump)(struct stmmac_safety_stats *stats, int index,
			unsigned long *count);
	struct stmmac_priv *priv = netdev_priv(dev);
	u32 rx_queues_count = priv->plat->rx_queues_to_use;
	u32 tx_queues_count = priv->plat->tx_queues_to_use;
	unsigned long count;
	int i, j = 0, ret;

	if (priv->dma_cap.asp && priv->hw->mac->safety_feat_dump) {
		dump = priv->hw->mac->safety_feat_dump;

	if (priv->dma_cap.asp) {
		for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
			if (dump(&priv->sstats, i, &count))
			if (!stmmac_safety_feat_dump(priv, &priv->sstats, i,
						&count, NULL))
				data[j++] = count;
		}
	}
@@ -563,9 +550,8 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
				priv->xstats.phy_eee_wakeup_error_n = val;
		}

		if ((priv->hw->mac->debug) &&
		    (priv->synopsys_id >= DWMAC_CORE_3_50))
			priv->hw->mac->debug(priv->ioaddr,
		if (priv->synopsys_id >= DWMAC_CORE_3_50)
			stmmac_mac_debug(priv, priv->ioaddr,
					(void *)&priv->xstats,
					rx_queues_count, tx_queues_count);
	}
@@ -579,8 +565,6 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
static int stmmac_get_sset_count(struct net_device *netdev, int sset)
{
	struct stmmac_priv *priv = netdev_priv(netdev);
	const char *(*dump)(struct stmmac_safety_stats *stats, int index,
			unsigned long *count);
	int i, len, safety_len = 0;

	switch (sset) {
@@ -589,11 +573,11 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)

		if (priv->dma_cap.rmon)
			len += STMMAC_MMC_STATS_LEN;
		if (priv->dma_cap.asp && priv->hw->mac->safety_feat_dump) {
			dump = priv->hw->mac->safety_feat_dump;

		if (priv->dma_cap.asp) {
			for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
				if (dump(&priv->sstats, i, NULL))
				if (!stmmac_safety_feat_dump(priv,
							&priv->sstats, i,
							NULL, NULL))
					safety_len++;
			}

@@ -611,17 +595,15 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
	int i;
	u8 *p = data;
	struct stmmac_priv *priv = netdev_priv(dev);
	const char *(*dump)(struct stmmac_safety_stats *stats, int index,
			unsigned long *count);

	switch (stringset) {
	case ETH_SS_STATS:
		if (priv->dma_cap.asp && priv->hw->mac->safety_feat_dump) {
			dump = priv->hw->mac->safety_feat_dump;
		if (priv->dma_cap.asp) {
			for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
				const char *desc = dump(&priv->sstats, i, NULL);

				if (desc) {
				const char *desc;
				if (!stmmac_safety_feat_dump(priv,
							&priv->sstats, i,
							NULL, &desc)) {
					memcpy(p, desc, ETH_GSTRING_LEN);
					p += ETH_GSTRING_LEN;
				}
Loading