Commit ab526eaa authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'dpaa-cleanups'

Sean Anderson says:

====================
net: dpaa: Cleanups in preparation for phylink conversion (part 2)

This series contains several cleanup patches for dpaa/fman. While they
are intended to prepare for a phylink conversion, they stand on their
own. This series was originally submitted as part of [1].

[1] https://lore.kernel.org/netdev/20220715215954.1449214-1-sean.anderson@seco.com



Changes in v5:
- Reduce line length of tgec_config
- Reduce line length of qman_update_cgr_safe
- Rebase onto net-next/master

Changes in v4:
- weer -> were
- tricy -> tricky
- Use mac_dev for calling change_addr
- qman_cgr_create -> qman_create_cgr

Changes in v2:
- Fix prototype for dtsec_initialization
- Fix warning if sizeof(void *) != sizeof(resource_size_t)
- Specify type of mac_dev for exception_cb
- Add helper for sanity checking cgr ops
- Add CGR update function
- Adjust queue depth on rate change
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 36f9b474 ef2a8d54
Loading
Loading
Loading
Loading
+40 −12
Original line number Diff line number Diff line
@@ -197,12 +197,15 @@ static int dpaa_rx_extra_headroom;
#define dpaa_get_max_mtu()	\
	(dpaa_max_frm - (VLAN_ETH_HLEN + ETH_FCS_LEN))

static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed);

static int dpaa_netdev_init(struct net_device *net_dev,
			    const struct net_device_ops *dpaa_ops,
			    u16 tx_timeout)
{
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct device *dev = net_dev->dev.parent;
	struct mac_device *mac_dev = priv->mac_dev;
	struct dpaa_percpu_priv *percpu_priv;
	const u8 *mac_addr;
	int i, err;
@@ -216,10 +219,10 @@ static int dpaa_netdev_init(struct net_device *net_dev,
	}

	net_dev->netdev_ops = dpaa_ops;
	mac_addr = priv->mac_dev->addr;
	mac_addr = mac_dev->addr;

	net_dev->mem_start = priv->mac_dev->res->start;
	net_dev->mem_end = priv->mac_dev->res->end;
	net_dev->mem_start = (unsigned long)mac_dev->vaddr;
	net_dev->mem_end = (unsigned long)mac_dev->vaddr_end;

	net_dev->min_mtu = ETH_MIN_MTU;
	net_dev->max_mtu = dpaa_get_max_mtu();
@@ -246,7 +249,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
		eth_hw_addr_set(net_dev, mac_addr);
	} else {
		eth_hw_addr_random(net_dev);
		err = priv->mac_dev->change_addr(priv->mac_dev->fman_mac,
		err = mac_dev->change_addr(mac_dev->fman_mac,
			(const enet_addr_t *)net_dev->dev_addr);
		if (err) {
			dev_err(dev, "Failed to set random MAC address\n");
@@ -261,6 +264,9 @@ static int dpaa_netdev_init(struct net_device *net_dev,
	net_dev->needed_headroom = priv->tx_headroom;
	net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);

	mac_dev->net_dev = net_dev;
	mac_dev->update_speed = dpaa_eth_cgr_set_speed;

	/* start without the RUNNING flag, phylib controls it later */
	netif_carrier_off(net_dev);

@@ -290,10 +296,7 @@ static int dpaa_stop(struct net_device *net_dev)

	if (mac_dev->phy_dev)
		phy_stop(mac_dev->phy_dev);
	err = mac_dev->disable(mac_dev->fman_mac);
	if (err < 0)
		netif_err(priv, ifdown, net_dev, "mac_dev->disable() = %d\n",
			  err);
	mac_dev->disable(mac_dev->fman_mac);

	for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
		error = fman_port_disable(mac_dev->port[i]);
@@ -828,10 +831,10 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
	initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES);
	initcgr.cgr.cscn_en = QM_CGR_EN;

	/* Set different thresholds based on the MAC speed.
	 * This may turn suboptimal if the MAC is reconfigured at a speed
	 * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
	 * In such cases, we ought to reconfigure the threshold, too.
	/* Set different thresholds based on the configured MAC speed.
	 * This may turn suboptimal if the MAC is reconfigured at another
	 * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
	 * callback.
	 */
	if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
		cs_th = DPAA_CS_THRESHOLD_10G;
@@ -860,6 +863,31 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
	return err;
}

static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
{
	struct net_device *net_dev = mac_dev->net_dev;
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct qm_mcc_initcgr opts = { };
	u32 cs_th;
	int err;

	opts.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES);
	switch (speed) {
	case SPEED_10000:
		cs_th = DPAA_CS_THRESHOLD_10G;
		break;
	case SPEED_1000:
	default:
		cs_th = DPAA_CS_THRESHOLD_1G;
		break;
	}
	qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, cs_th, 1);

	err = qman_update_cgr_safe(&priv->cgr_data.cgr, &opts);
	if (err)
		netdev_err(net_dev, "could not update speed: %d\n", err);
}

