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

Merge branch 'octeon-ethtool'



Hariprasad Kelam says:

====================
ethtool support for fec and link configuration

This series of patches add support for forward error correction(fec) and
physical link configuration. Patches 1&2 adds necessary mbox handlers for fec
mode configuration request and to fetch stats. Patch 3 registers driver
callbacks for fec mode configuration and display. Patch 4&5 adds support of mbox
handlers for configuring link parameters like speed/duplex and autoneg etc.
Patche 6&7 registers driver callbacks for physical link configuration.

Change-log:
v2:
	- Fixed review comments
	- Corrected indentation issues
        - Return -ENOMEM incase of mbox allocation failure
	- added validation for input fecparams bitmask values
        - added more comments

V3:
	- Removed inline functions
        - Make use of ethtool helpers APIs to display supported
          advertised modes
        - corrected indentation issues
        - code changes such that return early in case of failure
          to aid branch prediction
v4:
	- Corrected indentation issues
	- Use FEC_OFF if user requests for FEC_AUTO mode
	- Do not clear fec stats in case of user changes
	  fec mode
	- dont hide fec stats depending on interface mode
	  selection
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1fb3ca76 cff713ce
Loading
Loading
Loading
Loading
+257 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
@@ -340,6 +341,60 @@ int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat)
	return 0;
}

static int cgx_set_fec_stats_count(struct cgx_link_user_info *linfo)
{
	if (!linfo->fec)
		return 0;

	switch (linfo->lmac_type_id) {
	case LMAC_MODE_SGMII:
	case LMAC_MODE_XAUI:
	case LMAC_MODE_RXAUI:
	case LMAC_MODE_QSGMII:
		return 0;
	case LMAC_MODE_10G_R:
	case LMAC_MODE_25G_R:
	case LMAC_MODE_100G_R:
	case LMAC_MODE_USXGMII:
		return 1;
	case LMAC_MODE_40G_R:
		return 4;
	case LMAC_MODE_50G_R:
		if (linfo->fec == OTX2_FEC_BASER)
			return 2;
		else
			return 1;
	default:
		return 0;
	}
}

int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp)
{
	int stats, fec_stats_count = 0;
	int corr_reg, uncorr_reg;
	struct cgx *cgx = cgxd;

	if (!cgx || lmac_id >= cgx->lmac_count)
		return -ENODEV;
	fec_stats_count =
		cgx_set_fec_stats_count(&cgx->lmac_idmap[lmac_id]->link_info);
	if (cgx->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) {
		corr_reg = CGXX_SPUX_LNX_FEC_CORR_BLOCKS;
		uncorr_reg = CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS;
	} else {
		corr_reg = CGXX_SPUX_RSFEC_CORR;
		uncorr_reg = CGXX_SPUX_RSFEC_UNCORR;
	}
	for (stats = 0; stats < fec_stats_count; stats++) {
		rsp->fec_corr_blks +=
			cgx_read(cgx, lmac_id, corr_reg + (stats * 8));
		rsp->fec_uncorr_blks +=
			cgx_read(cgx, lmac_id, uncorr_reg + (stats * 8));
	}
	return 0;
}

int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable)
{
	struct cgx *cgx = cgxd;
@@ -592,6 +647,7 @@ static inline void cgx_link_usertable_init(void)
	cgx_speed_mbps[CGX_LINK_25G] = 25000;
	cgx_speed_mbps[CGX_LINK_40G] = 40000;
	cgx_speed_mbps[CGX_LINK_50G] = 50000;
	cgx_speed_mbps[CGX_LINK_80G] = 80000;
	cgx_speed_mbps[CGX_LINK_100G] = 100000;

	cgx_lmactype_string[LMAC_MODE_SGMII] = "SGMII";
@@ -606,6 +662,143 @@ static inline void cgx_link_usertable_init(void)
	cgx_lmactype_string[LMAC_MODE_USXGMII] = "USXGMII";
}

static int cgx_link_usertable_index_map(int speed)
{
	switch (speed) {
	case SPEED_10:
		return CGX_LINK_10M;
	case SPEED_100:
		return CGX_LINK_100M;
	case SPEED_1000:
		return CGX_LINK_1G;
	case SPEED_2500:
		return CGX_LINK_2HG;
	case SPEED_5000:
		return CGX_LINK_5G;
	case SPEED_10000:
		return CGX_LINK_10G;
	case SPEED_20000:
		return CGX_LINK_20G;
	case SPEED_25000:
		return CGX_LINK_25G;
	case SPEED_40000:
		return CGX_LINK_40G;
	case SPEED_50000:
		return CGX_LINK_50G;
	case 80000:
		return CGX_LINK_80G;
	case SPEED_100000:
		return CGX_LINK_100G;
	case SPEED_UNKNOWN:
		return CGX_LINK_NONE;
	}
	return CGX_LINK_NONE;
}

