Commit 391daec3 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'octeontx2-af-rpm-misc-feaures'

Hariprasad Kelam says:

====================
Octeontx2-af: RPM: misc feaures

This series patches adds different features like debugfs
support for shared firmware structure and DMAC filter
related enhancements.

Patch1: Saves interface MAC address configured from DMAC filters.

Patch2: Disables the stale DMAC filters in driver initialization

Patch3: Configure dma mask for CGX/RPM drivers

Patch4: Debugfs support for shared firmware data.
====================

Link: https://patch.msgid.link/20250720163638.1560323-1-hkelam@marvell.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 2094200b 49f02e68
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -1704,9 +1704,11 @@ unsigned long cgx_get_lmac_bmap(void *cgxd)

static int cgx_lmac_init(struct cgx *cgx)
{
	u8 max_dmac_filters;
	struct lmac *lmac;
	u64 lmac_list;
	int i, err;
	int filter;

	/* lmac_list specifies which lmacs are enabled
	 * when bit n is set to 1, LMAC[n] is enabled
@@ -1745,6 +1747,8 @@ static int cgx_lmac_init(struct cgx *cgx)
				cgx->mac_ops->dmac_filter_count /
				cgx->lmac_count;

		max_dmac_filters = lmac->mac_to_index_bmap.max;

		err = rvu_alloc_bitmap(&lmac->mac_to_index_bmap);
		if (err)
			goto err_name_free;
@@ -1774,6 +1778,15 @@ static int cgx_lmac_init(struct cgx *cgx)
		set_bit(lmac->lmac_id, &cgx->lmac_bmap);
		cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, true);
		lmac->lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac->lmac_id);

		/* Disable stale DMAC filters for sane state */
		for (filter = 0; filter < max_dmac_filters; filter++)
			cgx_lmac_addr_del(cgx->cgx_id, lmac->lmac_id, filter);

		/* As cgx_lmac_addr_del does not clear entry for index 0
		 * so it needs to be done explicitly
		 */
		cgx_lmac_addr_reset(cgx->cgx_id, lmac->lmac_id);
	}

	/* Start X2P reset on given MAC block */
@@ -1951,6 +1964,12 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
		goto err_disable_device;
	}

	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
	if (err) {
		dev_err(dev, "DMA mask config failed, abort\n");
		goto err_release_regions;
	}

	/* MAP configuration registers */
	cgx->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
	if (!cgx->reg_base) {
+6 −1
Original line number Diff line number Diff line
@@ -664,7 +664,12 @@ struct cgx_lmac_fwdata_s {
	/* Only applicable if SFP/QSFP slot is present */
	struct sfp_eeprom_s sfp_eeprom;
	struct phy_s phy;
#define LMAC_FWDATA_RESERVED_MEM 1021
	u32 lmac_type;
	u32 portm_idx;
	u64 mgmt_port:1;
	u64 advertised_an:1;
	u64 port;
#define LMAC_FWDATA_RESERVED_MEM 1018
	u64 reserved[LMAC_FWDATA_RESERVED_MEM];
};

+9 −14
Original line number Diff line number Diff line
@@ -682,16 +682,19 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
				      struct cgx_mac_addr_set_or_get *rsp)
{
	int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
	struct rvu_pfvf *pfvf;
	u8 cgx_id, lmac_id;

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;
	if (!is_pf_cgxmapped(rvu, pf))
		return LMAC_AF_ERR_PF_NOT_MAPPED;

	if (rvu_npc_exact_has_match_table(rvu))
		return rvu_npc_exact_mac_addr_set(rvu, req, rsp);

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);

	pfvf = &rvu->pf[pf];
	ether_addr_copy(pfvf->mac_addr, req->mac_addr);
	cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr);

	return 0;
@@ -769,20 +772,12 @@ int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
				      struct cgx_mac_addr_set_or_get *req,
				      struct cgx_mac_addr_set_or_get *rsp)
{
	int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
	u8 cgx_id, lmac_id;
	int rc = 0;
	u64 cfg;
	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);

	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
		return -EPERM;

	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
	if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, req->hdr.pcifunc)))
		return LMAC_AF_ERR_PF_NOT_MAPPED;

	rsp->hdr.rc = rc;
	cfg = cgx_lmac_addr_get(cgx_id, lmac_id);
	/* copy 48 bit mac address to req->mac_addr */
	u64_to_ether_addr(cfg, rsp->mac_addr);
	ether_addr_copy(rsp->mac_addr, pfvf->mac_addr);
	return 0;
}