static inline void dpaa_setup_ingress(const struct dpaa_priv *priv,
				      struct dpaa_fq *fq,
				      const struct qman_fq *template)
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ static ssize_t dpaa_eth_show_addr(struct device *dev,

	if (mac_dev)
		return sprintf(buf, "%llx",
				(unsigned long long)mac_dev->res->start);
				(unsigned long long)mac_dev->vaddr);
	else
		return sprintf(buf, "none");
}
+114 −70
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#include "fman_dtsec.h"
#include "fman.h"
#include "mac.h"

#include <linux/slab.h>
#include <linux/bitrev.h>
@@ -300,7 +301,7 @@ struct fman_mac {
	/* Ethernet physical interface */
	phy_interface_t phy_if;
	u16 max_speed;
	void *dev_id; /* device cookie used by the exception cbs */
	struct mac_device *dev_id; /* device cookie used by the exception cbs */
	fman_mac_exception_cb *exception_cb;
	fman_mac_exception_cb *event_cb;
	/* Number of individual addresses in registers for this station */
@@ -813,26 +814,6 @@ static void free_init_resources(struct fman_mac *dtsec)
	dtsec->unicast_addr_hash = NULL;
}

int dtsec_cfg_max_frame_len(struct fman_mac *dtsec, u16 new_val)
{
	if (is_init_done(dtsec->dtsec_drv_param))
		return -EINVAL;

	dtsec->dtsec_drv_param->maximum_frame = new_val;

	return 0;
}

int dtsec_cfg_pad_and_crc(struct fman_mac *dtsec, bool new_val)
{
	if (is_init_done(dtsec->dtsec_drv_param))
		return -EINVAL;

	dtsec->dtsec_drv_param->tx_pad_crc = new_val;

	return 0;
}

static void graceful_start(struct fman_mac *dtsec)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
@@ -871,7 +852,7 @@ static void graceful_stop(struct fman_mac *dtsec)
	}
}

int dtsec_enable(struct fman_mac *dtsec)
static int dtsec_enable(struct fman_mac *dtsec)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 tmp;
@@ -890,13 +871,12 @@ int dtsec_enable(struct fman_mac *dtsec)
	return 0;
}

int dtsec_disable(struct fman_mac *dtsec)
static void dtsec_disable(struct fman_mac *dtsec)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 tmp;

	if (!is_init_done(dtsec->dtsec_drv_param))
		return -EINVAL;
	WARN_ON_ONCE(!is_init_done(dtsec->dtsec_drv_param));

	/* Graceful stop - Assert the graceful Rx/Tx stop bit */
	graceful_stop(dtsec);
@@ -904,13 +884,12 @@ int dtsec_disable(struct fman_mac *dtsec)
	tmp = ioread32be(&regs->maccfg1);
	tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
	iowrite32be(tmp, &regs->maccfg1);

	return 0;
}

