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

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

Merge branch 'liquidio-CN23XX-part-2'



Raghu Vatsavayi says:

====================
liquidio CN23XX support

I am posting the remaining half of patchset after the
acceptance of first half. With this patchset I am able
to completely submit the code of V3 patchset  which you
earlier advised me to split into smaller ones.

This V5 patch also addresses all the comments from previous
submission:
1) Avoid busy loop while reading registers.
2) Other minor comments about debug messages and constants.

Please apply patches in following order as some of the
patches depend on earlier patches.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0cc1f315 30136395
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -887,6 +887,67 @@ static irqreturn_t cn23xx_interrupt_handler(void *dev)
	return IRQ_HANDLED;
}

static void cn23xx_bar1_idx_setup(struct octeon_device *oct, u64 core_addr,
				  u32 idx, int valid)
{
	u64 bar1;
	u64 reg_adr;

	if (!valid) {
		reg_adr = lio_pci_readq(
			oct, CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx));
		WRITE_ONCE(bar1, reg_adr);
		lio_pci_writeq(oct, (READ_ONCE(bar1) & 0xFFFFFFFEULL),
			       CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx));
		reg_adr = lio_pci_readq(
			oct, CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx));
		WRITE_ONCE(bar1, reg_adr);
		return;
	}

	/*  The PEM(0..3)_BAR1_INDEX(0..15)[ADDR_IDX]<23:4> stores
	 *  bits <41:22> of the Core Addr
	 */
	lio_pci_writeq(oct, (((core_addr >> 22) << 4) | PCI_BAR1_MASK),
		       CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx));

	WRITE_ONCE(bar1, lio_pci_readq(
		   oct, CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx)));
}

static void cn23xx_bar1_idx_write(struct octeon_device *oct, u32 idx, u32 mask)
{
	lio_pci_writeq(oct, mask,
		       CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx));
}

static u32 cn23xx_bar1_idx_read(struct octeon_device *oct, u32 idx)
{
	return (u32)lio_pci_readq(
	    oct, CN23XX_PEM_BAR1_INDEX_REG(oct->pcie_port, idx));
}

/* always call with lock held */
static u32 cn23xx_update_read_index(struct octeon_instr_queue *iq)
{
	u32 new_idx;
	u32 last_done;
	u32 pkt_in_done = readl(iq->inst_cnt_reg);

	last_done = pkt_in_done - iq->pkt_in_done;
	iq->pkt_in_done = pkt_in_done;

	/* Modulo of the new index with the IQ size will give us
	 * the new index.  The iq->reset_instr_cnt is always zero for
	 * cn23xx, so no extra adjustments are needed.
	 */
	new_idx = (iq->octeon_read_index +
		   (u32)(last_done & CN23XX_PKT_IN_DONE_CNT_MASK)) %
		  iq->max_count;

	return new_idx;
}

static void cn23xx_enable_pf_interrupt(struct octeon_device *oct, u8 intr_flag)
{
	struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
@@ -1063,6 +1124,11 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)

	oct->fn_list.soft_reset = cn23xx_pf_soft_reset;
	oct->fn_list.setup_device_regs = cn23xx_setup_pf_device_regs;
	oct->fn_list.update_iq_read_idx = cn23xx_update_read_index;

	oct->fn_list.bar1_idx_setup = cn23xx_bar1_idx_setup;
	oct->fn_list.bar1_idx_write = cn23xx_bar1_idx_write;
	oct->fn_list.bar1_idx_read = cn23xx_bar1_idx_read;

	oct->fn_list.enable_interrupt = cn23xx_enable_pf_interrupt;
	oct->fn_list.disable_interrupt = cn23xx_disable_pf_interrupt;
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct);
int validate_cn23xx_pf_config_info(struct octeon_device *oct,
				   struct octeon_config *conf23xx);

u32 cn23xx_pf_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us);

void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct);