+162 −0
Original line number Diff line number Diff line
@@ -867,6 +867,71 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)

RVU_DEBUG_SEQ_FOPS(rvu_pf_cgx_map, rvu_pf_cgx_map_display, NULL);

static int rvu_dbg_rvu_fwdata_display(struct seq_file *s, void *unused)
{
	struct rvu *rvu = s->private;
	struct rvu_fwdata *fwdata;
	u8 mac[ETH_ALEN];
	int count = 0, i;

	if (!rvu->fwdata)
		return -EAGAIN;

	fwdata = rvu->fwdata;
	seq_puts(s, "\nRVU Firmware Data:\n");
	seq_puts(s, "\n\t\tPTP INFORMATION\n");
	seq_puts(s, "\t\t===============\n");
	seq_printf(s, "\t\texternal clockrate \t :%x\n",
		   fwdata->ptp_ext_clk_rate);
	seq_printf(s, "\t\texternal timestamp \t :%x\n",
		   fwdata->ptp_ext_tstamp);
	seq_puts(s, "\n");

	seq_puts(s, "\n\t\tSDP CHANNEL INFORMATION\n");
	seq_puts(s, "\t\t=======================\n");
	seq_printf(s, "\t\tValid \t\t\t :%x\n", fwdata->channel_data.valid);
	seq_printf(s, "\t\tNode ID \t\t :%x\n",
		   fwdata->channel_data.info.node_id);
	seq_printf(s, "\t\tNumber of VFs  \t\t :%x\n",
		   fwdata->channel_data.info.max_vfs);
	seq_printf(s, "\t\tNumber of PF-Rings \t :%x\n",
		   fwdata->channel_data.info.num_pf_rings);
	seq_printf(s, "\t\tPF SRN \t\t\t :%x\n",
		   fwdata->channel_data.info.pf_srn);
	seq_puts(s, "\n");

	seq_puts(s, "\n\t\tPF-INDEX  MACADDRESS\n");
	seq_puts(s, "\t\t====================\n");
	for (i = 0; i < PF_MACNUM_MAX; i++) {
		u64_to_ether_addr(fwdata->pf_macs[i], mac);
		if (!is_zero_ether_addr(mac)) {
			seq_printf(s, "\t\t  %d       %pM\n", i, mac);
			count++;
		}
	}

	if (!count)
		seq_puts(s, "\t\tNo valid address found\n");

	seq_puts(s, "\n\t\tVF-INDEX  MACADDRESS\n");
	seq_puts(s, "\t\t====================\n");
	count = 0;
	for (i = 0; i < VF_MACNUM_MAX; i++) {
		u64_to_ether_addr(fwdata->vf_macs[i], mac);
		if (!is_zero_ether_addr(mac)) {
			seq_printf(s, "\t\t  %d       %pM\n", i, mac);
			count++;
		}
	}

	if (!count)
		seq_puts(s, "\t\tNo valid address found\n");

	return 0;
}

RVU_DEBUG_SEQ_FOPS(rvu_fwdata, rvu_fwdata_display, NULL);

