Skip to content

Commit

Permalink
octeontx2-af: forward error correction configuration
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christina Jacob authored and David S. Miller committed Feb 10, 2021
1 parent 1fb3ca7 commit 84c4f9c
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 2 deletions.
76 changes: 76 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/cgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/cgx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
17 changes: 16 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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__ */
24 changes: 23 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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) \
Expand Down Expand Up @@ -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
*/
Expand All @@ -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];
};
Expand All @@ -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
Expand Down
33 changes: 33 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -767,3 +783,20 @@ int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
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;
}

0 comments on commit 84c4f9c

Please sign in to comment.