int cn23xx_fw_loaded(struct octeon_device *oct);
+8 −3
Original line number Diff line number Diff line
@@ -156,14 +156,19 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
		dev_info(&oct->pci_dev->dev, "%s MTU Changed from %d to %d\n",
			 netdev->name, netdev->mtu,
			 nctrl->ncmd.s.param1);
		rtnl_lock();
		netdev->mtu = nctrl->ncmd.s.param1;
		call_netdevice_notifiers(NETDEV_CHANGEMTU, netdev);
		rtnl_unlock();
		queue_delayed_work(lio->link_status_wq.wq,
				   &lio->link_status_wq.wk.work, 0);
		break;

	case OCTNET_CMD_GPIO_ACCESS:
		netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n");

		break;

	case OCTNET_CMD_ID_ACTIVE:
		netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n");

		break;

	case OCTNET_CMD_LRO_ENABLE:
+487 −8
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "octeon_network.h"
#include "cn66xx_regs.h"
#include "cn66xx_device.h"
#include "cn23xx_pf_device.h"

static int octnet_get_link_stats(struct net_device *netdev);

@@ -75,6 +76,7 @@ enum {

#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
#define OCT_ETHTOOL_REGDUMP_LEN  4096
#define OCT_ETHTOOL_REGDUMP_LEN_23XX  (4096 * 11)
#define OCT_ETHTOOL_REGSVER  1

/* statistics of PF */
@@ -188,6 +190,10 @@ static const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = {
	"buffer_alloc_failure",
};

/* LiquidIO driver private flags */
static const char oct_priv_flags_strings[][ETH_GSTRING_LEN] = {
};

#define OCTNIC_NCMD_AUTONEG_ON  0x1
#define OCTNIC_NCMD_PHY_ON      0x2

@@ -259,6 +265,13 @@ lio_ethtool_get_channels(struct net_device *dev,
		max_tx = CFG_GET_IQ_MAX_Q(conf6x);
		rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx);
		tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx);
	} else if (OCTEON_CN23XX_PF(oct)) {
		struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf);

		max_rx = CFG_GET_OQ_MAX_Q(conf23);
		max_tx = CFG_GET_IQ_MAX_Q(conf23);
		rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf23, lio->ifidx);
		tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf23, lio->ifidx);
	}

	channel->max_rx = max_rx;
@@ -331,6 +344,32 @@ static int octnet_gpio_access(struct net_device *netdev, int addr, int val)
	return 0;
}

static int octnet_id_active(struct net_device *netdev, int val)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct octnic_ctrl_pkt nctrl;
	int ret = 0;

	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));

	nctrl.ncmd.u64 = 0;
	nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE;
	nctrl.ncmd.s.param1 = val;
	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
	nctrl.wait_time = 100;
	nctrl.netpndev = (u64)netdev;
	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;

	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
	if (ret < 0) {
		dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
		return -EINVAL;
	}

	return 0;
}

/* Callback for when mdio command response arrives
 */
static void octnet_mdio_resp_callback(struct octeon_device *oct,
@@ -474,6 +513,11 @@ static int lio_set_phys_id(struct net_device *netdev,
						   &value);
			if (ret)
				return ret;
		} else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {
			octnet_id_active(netdev, LED_IDENTIFICATION_ON);

			/* returns 0 since updates are asynchronous */
			return 0;
		} else {
			return -EINVAL;
		}
@@ -519,7 +563,10 @@ static int lio_set_phys_id(struct net_device *netdev,
						   &lio->phy_beacon_val);
			if (ret)
				return ret;
		} else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {
			octnet_id_active(netdev, LED_IDENTIFICATION_OFF);

			return 0;
		} else {
			return -EINVAL;
		}
@@ -548,6 +595,13 @@ lio_ethtool_get_ringparam(struct net_device *netdev,
		rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS;
		rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx);
		tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx);
	} else if (OCTEON_CN23XX_PF(oct)) {
		struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf);

		tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS;
		rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS;
		rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf23, lio->ifidx);
		tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf23, lio->ifidx);
	}

	if (lio->mtu > OCTNET_DEFAULT_FRM_SIZE - OCTNET_FRM_HEADER_SIZE) {
@@ -608,6 +662,69 @@ lio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
	pause->rx_pause = oct->rx_pause;
}