static void set_mod_args(struct cgx_set_link_mode_args *args,
			 u32 speed, u8 duplex, u8 autoneg, u64 mode)
{
	/* Fill default values incase of user did not pass
	 * valid parameters
	 */
	if (args->duplex == DUPLEX_UNKNOWN)
		args->duplex = duplex;
	if (args->speed == SPEED_UNKNOWN)
		args->speed = speed;
	if (args->an == AUTONEG_UNKNOWN)
		args->an = autoneg;
	args->mode = mode;
	args->ports = 0;
}

static void otx2_map_ethtool_link_modes(u64 bitmask,
					struct cgx_set_link_mode_args *args)
{
	switch (bitmask) {
	case ETHTOOL_LINK_MODE_10baseT_Half_BIT:
		set_mod_args(args, 10, 1, 1, BIT_ULL(CGX_MODE_SGMII));
		break;
	case  ETHTOOL_LINK_MODE_10baseT_Full_BIT:
		set_mod_args(args, 10, 0, 1, BIT_ULL(CGX_MODE_SGMII));
		break;
	case  ETHTOOL_LINK_MODE_100baseT_Half_BIT:
		set_mod_args(args, 100, 1, 1, BIT_ULL(CGX_MODE_SGMII));
		break;
	case  ETHTOOL_LINK_MODE_100baseT_Full_BIT:
		set_mod_args(args, 100, 0, 1, BIT_ULL(CGX_MODE_SGMII));
		break;
	case  ETHTOOL_LINK_MODE_1000baseT_Half_BIT:
		set_mod_args(args, 1000, 1, 1, BIT_ULL(CGX_MODE_SGMII));
		break;
	case  ETHTOOL_LINK_MODE_1000baseT_Full_BIT:
		set_mod_args(args, 1000, 0, 1, BIT_ULL(CGX_MODE_SGMII));
		break;
	case  ETHTOOL_LINK_MODE_1000baseX_Full_BIT:
		set_mod_args(args, 1000, 0, 0, BIT_ULL(CGX_MODE_1000_BASEX));
		break;
	case  ETHTOOL_LINK_MODE_10000baseT_Full_BIT:
		set_mod_args(args, 1000, 0, 1, BIT_ULL(CGX_MODE_QSGMII));
		break;
	case  ETHTOOL_LINK_MODE_10000baseSR_Full_BIT:
		set_mod_args(args, 10000, 0, 0, BIT_ULL(CGX_MODE_10G_C2C));
		break;
	case  ETHTOOL_LINK_MODE_10000baseLR_Full_BIT:
		set_mod_args(args, 10000, 0, 0, BIT_ULL(CGX_MODE_10G_C2M));
		break;
	case  ETHTOOL_LINK_MODE_10000baseKR_Full_BIT:
		set_mod_args(args, 10000, 0, 1, BIT_ULL(CGX_MODE_10G_KR));
		break;
	case  ETHTOOL_LINK_MODE_25000baseSR_Full_BIT:
		set_mod_args(args, 25000, 0, 0, BIT_ULL(CGX_MODE_25G_C2C));
		break;
	case  ETHTOOL_LINK_MODE_25000baseCR_Full_BIT:
		set_mod_args(args, 25000, 0, 1, BIT_ULL(CGX_MODE_25G_CR));
		break;
	case  ETHTOOL_LINK_MODE_25000baseKR_Full_BIT:
		set_mod_args(args, 25000, 0, 1, BIT_ULL(CGX_MODE_25G_KR));
		break;
	case  ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT:
		set_mod_args(args, 40000, 0, 0, BIT_ULL(CGX_MODE_40G_C2C));
		break;
	case  ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT:
		set_mod_args(args, 40000, 0, 0, BIT_ULL(CGX_MODE_40G_C2M));
		break;
	case  ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT:
		set_mod_args(args, 40000, 0, 1, BIT_ULL(CGX_MODE_40G_CR4));
		break;
	case  ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT:
		set_mod_args(args, 40000, 0, 1, BIT_ULL(CGX_MODE_40G_KR4));
		break;
	case  ETHTOOL_LINK_MODE_50000baseSR_Full_BIT:
		set_mod_args(args, 50000, 0, 0, BIT_ULL(CGX_MODE_50G_C2C));
		break;
	case  ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT:
		set_mod_args(args, 50000, 0, 0, BIT_ULL(CGX_MODE_50G_C2M));
		break;
	case  ETHTOOL_LINK_MODE_50000baseCR_Full_BIT:
		set_mod_args(args, 50000, 0, 1, BIT_ULL(CGX_MODE_50G_CR));
		break;
	case  ETHTOOL_LINK_MODE_50000baseKR_Full_BIT:
		set_mod_args(args, 50000, 0, 1, BIT_ULL(CGX_MODE_50G_KR));
		break;
	case  ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT:
		set_mod_args(args, 100000, 0, 0, BIT_ULL(CGX_MODE_100G_C2C));
		break;
	case  ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT:
		set_mod_args(args, 100000, 0, 0, BIT_ULL(CGX_MODE_100G_C2M));
		break;
	case  ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT:
		set_mod_args(args, 100000, 0, 1, BIT_ULL(CGX_MODE_100G_CR4));
		break;
	case  ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT:
		set_mod_args(args, 100000, 0, 1, BIT_ULL(CGX_MODE_100G_KR4));
		break;
	default:
		set_mod_args(args, 0, 1, 0, BIT_ULL(CGX_MODE_MAX));
		break;
	}
}