int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
static int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
				     u8 __maybe_unused priority,
			      u16 pause_time, u16 __maybe_unused thresh_time)
				     u16 pause_time,
				     u16 __maybe_unused thresh_time)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 ptv = 0;
@@ -945,7 +924,7 @@ int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
	return 0;
}

int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
static int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 tmp;
@@ -967,7 +946,8 @@ int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
	return 0;
}

int dtsec_modify_mac_address(struct fman_mac *dtsec, const enet_addr_t *enet_addr)
static int dtsec_modify_mac_address(struct fman_mac *dtsec,
				    const enet_addr_t *enet_addr)
{
	if (!is_init_done(dtsec->dtsec_drv_param))
		return -EINVAL;
@@ -985,7 +965,8 @@ int dtsec_modify_mac_address(struct fman_mac *dtsec, const enet_addr_t *enet_add
	return 0;
}

int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
static int dtsec_add_hash_mac_address(struct fman_mac *dtsec,
				      enet_addr_t *eth_addr)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	struct eth_hash_entry *hash_entry;
@@ -1051,7 +1032,7 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
	return 0;
}

int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
static int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
{
	u32 tmp;
	struct dtsec_regs __iomem *regs = dtsec->regs;
@@ -1070,7 +1051,7 @@ int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
	return 0;
}

int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
static int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 rctrl, tctrl;
@@ -1095,7 +1076,8 @@ int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
	return 0;
}

int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
static int dtsec_del_hash_mac_address(struct fman_mac *dtsec,
				      enet_addr_t *eth_addr)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	struct list_head *pos;
@@ -1166,7 +1148,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
	return 0;
}

int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
static int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 tmp;
@@ -1195,7 +1177,7 @@ int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
	return 0;
}

int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
static int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	u32 tmp;
@@ -1229,7 +1211,7 @@ int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
	return 0;
}

int dtsec_restart_autoneg(struct fman_mac *dtsec)
static int dtsec_restart_autoneg(struct fman_mac *dtsec)
{
	u16 tmp_reg16;

@@ -1247,19 +1229,30 @@ int dtsec_restart_autoneg(struct fman_mac *dtsec)
	return 0;
}

int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version)
static void adjust_link_dtsec(struct mac_device *mac_dev)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	struct phy_device *phy_dev = mac_dev->phy_dev;
	struct fman_mac *fman_mac;
	bool rx_pause, tx_pause;
	int err;

	if (!is_init_done(dtsec->dtsec_drv_param))
		return -EINVAL;
	fman_mac = mac_dev->fman_mac;
	if (!phy_dev->link) {
		dtsec_restart_autoneg(fman_mac);

	*mac_version = ioread32be(&regs->tsec_id);
		return;
	}

	return 0;
	dtsec_adjust_link(fman_mac, phy_dev->speed);
	mac_dev->update_speed(mac_dev, phy_dev->speed);
	fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
	err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
	if (err < 0)
		dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
			err);
}