static int
lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
{
	/* Notes: Not supporting any auto negotiation in these
	 * drivers.
	 */
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct octnic_ctrl_pkt nctrl;
	struct oct_link_info *linfo = &lio->linfo;

	int ret = 0;

	if (oct->chip_id != OCTEON_CN23XX_PF_VID)
		return -EINVAL;

	if (linfo->link.s.duplex == 0) {
		/*no flow control for half duplex*/
		if (pause->rx_pause || pause->tx_pause)
			return -EINVAL;
	}

	/*do not support autoneg of link flow control*/
	if (pause->autoneg == AUTONEG_ENABLE)
		return -EINVAL;

	memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));

	nctrl.ncmd.u64 = 0;
	nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL;
	nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
	nctrl.wait_time = 100;
	nctrl.netpndev = (u64)netdev;
	nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;

	if (pause->rx_pause) {
		/*enable rx pause*/
		nctrl.ncmd.s.param1 = 1;
	} else {
		/*disable rx pause*/
		nctrl.ncmd.s.param1 = 0;
	}

	if (pause->tx_pause) {
		/*enable tx pause*/
		nctrl.ncmd.s.param2 = 1;
	} else {
		/*disable tx pause*/
		nctrl.ncmd.s.param2 = 0;
	}

	ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
	if (ret < 0) {
		dev_err(&oct->pci_dev->dev, "Failed to set pause parameter\n");
		return -EINVAL;
	}

	oct->rx_pause = pause->rx_pause;
	oct->tx_pause = pause->tx_pause;

	return 0;
}

static void
lio_get_ethtool_stats(struct net_device *netdev,
		      struct ethtool_stats *stats  __attribute__((unused)),
@@ -875,6 +992,27 @@ lio_get_ethtool_stats(struct net_device *netdev,
	}
}

static void lio_get_priv_flags_strings(struct lio *lio, u8 *data)
{
	struct octeon_device *oct_dev = lio->oct_dev;
	int i;

	switch (oct_dev->chip_id) {
	case OCTEON_CN23XX_PF_VID:
		for (i = 0; i < ARRAY_SIZE(oct_priv_flags_strings); i++) {
			sprintf(data, "%s", oct_priv_flags_strings[i]);
			data += ETH_GSTRING_LEN;
		}
		break;
	case OCTEON_CN68XX:
	case OCTEON_CN66XX:
		break;
	default:
		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
		break;
	}
}

static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
	struct lio *lio = GET_LIO(netdev);
@@ -914,12 +1052,31 @@ static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
		}
		break;

	case ETH_SS_PRIV_FLAGS:
		lio_get_priv_flags_strings(lio, data);
		break;
	default:
		netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n");
		break;
	}
}

static int lio_get_priv_flags_ss_count(struct lio *lio)
{
	struct octeon_device *oct_dev = lio->oct_dev;

	switch (oct_dev->chip_id) {
	case OCTEON_CN23XX_PF_VID:
		return ARRAY_SIZE(oct_priv_flags_strings);
	case OCTEON_CN68XX:
	case OCTEON_CN66XX:
		return -EOPNOTSUPP;
	default:
		netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
		return -EOPNOTSUPP;
	}
}

static int lio_get_sset_count(struct net_device *netdev, int sset)
{
	struct lio *lio = GET_LIO(netdev);
@@ -930,6 +1087,8 @@ static int lio_get_sset_count(struct net_device *netdev, int sset)
		return (ARRAY_SIZE(oct_stats_strings) +
			ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs +
			ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);
	case ETH_SS_PRIV_FLAGS:
		return lio_get_priv_flags_ss_count(lio);
	default:
		return -EOPNOTSUPP;
	}
