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

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

Merge branch 'thunderx-new-features'



Sunil Goutham says:

====================
net: thunderx: Support for 80xx, RED, PFC e.t.c

This patch series adds support for SLM modules present on 80xx
silicon, enables ramdom early discard, backpressure generation,
PFC and some ethtool changes to display supported link modes e.t.c.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a7dac9f9 430da208
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -149,6 +149,12 @@ struct nicvf_rss_info {
	u64 key[RSS_HASH_KEY_SIZE];
} ____cacheline_aligned_in_smp;

struct nicvf_pfc {
	u8    autoneg;
	u8    fc_rx;
	u8    fc_tx;
};

enum rx_stats_reg_offset {
	RX_OCTS = 0x0,
	RX_UCAST = 0x1,
@@ -292,11 +298,13 @@ struct nicvf {
	u8			node;
	u8			cpi_alg;
	bool			link_up;
	u8			mac_type;
	u8			duplex;
	u32			speed;
	bool			tns_mode;
	bool			loopback_supported;
	struct nicvf_rss_info	rss_info;
	struct nicvf_pfc	pfc;
	struct tasklet_struct	qs_err_task;
	struct work_struct	reset_task;

@@ -357,6 +365,7 @@ struct nicvf {
#define	NIC_MBOX_MSG_SNICVF_PTR		0x15	/* Send sqet nicvf ptr to PVF */
#define	NIC_MBOX_MSG_LOOPBACK		0x16	/* Set interface in loopback */
#define	NIC_MBOX_MSG_RESET_STAT_COUNTER 0x17	/* Reset statistics counters */
#define	NIC_MBOX_MSG_PFC		0x18	/* Pause frame control */
#define	NIC_MBOX_MSG_CFG_DONE		0xF0	/* VF configuration done */
#define	NIC_MBOX_MSG_SHUTDOWN		0xF1	/* VF is being shutdown */

@@ -446,6 +455,7 @@ struct bgx_stats_msg {
/* Physical interface link status */
struct bgx_link_status {
	u8    msg;
	u8    mac_type;
	u8    link_up;
	u8    duplex;
	u32   speed;
@@ -498,6 +508,14 @@ struct reset_stat_cfg {
	u16   sq_stat_mask;
};

struct pfc {
	u8    msg;
	u8    get; /* Get or set PFC settings */
	u8    autoneg;
	u8    fc_rx;
	u8    fc_tx;
};

/* 128 bit shared memory between PF and each VF */
union nic_mbx {
	struct { u8 msg; }	msg;
@@ -516,6 +534,7 @@ union nic_mbx {
	struct nicvf_ptr	nicvf;
	struct set_loopback	lbk;
	struct reset_stat_cfg	reset_stat;
	struct pfc		pfc;
};

#define NIC_NODE_ID_MASK	0x03
+37 −0
Original line number Diff line number Diff line
@@ -809,6 +809,15 @@ static int nic_config_loopback(struct nicpf *nic, struct set_loopback *lbk)

	bgx_lmac_internal_loopback(nic->node, bgx_idx, lmac_idx, lbk->enable);

	/* Enable moving average calculation.
	 * Keep the LVL/AVG delay to HW enforced minimum so that, not too many
	 * packets sneek in between average calculations.
	 */
	nic_reg_write(nic, NIC_PF_CQ_AVG_CFG,
		      (BIT_ULL(20) | 0x2ull << 14 | 0x1));
	nic_reg_write(nic, NIC_PF_RRM_AVG_CFG,
		      (BIT_ULL(20) | 0x3ull << 14 | 0x1));

	return 0;
}

@@ -889,6 +898,30 @@ static void nic_enable_vf(struct nicpf *nic, int vf, bool enable)
	bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, enable);
}

static void nic_pause_frame(struct nicpf *nic, int vf, struct pfc *cfg)
{
	int bgx, lmac;
	struct pfc pfc;
	union nic_mbx mbx = {};

	if (vf >= nic->num_vf_en)
		return;
	bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);

	if (cfg->get) {
		bgx_lmac_get_pfc(nic->node, bgx, lmac, &pfc);
		mbx.pfc.msg = NIC_MBOX_MSG_PFC;
		mbx.pfc.autoneg = pfc.autoneg;
		mbx.pfc.fc_rx = pfc.fc_rx;
		mbx.pfc.fc_tx = pfc.fc_tx;
		nic_send_msg_to_vf(nic, vf, &mbx);
	} else {
		bgx_lmac_set_pfc(nic->node, bgx, lmac, cfg);
		nic_mbx_send_ack(nic, vf);
	}
}

/* Interrupt handler to handle mailbox messages from VFs */
static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
{
@@ -1028,6 +1061,9 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
	case NIC_MBOX_MSG_RESET_STAT_COUNTER:
		ret = nic_reset_stat_counters(nic, vf, &mbx.reset_stat);
		break;
	case NIC_MBOX_MSG_PFC:
		nic_pause_frame(nic, vf, &mbx.pfc);
		goto unlock;
	default:
		dev_err(&nic->pdev->dev,
			"Invalid msg from VF%d, msg 0x%x\n", vf, mbx.msg.msg);
@@ -1258,6 +1294,7 @@ static void nic_poll_for_link(struct work_struct *work)
			mbx.link_status.link_up = link.link_up;
			mbx.link_status.duplex = link.duplex;
			mbx.link_status.speed = link.speed;
			mbx.link_status.mac_type = link.mac_type;
			nic_send_msg_to_vf(nic, vf, &mbx);
		}
	}
+84 −3
Original line number Diff line number Diff line
@@ -130,12 +130,42 @@ static int nicvf_get_settings(struct net_device *netdev,
		return 0;
	}