int dtsec_set_exception(struct fman_mac *dtsec,
static int dtsec_set_exception(struct fman_mac *dtsec,
			       enum fman_mac_exceptions exception, bool enable)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
@@ -1313,7 +1306,7 @@ int dtsec_set_exception(struct fman_mac *dtsec,
	return 0;
}

int dtsec_init(struct fman_mac *dtsec)
static int dtsec_init(struct fman_mac *dtsec)
{
	struct dtsec_regs __iomem *regs = dtsec->regs;
	struct dtsec_cfg *dtsec_drv_param;
@@ -1407,7 +1400,7 @@ int dtsec_init(struct fman_mac *dtsec)
	return 0;
}

int dtsec_free(struct fman_mac *dtsec)
static int dtsec_free(struct fman_mac *dtsec)
{
	free_init_resources(dtsec);

@@ -1418,13 +1411,11 @@ int dtsec_free(struct fman_mac *dtsec)
	return 0;
}

struct fman_mac *dtsec_config(struct fman_mac_params *params)
static struct fman_mac *dtsec_config(struct mac_device *mac_dev,
				     struct fman_mac_params *params)
{
	struct fman_mac *dtsec;
	struct dtsec_cfg *dtsec_drv_param;
	void __iomem *base_addr;

	base_addr = params->base_addr;

	/* allocate memory for the UCC GETH data structure. */
	dtsec = kzalloc(sizeof(*dtsec), GFP_KERNEL);
@@ -1441,10 +1432,10 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params)

	set_dflts(dtsec_drv_param);

	dtsec->regs = base_addr;
	dtsec->addr = ENET_ADDR_TO_UINT64(params->addr);
	dtsec->regs = mac_dev->vaddr;
	dtsec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
	dtsec->max_speed = params->max_speed;
	dtsec->phy_if = params->phy_if;
	dtsec->phy_if = mac_dev->phy_if;
	dtsec->mac_id = params->mac_id;
	dtsec->exceptions = (DTSEC_IMASK_BREN	|
			     DTSEC_IMASK_RXCEN	|
@@ -1461,34 +1452,87 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params)
			     DTSEC_IMASK_RDPEEN);
	dtsec->exception_cb = params->exception_cb;
	dtsec->event_cb = params->event_cb;
	dtsec->dev_id = params->dev_id;
	dtsec->dev_id = mac_dev;
	dtsec->ptp_tsu_enabled = dtsec->dtsec_drv_param->ptp_tsu_en;
	dtsec->en_tsu_err_exception = dtsec->dtsec_drv_param->ptp_exception_en;

	dtsec->fm = params->fm;
	dtsec->basex_if = params->basex_if;

	if (!params->internal_phy_node) {
	/* Save FMan revision */
	fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);

	return dtsec;

err_dtsec:
	kfree(dtsec);
	return NULL;
}

int dtsec_initialization(struct mac_device *mac_dev,
			 struct device_node *mac_node,
			 struct fman_mac_params *params)
{
	int			err;
	struct fman_mac		*dtsec;
	struct device_node	*phy_node;

	mac_dev->set_promisc		= dtsec_set_promiscuous;
	mac_dev->change_addr		= dtsec_modify_mac_address;
	mac_dev->add_hash_mac_addr	= dtsec_add_hash_mac_address;
	mac_dev->remove_hash_mac_addr	= dtsec_del_hash_mac_address;
	mac_dev->set_tx_pause		= dtsec_set_tx_pause_frames;
	mac_dev->set_rx_pause		= dtsec_accept_rx_pause_frames;
	mac_dev->set_exception		= dtsec_set_exception;
	mac_dev->set_allmulti		= dtsec_set_allmulti;
	mac_dev->set_tstamp		= dtsec_set_tstamp;
	mac_dev->set_multi		= fman_set_multi;
	mac_dev->adjust_link            = adjust_link_dtsec;
	mac_dev->enable			= dtsec_enable;
	mac_dev->disable		= dtsec_disable;

	mac_dev->fman_mac = dtsec_config(mac_dev, params);
	if (!mac_dev->fman_mac) {
		err = -EINVAL;
		goto _return;
	}

	dtsec = mac_dev->fman_mac;
	dtsec->dtsec_drv_param->maximum_frame = fman_get_max_frm();
	dtsec->dtsec_drv_param->tx_pad_crc = true;

	phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
	if (!phy_node) {
		pr_err("TBI PHY node is not available\n");
		goto err_dtsec_drv_param;
		err = -EINVAL;
		goto _return_fm_mac_free;
	}

	dtsec->tbiphy = of_phy_find_device(params->internal_phy_node);
	dtsec->tbiphy = of_phy_find_device(phy_node);
	if (!dtsec->tbiphy) {
		pr_err("of_phy_find_device (TBI PHY) failed\n");
		goto err_dtsec_drv_param;
		err = -EINVAL;
		goto _return_fm_mac_free;
	}

	put_device(&dtsec->tbiphy->mdio.dev);