@@ -946,6 +1105,16 @@ static int lio_get_intr_coalesce(struct net_device *netdev,
	intrmod_cfg = &oct->intrmod;

	switch (oct->chip_id) {
	case OCTEON_CN23XX_PF_VID:
		if (!intrmod_cfg->rx_enable) {
			intr_coal->rx_coalesce_usecs = intrmod_cfg->rx_usecs;
			intr_coal->rx_max_coalesced_frames =
				intrmod_cfg->rx_frames;
		}
		if (!intrmod_cfg->tx_enable)
			intr_coal->tx_max_coalesced_frames =
				intrmod_cfg->tx_frames;
		break;
	case OCTEON_CN68XX:
	case OCTEON_CN66XX: {
		struct octeon_cn6xxx *cn6xxx =
@@ -983,6 +1152,14 @@ static int lio_get_intr_coalesce(struct net_device *netdev,
		intr_coal->rx_max_coalesced_frames_low =
		    intrmod_cfg->rx_mincnt_trigger;
	}
	if (OCTEON_CN23XX_PF(oct) &&
	    (intrmod_cfg->tx_enable)) {
		intr_coal->use_adaptive_tx_coalesce = intrmod_cfg->tx_enable;
		intr_coal->tx_max_coalesced_frames_high =
		    intrmod_cfg->tx_maxcnt_trigger;
		intr_coal->tx_max_coalesced_frames_low =
		    intrmod_cfg->tx_mincnt_trigger;
	}
	return 0;
}

@@ -1059,10 +1236,10 @@ octnet_nic_stats_callback(struct octeon_device *oct_dev,
			  u32 status, void *ptr)
{
	struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr;
	struct oct_nic_stats_resp *resp = (struct oct_nic_stats_resp *)
		sc->virtrptr;
	struct oct_nic_stats_ctrl *ctrl = (struct oct_nic_stats_ctrl *)
		sc->ctxptr;
	struct oct_nic_stats_resp *resp =
	    (struct oct_nic_stats_resp *)sc->virtrptr;
	struct oct_nic_stats_ctrl *ctrl =
	    (struct oct_nic_stats_ctrl *)sc->ctxptr;
	struct nic_rx_stats *rsp_rstats = &resp->stats.fromwire;
	struct nic_tx_stats *rsp_tstats = &resp->stats.fromhost;

@@ -1312,6 +1489,27 @@ oct_cfg_rx_intrcnt(struct lio *lio, struct ethtool_coalesce *intr_coal)
		CFG_SET_OQ_INTR_PKT(cn6xxx->conf, rx_max_coalesced_frames);
		break;
	}
	case OCTEON_CN23XX_PF_VID: {
		int q_no;

		if (!intr_coal->rx_max_coalesced_frames)
			rx_max_coalesced_frames = oct->intrmod.rx_frames;
		else
			rx_max_coalesced_frames =
			    intr_coal->rx_max_coalesced_frames;
		for (q_no = 0; q_no < oct->num_oqs; q_no++) {
			q_no += oct->sriov_info.pf_srn;
			octeon_write_csr64(
			    oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
			    (octeon_read_csr64(
				 oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) &
			     (0x3fffff00000000UL)) |
				rx_max_coalesced_frames);
			/*consider setting resend bit*/
		}
		oct->intrmod.rx_frames = rx_max_coalesced_frames;
		break;
	}
	default:
		return -EINVAL;
	}
@@ -1344,6 +1542,27 @@ static int oct_cfg_rx_intrtime(struct lio *lio,
		CFG_SET_OQ_INTR_TIME(cn6xxx->conf, rx_coalesce_usecs);
		break;
	}
	case OCTEON_CN23XX_PF_VID: {
		u64 time_threshold;
		int q_no;

		if (!intr_coal->rx_coalesce_usecs)
			rx_coalesce_usecs = oct->intrmod.rx_usecs;
		else
			rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
		time_threshold =
		    cn23xx_pf_get_oq_ticks(oct, (u32)rx_coalesce_usecs);
		for (q_no = 0; q_no < oct->num_oqs; q_no++) {
			q_no += oct->sriov_info.pf_srn;
			octeon_write_csr64(oct,
					   CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
					   (oct->intrmod.rx_frames |
					    (time_threshold << 32)));
			/*consider writing to resend bit here*/
		}
		oct->intrmod.rx_usecs = rx_coalesce_usecs;
		break;
	}
	default:
		return -EINVAL;
	}