	if (nic->speed <= 1000) {
		cmd->port = PORT_MII;
	switch (nic->speed) {
	case SPEED_1000:
		cmd->port = PORT_MII | PORT_TP;
		cmd->autoneg = AUTONEG_ENABLE;
		cmd->supported |= SUPPORTED_MII | SUPPORTED_TP;
		cmd->supported |= SUPPORTED_1000baseT_Full |
				  SUPPORTED_1000baseT_Half |
				  SUPPORTED_100baseT_Full  |
				  SUPPORTED_100baseT_Half  |
				  SUPPORTED_10baseT_Full   |
				  SUPPORTED_10baseT_Half;
		cmd->supported |= SUPPORTED_Autoneg;
		cmd->advertising |= ADVERTISED_1000baseT_Full |
				    ADVERTISED_1000baseT_Half |
				    ADVERTISED_100baseT_Full  |
				    ADVERTISED_100baseT_Half  |
				    ADVERTISED_10baseT_Full   |
				    ADVERTISED_10baseT_Half;
		break;
	case SPEED_10000:
		if (nic->mac_type == BGX_MODE_RXAUI) {
			cmd->port = PORT_TP;
			cmd->supported |= SUPPORTED_TP;
		} else {
			cmd->port = PORT_FIBRE;
			cmd->supported |= SUPPORTED_FIBRE;
		}
		cmd->autoneg = AUTONEG_DISABLE;
		cmd->supported |= SUPPORTED_10000baseT_Full;
		break;
	case SPEED_40000:
		cmd->port = PORT_FIBRE;
		cmd->autoneg = AUTONEG_DISABLE;
		cmd->supported |= SUPPORTED_FIBRE;
		cmd->supported |= SUPPORTED_40000baseCR4_Full;
		break;
	}
	cmd->duplex = nic->duplex;
	ethtool_cmd_speed_set(cmd, nic->speed);
@@ -690,6 +720,55 @@ static int nicvf_set_channels(struct net_device *dev,
	return err;
}

static void nicvf_get_pauseparam(struct net_device *dev,
				 struct ethtool_pauseparam *pause)
{
	struct nicvf *nic = netdev_priv(dev);
	union nic_mbx mbx = {};

	/* Supported only for 10G/40G interfaces */
	if ((nic->mac_type == BGX_MODE_SGMII) ||
	    (nic->mac_type == BGX_MODE_QSGMII) ||
	    (nic->mac_type == BGX_MODE_RGMII))
		return;

	mbx.pfc.msg = NIC_MBOX_MSG_PFC;
	mbx.pfc.get = 1;
	if (!nicvf_send_msg_to_pf(nic, &mbx)) {
		pause->autoneg = nic->pfc.autoneg;
		pause->rx_pause = nic->pfc.fc_rx;
		pause->tx_pause = nic->pfc.fc_tx;
	}
}

static int nicvf_set_pauseparam(struct net_device *dev,
				struct ethtool_pauseparam *pause)
{
	struct nicvf *nic = netdev_priv(dev);
	union nic_mbx mbx = {};

	/* Supported only for 10G/40G interfaces */
	if ((nic->mac_type == BGX_MODE_SGMII) ||
	    (nic->mac_type == BGX_MODE_QSGMII) ||
	    (nic->mac_type == BGX_MODE_RGMII))
		return -EOPNOTSUPP;

	if (pause->autoneg)
		return -EOPNOTSUPP;

	mbx.pfc.msg = NIC_MBOX_MSG_PFC;
	mbx.pfc.get = 0;
	mbx.pfc.fc_rx = pause->rx_pause;
	mbx.pfc.fc_tx = pause->tx_pause;
	if (nicvf_send_msg_to_pf(nic, &mbx))
		return -EAGAIN;

	nic->pfc.fc_rx = pause->rx_pause;
	nic->pfc.fc_tx = pause->tx_pause;

	return 0;
}

static const struct ethtool_ops nicvf_ethtool_ops = {
	.get_settings		= nicvf_get_settings,
	.get_link		= nicvf_get_link,
@@ -711,6 +790,8 @@ static const struct ethtool_ops nicvf_ethtool_ops = {
	.set_rxfh		= nicvf_set_rxfh,
	.get_channels		= nicvf_get_channels,
	.set_channels		= nicvf_set_channels,
	.get_pauseparam         = nicvf_get_pauseparam,
	.set_pauseparam         = nicvf_set_pauseparam,
	.get_ts_info		= ethtool_op_get_ts_info,
};

+7 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ static void nicvf_handle_mbx_intr(struct nicvf *nic)
		nic->link_up = mbx.link_status.link_up;
		nic->duplex = mbx.link_status.duplex;
		nic->speed = mbx.link_status.speed;
		nic->mac_type = mbx.link_status.mac_type;
		if (nic->link_up) {
			netdev_info(nic->netdev, "%s: Link is Up %d Mbps %s\n",
				    nic->netdev->name, nic->speed,
@@ -255,6 +256,12 @@ static void nicvf_handle_mbx_intr(struct nicvf *nic)
		nic->pnicvf = (struct nicvf *)mbx.nicvf.nicvf;
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_PFC:
		nic->pfc.autoneg = mbx.pfc.autoneg;
		nic->pfc.fc_rx = mbx.pfc.fc_rx;
		nic->pfc.fc_tx = mbx.pfc.fc_tx;
		nic->pf_acked = true;
		break;
	default:
		netdev_err(nic->netdev,
			   "Invalid message from PF, msg 0x%x\n", mbx.msg.msg);
+7 −2
Original line number Diff line number Diff line
@@ -544,14 +544,18 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
	nicvf_send_msg_to_pf(nic, &mbx);

	mbx.rq.msg = NIC_MBOX_MSG_RQ_BP_CFG;
	mbx.rq.cfg = (1ULL << 63) | (1ULL << 62) | (qs->vnic_id << 0);
	mbx.rq.cfg = BIT_ULL(63) | BIT_ULL(62) |
		     (RQ_PASS_RBDR_LVL << 16) | (RQ_PASS_CQ_LVL << 8) |
		     (qs->vnic_id << 0);
	nicvf_send_msg_to_pf(nic, &mbx);

	/* RQ drop config
	 * Enable CQ drop to reserve sufficient CQEs for all tx packets
	 */
	mbx.rq.msg = NIC_MBOX_MSG_RQ_DROP_CFG;
	mbx.rq.cfg = (1ULL << 62) | (RQ_CQ_DROP << 8);
	mbx.rq.cfg = BIT_ULL(63) | BIT_ULL(62) |
		     (RQ_PASS_RBDR_LVL << 40) | (RQ_DROP_RBDR_LVL << 32) |
		     (RQ_PASS_CQ_LVL << 16) | (RQ_DROP_CQ_LVL << 8);
	nicvf_send_msg_to_pf(nic, &mbx);

	if (!nic->sqs_mode && (qidx == 0)) {
@@ -650,6 +654,7 @@ static void nicvf_snd_queue_config(struct nicvf *nic, struct queue_set *qs,
	sq_cfg.ldwb = 0;
	sq_cfg.qsize = SND_QSIZE;
	sq_cfg.tstmp_bgx_intf = 0;
	sq_cfg.cq_limit = 0;
	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, *(u64 *)&sq_cfg);

	/* Set threshold value for interrupt generation */
Loading