static bool rvu_dbg_is_valid_lf(struct rvu *rvu, int blkaddr, int lf,
				u16 *pcifunc)
{
@@ -2923,6 +2988,97 @@ static int rvu_dbg_cgx_dmac_flt_display(struct seq_file *s, void *unused)

RVU_DEBUG_SEQ_FOPS(cgx_dmac_flt, cgx_dmac_flt_display, NULL);

static int cgx_print_fwdata(struct seq_file *s, int lmac_id)
{
	struct cgx_lmac_fwdata_s *fwdata;
	void *cgxd = s->private;
	struct phy_s *phy;
	struct rvu *rvu;
	int cgx_id, i;

	rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
					     PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
	if (!rvu)
		return -ENODEV;

	if (!rvu->fwdata)
		return -EAGAIN;

	cgx_id = cgx_get_cgxid(cgxd);

	if (rvu->hw->lmac_per_cgx == CGX_LMACS_USX)
		fwdata =  &rvu->fwdata->cgx_fw_data_usx[cgx_id][lmac_id];
	else
		fwdata =  &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id];

	seq_puts(s, "\nFIRMWARE SHARED:\n");
	seq_puts(s, "\t\tSUPPORTED LINK INFORMATION\t\t\n");
	seq_puts(s, "\t\t==========================\n");
	seq_printf(s, "\t\t Link modes \t\t :%llx\n",
		   fwdata->supported_link_modes);
	seq_printf(s, "\t\t Autoneg \t\t :%llx\n", fwdata->supported_an);
	seq_printf(s, "\t\t FEC \t\t\t :%llx\n", fwdata->supported_fec);
	seq_puts(s, "\n");

	seq_puts(s, "\t\tADVERTISED LINK INFORMATION\t\t\n");
	seq_puts(s, "\t\t==========================\n");
	seq_printf(s, "\t\t Link modes \t\t :%llx\n",
		   (u64)fwdata->advertised_link_modes);
	seq_printf(s, "\t\t Autoneg \t\t :%x\n", fwdata->advertised_an);
	seq_printf(s, "\t\t FEC \t\t\t :%llx\n", fwdata->advertised_fec);
	seq_puts(s, "\n");

	seq_puts(s, "\t\tLMAC CONFIG\t\t\n");
	seq_puts(s, "\t\t============\n");
	seq_printf(s, "\t\t rw_valid  \t\t :%x\n",  fwdata->rw_valid);
	seq_printf(s, "\t\t lmac_type \t\t :%x\n", fwdata->lmac_type);
	seq_printf(s, "\t\t portm_idx \t\t :%x\n", fwdata->portm_idx);
	seq_printf(s, "\t\t mgmt_port \t\t :%x\n", fwdata->mgmt_port);
	seq_printf(s, "\t\t Link modes own \t :%llx\n",
		   (u64)fwdata->advertised_link_modes_own);
	seq_puts(s, "\n");

	seq_puts(s, "\n\t\tEEPROM DATA\n");
	seq_puts(s, "\t\t===========\n");
	seq_printf(s, "\t\t sff_id \t\t :%x\n", fwdata->sfp_eeprom.sff_id);
	seq_puts(s, "\t\t data \t\t\t :\n");
	seq_puts(s, "\t\t");
	for (i = 0; i < SFP_EEPROM_SIZE; i++) {
		seq_printf(s, "%x", fwdata->sfp_eeprom.buf[i]);
		if ((i + 1) % 16 == 0) {
			seq_puts(s, "\n");
			seq_puts(s, "\t\t");
		}
	}
	seq_puts(s, "\n");

	phy = &fwdata->phy;
	seq_puts(s, "\n\t\tPHY INFORMATION\n");
	seq_puts(s, "\t\t===============\n");
	seq_printf(s, "\t\t Mod type configurable \t\t :%x\n",
		   phy->misc.can_change_mod_type);
	seq_printf(s, "\t\t Mod type \t\t\t :%x\n", phy->misc.mod_type);
	seq_printf(s, "\t\t Support FEC \t\t\t :%x\n", phy->misc.has_fec_stats);
	seq_printf(s, "\t\t RSFEC corrected words \t\t :%x\n",
		   phy->fec_stats.rsfec_corr_cws);
	seq_printf(s, "\t\t RSFEC uncorrected words \t :%x\n",
		   phy->fec_stats.rsfec_uncorr_cws);
	seq_printf(s, "\t\t BRFEC corrected words \t\t :%x\n",
		   phy->fec_stats.brfec_corr_blks);
	seq_printf(s, "\t\t BRFEC uncorrected words \t :%x\n",
		   phy->fec_stats.brfec_uncorr_blks);
	seq_puts(s, "\n");

	return 0;
}

static int rvu_dbg_cgx_fwdata_display(struct seq_file *s, void *unused)
{
	return cgx_print_fwdata(s, rvu_dbg_derive_lmacid(s));
}

RVU_DEBUG_SEQ_FOPS(cgx_fwdata, cgx_fwdata_display, NULL);

static void rvu_dbg_cgx_init(struct rvu *rvu)
{
	struct mac_ops *mac_ops;
@@ -2962,6 +3118,9 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)
			debugfs_create_file_aux_num("mac_filter", 0600,
					    rvu->rvu_dbg.lmac, cgx, lmac_id,
					    &rvu_dbg_cgx_dmac_flt_fops);
			debugfs_create_file("fwdata", 0600,
					    rvu->rvu_dbg.lmac, cgx,
					    &rvu_dbg_cgx_fwdata_fops);
		}
	}
}
@@ -3808,6 +3967,9 @@ void rvu_dbg_init(struct rvu *rvu)
		debugfs_create_file("lmtst_map_table", 0444, rvu->rvu_dbg.root,
				    rvu, &rvu_dbg_lmtst_map_table_fops);

	debugfs_create_file("rvu_fwdata", 0444, rvu->rvu_dbg.root, rvu,
			    &rvu_dbg_rvu_fwdata_fops);

	if (!cgx_get_cgxcnt_max())
		goto create;