	/* Save FMan revision */
	fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
	err = dtsec_init(dtsec);
	if (err < 0)
		goto _return_fm_mac_free;

	return dtsec;
	/* For 1G MAC, disable by default the MIB counters overflow interrupt */
	err = dtsec_set_exception(dtsec, FM_MAC_EX_1G_RX_MIB_CNT_OVFL, false);
	if (err < 0)
		goto _return_fm_mac_free;

err_dtsec_drv_param:
	kfree(dtsec_drv_param);
err_dtsec:
	kfree(dtsec);
	return NULL;
	dev_info(mac_dev->dev, "FMan dTSEC version: 0x%08x\n",
		 ioread32be(&dtsec->regs->tsec_id));

	goto _return;

_return_fm_mac_free:
	dtsec_free(dtsec);

_return:
	return err;
}
+5 −22
Original line number Diff line number Diff line
@@ -8,27 +8,10 @@

#include "fman_mac.h"

struct fman_mac *dtsec_config(struct fman_mac_params *params);
int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val);
int dtsec_modify_mac_address(struct fman_mac *dtsec, const enet_addr_t *enet_addr);
int dtsec_adjust_link(struct fman_mac *dtsec,
		      u16 speed);
int dtsec_restart_autoneg(struct fman_mac *dtsec);
int dtsec_cfg_max_frame_len(struct fman_mac *dtsec, u16 new_val);
int dtsec_cfg_pad_and_crc(struct fman_mac *dtsec, bool new_val);
int dtsec_enable(struct fman_mac *dtsec);
int dtsec_disable(struct fman_mac *dtsec);
int dtsec_init(struct fman_mac *dtsec);
int dtsec_free(struct fman_mac *dtsec);
int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en);
int dtsec_set_tx_pause_frames(struct fman_mac *dtsec, u8 priority,
			      u16 pause_time, u16 thresh_time);
int dtsec_set_exception(struct fman_mac *dtsec,
			enum fman_mac_exceptions exception, bool enable);
int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable);
struct mac_device;

int dtsec_initialization(struct mac_device *mac_dev,
			 struct device_node *mac_node,
			 struct fman_mac_params *params);

#endif /* __DTSEC_H */
+3 −11
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <linux/if_ether.h>

struct fman_mac;
struct mac_device;

/* Ethernet Address */
typedef u8 enet_addr_t[ETH_ALEN];
@@ -158,30 +159,23 @@ struct eth_hash_entry {
	struct list_head node;
};

typedef void (fman_mac_exception_cb)(void *dev_id,
typedef void (fman_mac_exception_cb)(struct mac_device *dev_id,
				     enum fman_mac_exceptions exceptions);

/* FMan MAC config input */
struct fman_mac_params {
	/* Base of memory mapped FM MAC registers */
	void __iomem *base_addr;
	/* MAC address of device; First octet is sent first */
	enet_addr_t addr;
	/* MAC ID; numbering of dTSEC and 1G-mEMAC:
	 * 0 - FM_MAX_NUM_OF_1G_MACS;
	 * numbering of 10G-MAC (TGEC) and 10G-mEMAC:
	 * 0 - FM_MAX_NUM_OF_10G_MACS
	 */
	u8 mac_id;
	/* PHY interface */
	phy_interface_t	 phy_if;
	/* Note that the speed should indicate the maximum rate that
	 * this MAC should support rather than the actual speed;
	 */
	u16 max_speed;
	/* A handle to the FM object this port related to */
	void *fm;
	void *dev_id; /* device cookie used by the exception cbs */
	fman_mac_exception_cb *event_cb;    /* MDIO Events Callback Routine */
	fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
	/* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
@@ -190,8 +184,6 @@ struct fman_mac_params {
	 * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps
	*/
	bool basex_if;
	/* Pointer to TBI/PCS PHY node, used for TBI/PCS PHY access */
	struct device_node *internal_phy_node;
};

struct eth_hash_t {
Loading