static inline void link_status_user_format(u64 lstat,
					   struct cgx_link_user_info *linfo,
					   struct cgx *cgx, u8 lmac_id)
@@ -615,6 +808,8 @@ static inline void link_status_user_format(u64 lstat,
	linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
	linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
	linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)];
	linfo->an = FIELD_GET(RESP_LINKSTAT_AN, lstat);
	linfo->fec = FIELD_GET(RESP_LINKSTAT_FEC, lstat);
	linfo->lmac_type_id = cgx_get_lmac_type(cgx, lmac_id);
	lmac_string = cgx_lmactype_string[linfo->lmac_type_id];
	strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1);
@@ -642,6 +837,9 @@ static inline void cgx_link_change_handler(u64 lstat,
	lmac->link_info = event.link_uinfo;
	linfo = &lmac->link_info;

	if (err_type == CGX_ERR_SPEED_CHANGE_INVALID)
		return;

	/* Ensure callback doesn't get unregistered until we finish it */
	spin_lock(&lmac->event_cb_lock);

@@ -670,7 +868,8 @@ static inline bool cgx_cmdresp_is_linkevent(u64 event)

	id = FIELD_GET(EVTREG_ID, event);
	if (id == CGX_CMD_LINK_BRING_UP ||
	    id == CGX_CMD_LINK_BRING_DOWN)
	    id == CGX_CMD_LINK_BRING_DOWN ||
	    id == CGX_CMD_MODE_CHANGE)
		return true;
	else
		return false;
@@ -785,6 +984,63 @@ int cgx_get_fwdata_base(u64 *base)
	return err;
}

int cgx_set_link_mode(void *cgxd, struct cgx_set_link_mode_args args,
		      int cgx_id, int lmac_id)
{
	struct cgx *cgx = cgxd;
	u64 req = 0, resp;

	if (!cgx)
		return -ENODEV;

	if (args.mode)
		otx2_map_ethtool_link_modes(args.mode, &args);
	if (!args.speed && args.duplex && !args.an)
		return -EINVAL;

	req = FIELD_SET(CMDREG_ID, CGX_CMD_MODE_CHANGE, req);
	req = FIELD_SET(CMDMODECHANGE_SPEED,
			cgx_link_usertable_index_map(args.speed), req);
	req = FIELD_SET(CMDMODECHANGE_DUPLEX, args.duplex, req);
	req = FIELD_SET(CMDMODECHANGE_AN, args.an, req);
	req = FIELD_SET(CMDMODECHANGE_PORT, args.ports, req);
	req = FIELD_SET(CMDMODECHANGE_FLAGS, args.mode, req);

	return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
}
int cgx_set_fec(u64 fec, int cgx_id, int lmac_id)
{
	u64 req = 0, resp;
	struct cgx *cgx;
	int err = 0;

	cgx = cgx_get_pdata(cgx_id);
	if (!cgx)
		return -ENXIO;

	req = FIELD_SET(CMDREG_ID, CGX_CMD_SET_FEC, req);
	req = FIELD_SET(CMDSETFEC, fec, req);
	err = cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
	if (err)
		return err;

	cgx->lmac_idmap[lmac_id]->link_info.fec =
			FIELD_GET(RESP_LINKSTAT_FEC, resp);
	return cgx->lmac_idmap[lmac_id]->link_info.fec;
}