@@ -1356,12 +1575,37 @@ oct_cfg_tx_intrcnt(struct lio *lio, struct ethtool_coalesce *intr_coal
		   __attribute__((unused)))
{
	struct octeon_device *oct = lio->oct_dev;
	u32 iq_intr_pkt;
	void __iomem *inst_cnt_reg;
	u64 val;

	/* Config Cnt based interrupt values */
	switch (oct->chip_id) {
	case OCTEON_CN68XX:
	case OCTEON_CN66XX:
		break;
	case OCTEON_CN23XX_PF_VID: {
		int q_no;

		if (!intr_coal->tx_max_coalesced_frames)
			iq_intr_pkt = CN23XX_DEF_IQ_INTR_THRESHOLD &
				      CN23XX_PKT_IN_DONE_WMARK_MASK;
		else
			iq_intr_pkt = intr_coal->tx_max_coalesced_frames &
				      CN23XX_PKT_IN_DONE_WMARK_MASK;
		for (q_no = 0; q_no < oct->num_iqs; q_no++) {
			inst_cnt_reg = (oct->instr_queue[q_no])->inst_cnt_reg;
			val = readq(inst_cnt_reg);
			/*clear wmark and count.dont want to write count back*/
			val = (val & 0xFFFF000000000000ULL) |
			      ((u64)iq_intr_pkt
			       << CN23XX_PKT_IN_DONE_WMARK_BIT_POS);
			writeq(val, inst_cnt_reg);
			/*consider setting resend bit*/
		}
		oct->intrmod.tx_frames = iq_intr_pkt;
		break;
	}
	default:
		return -EINVAL;
	}
@@ -1397,6 +1641,8 @@ static int lio_set_intr_coalesce(struct net_device *netdev,
			return -EINVAL;
		}
		break;
	case OCTEON_CN23XX_PF_VID:
		break;
	default:
		return -EINVAL;
	}
@@ -1539,10 +1785,238 @@ static int lio_nway_reset(struct net_device *netdev)
}

/* Return register dump len. */
static int lio_get_regs_len(struct net_device *dev __attribute__((unused)))
static int lio_get_regs_len(struct net_device *dev)
{
	struct lio *lio = GET_LIO(dev);
	struct octeon_device *oct = lio->oct_dev;

	switch (oct->chip_id) {
	case OCTEON_CN23XX_PF_VID:
		return OCT_ETHTOOL_REGDUMP_LEN_23XX;
	default:
		return OCT_ETHTOOL_REGDUMP_LEN;
	}
}

