octeontx2-af: forward error correction configuration
CGX block supports forward error correction modes baseR and RS. This patch adds support to set encoding mode and to read corrected/uncorrected block counters Adds new mailbox handlers set_fec to configure encoding modes and fec_stats to read counters and also increase mbox timeout to accomdate firmware command response timeout. Along with new CGX_CMD_SET_FEC command add other commands to sync with kernel enum list with firmware. Signed-off-by: Christina Jacob <cjacob@marvell.com> Signed-off-by: Sunil Goutham <sgoutham@marvell.com> Signed-off-by: Hariprasad Kelam <hkelam@marvell.com> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1fb3ca7675
commit
84c4f9cab4
@ -340,6 +340,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;
|
||||
@ -615,6 +669,7 @@ 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->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);
|
||||
@ -785,6 +840,27 @@ int cgx_get_fwdata_base(u64 *base)
|
||||
return err;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable)
|
||||
{
|
||||
u64 req = 0;
|
||||
|
@ -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,7 @@ 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);
|
||||
|
||||
#endif /* CGX_H */
|
||||
|
@ -81,6 +81,14 @@ enum cgx_cmd_id {
|
||||
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,
|
||||
};
|
||||
|
||||
/* async event ids */
|
||||
@ -171,13 +179,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 +213,5 @@ struct cgx_lnk_sts {
|
||||
#define CMDLINKCHANGE_FULLDPLX BIT_ULL(9)
|
||||
#define CMDLINKCHANGE_SPEED GENMASK_ULL(13, 10)
|
||||
|
||||
#define CMDSETFEC GENMASK_ULL(9, 8)
|
||||
#endif /* __CGX_FW_INTF_H__ */
|
||||
|
@ -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,9 @@ 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) \
|
||||
/* 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 +363,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 +381,7 @@ 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 fec:2; /* FEC type if enabled else 0 */
|
||||
#define LMACTYPE_STR_LEN 16
|
||||
char lmac_type[LMACTYPE_STR_LEN];
|
||||
};
|
||||
@ -391,6 +400,19 @@ 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;
|
||||
};
|
||||
|
||||
/* NPA mbox message formats */
|
||||
|
||||
/* NPA mailbox error codes
|
||||
|
@ -462,6 +462,22 @@ int rvu_mbox_handler_cgx_stats(struct rvu *rvu, struct msg_req *req,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
|
||||
struct msg_req *req,
|
||||
struct cgx_fec_stats_rsp *rsp)
|
||||
{
|
||||
int pf = rvu_get_pf(req->hdr.pcifunc);
|
||||
u8 cgx_idx, lmac;
|
||||
void *cgxd;
|
||||
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return -EPERM;
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
|
||||
|
||||
cgxd = rvu_cgx_pdata(cgx_idx, rvu);
|
||||
return cgx_get_fec_stats(cgxd, lmac, rsp);
|
||||
}
|
||||
|
||||
int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
|
||||
struct cgx_mac_addr_set_or_get *req,
|
||||
struct cgx_mac_addr_set_or_get *rsp)
|
||||
@ -767,3 +783,20 @@ exit:
|
||||
mutex_unlock(&rvu->cgx_cfg_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
|
||||
struct fec_mode *req,
|
||||
struct fec_mode *rsp)
|
||||
{
|
||||
int pf = rvu_get_pf(req->hdr.pcifunc);
|
||||
u8 cgx_id, lmac_id;
|
||||
|
||||
if (!is_pf_cgxmapped(rvu, pf))
|
||||
return -EPERM;
|
||||
|
||||
if (req->fec == OTX2_FEC_OFF)
|
||||
req->fec = OTX2_FEC_NONE;
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user