int cgx_get_phy_fec_stats(void *cgxd, int lmac_id)
{
	struct cgx *cgx = cgxd;
	u64 req = 0, resp;

	if (!cgx)
		return -ENODEV;

	req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_PHY_FEC_STATS, req);
	return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
}

static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable)
{
	u64 req = 0;
+10 −0
Original line number Diff line number Diff line
@@ -56,6 +56,11 @@
#define CGXX_SCRATCH1_REG		0x1058
#define CGX_CONST			0x2000
#define CGXX_SPUX_CONTROL1		0x10000
#define CGXX_SPUX_LNX_FEC_CORR_BLOCKS	0x10700
#define CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS	0x10800
#define CGXX_SPUX_RSFEC_CORR		0x10088
#define CGXX_SPUX_RSFEC_UNCORR		0x10090

#define CGXX_SPUX_CONTROL1_LBK		BIT_ULL(14)
#define CGXX_GMP_PCS_MRX_CTL		0x30000
#define CGXX_GMP_PCS_MRX_CTL_LBK	BIT_ULL(14)
@@ -147,5 +152,10 @@ int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
			   u8 tx_pause, u8 rx_pause);
void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id);
int cgx_set_fec(u64 fec, int cgx_id, int lmac_id);
int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
int cgx_get_phy_fec_stats(void *cgxd, int lmac_id);
int cgx_set_link_mode(void *cgxd, struct cgx_set_link_mode_args args,
		      int cgx_id, int lmac_id);

#endif /* CGX_H */
+67 −3
Original line number Diff line number Diff line
@@ -43,7 +43,13 @@ enum cgx_error_type {
	CGX_ERR_TRAINING_FAIL,
	CGX_ERR_RX_EQU_FAIL,
	CGX_ERR_SPUX_BER_FAIL,
	CGX_ERR_SPUX_RSFEC_ALGN_FAIL,   /* = 22 */
	CGX_ERR_SPUX_RSFEC_ALGN_FAIL,
	CGX_ERR_SPUX_MARKER_LOCK_FAIL,
	CGX_ERR_SET_FEC_INVALID,
	CGX_ERR_SET_FEC_FAIL,
	CGX_ERR_MODULE_INVALID,
	CGX_ERR_MODULE_NOT_PRESENT,
	CGX_ERR_SPEED_CHANGE_INVALID,
};

/* LINK speed types */
@@ -59,10 +65,41 @@ enum cgx_link_speed {
	CGX_LINK_25G,
	CGX_LINK_40G,
	CGX_LINK_50G,
	CGX_LINK_80G,
	CGX_LINK_100G,
	CGX_LINK_SPEED_MAX,
};