static int cn23xx_read_csr_reg(char *s, struct octeon_device *oct)
{
	u32 reg;
	u8 pf_num = oct->pf_num;
	int len = 0;
	int i;

	/* PCI  Window Registers */

	len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");

	/*0x29030 or 0x29040*/
	reg = CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num);
	len += sprintf(s + len,
		       "\n[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n",
		       reg, oct->pcie_port, oct->pf_num,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x27080 or 0x27090*/
	reg = CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num);
	len +=
	    sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n",
		    reg, oct->pcie_port, oct->pf_num,
		    (u64)octeon_read_csr64(oct, reg));

	/*0x27000 or 0x27010*/
	reg = CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num);
	len +=
	    sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n",
		    reg, oct->pcie_port, oct->pf_num,
		    (u64)octeon_read_csr64(oct, reg));

	/*0x29120*/
	reg = 0x29120;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x27300*/
	reg = 0x27300 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +
	      (oct->pf_num) * CN23XX_PF_INT_OFFSET;
	len += sprintf(
	    s + len, "\n[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n", reg,
	    oct->pcie_port, oct->pf_num, (u64)octeon_read_csr64(oct, reg));

	/*0x27200*/
	reg = 0x27200 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +
	      (oct->pf_num) * CN23XX_PF_INT_OFFSET;
	len += sprintf(s + len,
		       "\n[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n",
		       reg, oct->pcie_port, oct->pf_num,
		       (u64)octeon_read_csr64(oct, reg));

	/*29130*/
	reg = CN23XX_SLI_PKT_CNT_INT;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x29140*/
	reg = CN23XX_SLI_PKT_TIME_INT;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x29160*/
	reg = 0x29160;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_INT): %016llx\n", reg,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x29180*/
	reg = CN23XX_SLI_OQ_WMARK;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n",
		       reg, (u64)octeon_read_csr64(oct, reg));

	/*0x291E0*/
	reg = CN23XX_SLI_PKT_IOQ_RING_RST;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_RING_RST): %016llx\n", reg,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x29210*/
	reg = CN23XX_SLI_GBL_CONTROL;
	len += sprintf(s + len,
		       "\n[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg,
		       (u64)octeon_read_csr64(oct, reg));

	/*0x29220*/
	reg = 0x29220;
	len += sprintf(s + len, "\n[%08x] (SLI_PKT_BIST_STATUS): %016llx\n",
		       reg, (u64)octeon_read_csr64(oct, reg));

	/*PF only*/
	if (pf_num == 0) {
		/*0x29260*/
		reg = CN23XX_SLI_OUT_BP_EN_W1S;
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT_OUT_BP_EN_W1S):  %016llx\n",
			       reg, (u64)octeon_read_csr64(oct, reg));
	} else if (pf_num == 1) {
		/*0x29270*/
		reg = CN23XX_SLI_OUT_BP_EN2_W1S;
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n",
			       reg, (u64)octeon_read_csr64(oct, reg));
	}

	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_BUFF_INFO_SIZE(i);
		len +=
		    sprintf(s + len, "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",
			    reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x10040*/
	for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
		reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x10080*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_PKTS_CREDIT(i);
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x10090*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_SIZE(i);
		len += sprintf(
		    s + len, "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",
		    reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x10050*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_PKT_CONTROL(i);
		len += sprintf(
			s + len,
			"\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",
			reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x10070*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_BASE_ADDR64(i);
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x100a0*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_PKT_INT_LEVELS(i);
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x100b0*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = CN23XX_SLI_OQ_PKTS_SENT(i);
		len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	/*0x100c0*/
	for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
		reg = 0x100c0 + i * CN23XX_OQ_OFFSET;
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));

		/*0x10000*/
		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
			reg = CN23XX_SLI_IQ_PKT_CONTROL64(i);
			len += sprintf(
				s + len,
				"\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",
				reg, i, (u64)octeon_read_csr64(oct, reg));
		}

		/*0x10010*/
		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
			reg = CN23XX_SLI_IQ_BASE_ADDR64(i);
			len += sprintf(
			    s + len,
			    "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", reg,
			    i, (u64)octeon_read_csr64(oct, reg));
		}

		/*0x10020*/
		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
			reg = CN23XX_SLI_IQ_DOORBELL(i);
			len += sprintf(
			    s + len,
			    "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",
			    reg, i, (u64)octeon_read_csr64(oct, reg));
		}

		/*0x10030*/
		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
			reg = CN23XX_SLI_IQ_SIZE(i);
			len += sprintf(
			    s + len,
			    "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",
			    reg, i, (u64)octeon_read_csr64(oct, reg));
		}

		/*0x10040*/
		for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++)
			reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);
		len += sprintf(s + len,
			       "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
			       reg, i, (u64)octeon_read_csr64(oct, reg));
	}

	return len;
}

static int cn6xxx_read_csr_reg(char *s, struct octeon_device *oct)
{
@@ -1686,6 +2160,10 @@ static void lio_get_regs(struct net_device *dev,
	regs->version = OCT_ETHTOOL_REGSVER;

	switch (oct->chip_id) {
	case OCTEON_CN23XX_PF_VID:
		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX);
		len += cn23xx_read_csr_reg(regbuf + len, oct);
		break;
	case OCTEON_CN68XX:
	case OCTEON_CN66XX:
		memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN);
@@ -1727,6 +2205,7 @@ static const struct ethtool_ops lio_ethtool_ops = {
	.get_strings		= lio_get_strings,
	.get_ethtool_stats	= lio_get_ethtool_stats,
	.get_pauseparam		= lio_get_pauseparam,
	.set_pauseparam		= lio_set_pauseparam,
	.get_regs_len		= lio_get_regs_len,
	.get_regs		= lio_get_regs,
	.get_msglevel		= lio_get_msglevel,
+323 −37

File changed.

Preview size limit exceeded, changes collapsed.

Loading