enum CGX_MODE_ {
	CGX_MODE_SGMII,
	CGX_MODE_1000_BASEX,
	CGX_MODE_QSGMII,
	CGX_MODE_10G_C2C,
	CGX_MODE_10G_C2M,
	CGX_MODE_10G_KR,
	CGX_MODE_20G_C2C,
	CGX_MODE_25G_C2C,
	CGX_MODE_25G_C2M,
	CGX_MODE_25G_2_C2C,
	CGX_MODE_25G_CR,
	CGX_MODE_25G_KR,
	CGX_MODE_40G_C2C,
	CGX_MODE_40G_C2M,
	CGX_MODE_40G_CR4,
	CGX_MODE_40G_KR4,
	CGX_MODE_40GAUI_C2C,
	CGX_MODE_50G_C2C,
	CGX_MODE_50G_C2M,
	CGX_MODE_50G_4_C2C,
	CGX_MODE_50G_CR,
	CGX_MODE_50G_KR,
	CGX_MODE_80GAUI_C2C,
	CGX_MODE_100G_C2C,
	CGX_MODE_100G_C2M,
	CGX_MODE_100G_CR4,
	CGX_MODE_100G_KR4,
	CGX_MODE_MAX /* = 29 */
};
/* REQUEST ID types. Input to firmware */
enum cgx_cmd_id {
	CGX_CMD_NONE,
@@ -75,12 +112,25 @@ enum cgx_cmd_id {
	CGX_CMD_INTERNAL_LBK,
	CGX_CMD_EXTERNAL_LBK,
	CGX_CMD_HIGIG,
	CGX_CMD_LINK_STATE_CHANGE,
	CGX_CMD_LINK_STAT_CHANGE,
	CGX_CMD_MODE_CHANGE,		/* hot plug support */
	CGX_CMD_INTF_SHUTDOWN,
	CGX_CMD_GET_MKEX_PRFL_SIZE,
	CGX_CMD_GET_MKEX_PRFL_ADDR,
	CGX_CMD_GET_FWD_BASE,		/* get base address of shared FW data */
	CGX_CMD_GET_LINK_MODES,		/* Supported Link Modes */
	CGX_CMD_SET_LINK_MODE,
	CGX_CMD_GET_SUPPORTED_FEC,
	CGX_CMD_SET_FEC,
	CGX_CMD_GET_AN,
	CGX_CMD_SET_AN,
	CGX_CMD_GET_ADV_LINK_MODES,
	CGX_CMD_GET_ADV_FEC,
	CGX_CMD_GET_PHY_MOD_TYPE, /* line-side modulation type: NRZ or PAM4 */
	CGX_CMD_SET_PHY_MOD_TYPE,
	CGX_CMD_PRBS,
	CGX_CMD_DISPLAY_EYE,
	CGX_CMD_GET_PHY_FEC_STATS,
};

/* async event ids */
@@ -171,13 +221,19 @@ struct cgx_lnk_sts {
	uint64_t full_duplex:1;
	uint64_t speed:4;		/* cgx_link_speed */
	uint64_t err_type:10;
	uint64_t reserved2:39;
	uint64_t an:1;			/* AN supported or not */
	uint64_t fec:2;			/* FEC type if enabled, if not 0 */
	uint64_t port:8;
	uint64_t reserved2:28;
};

#define RESP_LINKSTAT_UP		GENMASK_ULL(9, 9)
#define RESP_LINKSTAT_FDUPLEX		GENMASK_ULL(10, 10)
#define RESP_LINKSTAT_SPEED		GENMASK_ULL(14, 11)
#define RESP_LINKSTAT_ERRTYPE		GENMASK_ULL(24, 15)
#define RESP_LINKSTAT_AN		GENMASK_ULL(25, 25)
#define RESP_LINKSTAT_FEC		GENMASK_ULL(27, 26)
#define RESP_LINKSTAT_PORT		GENMASK_ULL(35, 28)

/* scratchx(1) CSR used for non-secure SW->ATF communication
 * This CSR acts as a command register
@@ -199,4 +255,12 @@ struct cgx_lnk_sts {
#define CMDLINKCHANGE_FULLDPLX	BIT_ULL(9)
#define CMDLINKCHANGE_SPEED	GENMASK_ULL(13, 10)

#define CMDSETFEC			GENMASK_ULL(9, 8)
/* command argument to be passed for cmd ID - CGX_CMD_MODE_CHANGE */
#define CMDMODECHANGE_SPEED		GENMASK_ULL(11, 8)
#define CMDMODECHANGE_DUPLEX		GENMASK_ULL(12, 12)
#define CMDMODECHANGE_AN		GENMASK_ULL(13, 13)
#define CMDMODECHANGE_PORT		GENMASK_ULL(21, 14)
#define CMDMODECHANGE_FLAGS		GENMASK_ULL(63, 22)

#endif /* __CGX_FW_INTF_H__ */
+88 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@

#define INTR_MASK(pfvfs) ((pfvfs < 64) ? (BIT_ULL(pfvfs) - 1) : (~0ull))

#define MBOX_RSP_TIMEOUT	2000 /* Time(ms) to wait for mbox response */
#define MBOX_RSP_TIMEOUT	3000 /* Time(ms) to wait for mbox response */

#define MBOX_MSG_ALIGN		16  /* Align mbox msg start to 16bytes */

@@ -149,6 +149,13 @@ M(CGX_PTP_RX_ENABLE, 0x20C, cgx_ptp_rx_enable, msg_req, msg_rsp) \
M(CGX_PTP_RX_DISABLE,	0x20D, cgx_ptp_rx_disable, msg_req, msg_rsp)	\
M(CGX_CFG_PAUSE_FRM,	0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg,	\
			       cgx_pause_frm_cfg)			\
M(CGX_FEC_SET,		0x210, cgx_set_fec_param, fec_mode, fec_mode)   \
M(CGX_FEC_STATS,	0x211, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \
M(CGX_GET_PHY_FEC_STATS, 0x212, cgx_get_phy_fec_stats, msg_req, msg_rsp) \
M(CGX_FW_DATA_GET,	0x213, cgx_get_aux_link_info, msg_req, cgx_fw_data) \
M(CGX_SET_LINK_MODE,	0x214, cgx_set_link_mode, cgx_set_link_mode_req,\
			       cgx_set_link_mode_rsp)	\
 /* NPA mbox IDs (range 0x400 - 0x5FF) */				\
/* NPA mbox IDs (range 0x400 - 0x5FF) */				\
M(NPA_LF_ALLOC,		0x400, npa_lf_alloc,				\
				npa_lf_alloc_req, npa_lf_alloc_rsp)	\
@@ -360,6 +367,11 @@ struct cgx_stats_rsp {
	u64 tx_stats[CGX_TX_STATS_COUNT];
};

struct cgx_fec_stats_rsp {
	struct mbox_msghdr hdr;
	u64 fec_corr_blks;
	u64 fec_uncorr_blks;
};
/* Structure for requesting the operation for
 * setting/getting mac address in the CGX interface
 */
@@ -373,6 +385,8 @@ struct cgx_link_user_info {
	uint64_t full_duplex:1;
	uint64_t lmac_type_id:4;
	uint64_t speed:20; /* speed in Mbps */
	uint64_t an:1;		/* AN supported or not */
	uint64_t fec:2;	 /* FEC type if enabled else 0 */
#define LMACTYPE_STR_LEN 16
	char lmac_type[LMACTYPE_STR_LEN];
};
@@ -391,6 +405,79 @@ struct cgx_pause_frm_cfg {
	u8 tx_pause;
};

enum fec_type {
	OTX2_FEC_NONE,
	OTX2_FEC_BASER,
	OTX2_FEC_RS,
	OTX2_FEC_STATS_CNT = 2,
	OTX2_FEC_OFF,
};

struct fec_mode {
	struct mbox_msghdr hdr;
	int fec;
};

struct sfp_eeprom_s {
#define SFP_EEPROM_SIZE 256
	u16 sff_id;
	u8 buf[SFP_EEPROM_SIZE];
	u64 reserved;
};

struct phy_s {
	struct {
		u64 can_change_mod_type:1;
		u64 mod_type:1;
		u64 has_fec_stats:1;
	} misc;
	struct fec_stats_s {
		u32 rsfec_corr_cws;
		u32 rsfec_uncorr_cws;
		u32 brfec_corr_blks;
		u32 brfec_uncorr_blks;
	} fec_stats;
};

struct cgx_lmac_fwdata_s {
	u16 rw_valid;
	u64 supported_fec;
	u64 supported_an;
	u64 supported_link_modes;
	/* only applicable if AN is supported */
	u64 advertised_fec;
	u64 advertised_link_modes;
	/* Only applicable if SFP/QSFP slot is present */
	struct sfp_eeprom_s sfp_eeprom;
	struct phy_s phy;
#define LMAC_FWDATA_RESERVED_MEM 1021
	u64 reserved[LMAC_FWDATA_RESERVED_MEM];
};

struct cgx_fw_data {
	struct mbox_msghdr hdr;
	struct cgx_lmac_fwdata_s fwdata;
};

struct cgx_set_link_mode_args {
	u32 speed;
	u8 duplex;
	u8 an;
	u8 ports;
	u64 mode;
};

struct cgx_set_link_mode_req {
#define AUTONEG_UNKNOWN		0xff
	struct mbox_msghdr hdr;
	struct cgx_set_link_mode_args args;
};

struct cgx_set_link_mode_rsp {
	struct mbox_msghdr hdr;
	int status;
};

/* NPA mbox message formats */

/* NPA mailbox error codes
+4 −0
Original line number Diff line number Diff line
@@ -357,6 +357,10 @@ struct rvu_fwdata {
	u64 msixtr_base;
#define FWDATA_RESERVED_MEM 1023
	u64 reserved[FWDATA_RESERVED_MEM];
#define CGX_MAX         5
#define CGX_LMACS_MAX   4
	struct cgx_lmac_fwdata_s cgx_fw_data[CGX_MAX][CGX_LMACS_MAX];
	/* Do not add new fields below this line */
};

struct ptp;
Loading