Commit 3ad3f8f9 authored by Hariprasad Kelam's avatar Hariprasad Kelam Committed by David S. Miller

octeontx2-af: cn10k: MAC internal loopback support

MAC on CN10K silicon support loopback for selftest or debug purposes.
This patch does necessary configuration to loopback packets upon receiving
request from LMAC mapped RVU PF's netdev via mailbox.

Also MAC (CGX) on OcteonTx2 silicon variants and MAC (RPM) on
OcteonTx3 CN10K are different and loopback needs to be configured
differently. Upper layer interface between RVU AF and PF netdev is
kept same. Based on silicon variant appropriate fn() pointer is
called to config the MAC.
Signed-off-by: default avatarHariprasad Kelam <hkelam@marvell.com>
Signed-off-by: default avatarGeetha sowjanya <gakula@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce7a6c31
...@@ -229,8 +229,9 @@ int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind) ...@@ -229,8 +229,9 @@ int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind)
return 0; return 0;
} }
static inline u8 cgx_get_lmac_type(struct cgx *cgx, int lmac_id) static u8 cgx_get_lmac_type(void *cgxd, int lmac_id)
{ {
struct cgx *cgx = cgxd;
u64 cfg; u64 cfg;
cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG); cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
...@@ -247,7 +248,7 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable) ...@@ -247,7 +248,7 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
if (!is_lmac_valid(cgx, lmac_id)) if (!is_lmac_valid(cgx, lmac_id))
return -ENODEV; return -ENODEV;
lmac_type = cgx_get_lmac_type(cgx, lmac_id); lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac_id);
if (lmac_type == LMAC_MODE_SGMII || lmac_type == LMAC_MODE_QSGMII) { if (lmac_type == LMAC_MODE_SGMII || lmac_type == LMAC_MODE_QSGMII) {
cfg = cgx_read(cgx, lmac_id, CGXX_GMP_PCS_MRX_CTL); cfg = cgx_read(cgx, lmac_id, CGXX_GMP_PCS_MRX_CTL);
if (enable) if (enable)
...@@ -1302,6 +1303,8 @@ static struct mac_ops cgx_mac_ops = { ...@@ -1302,6 +1303,8 @@ static struct mac_ops cgx_mac_ops = {
.rx_stats_cnt = 9, .rx_stats_cnt = 9,
.tx_stats_cnt = 18, .tx_stats_cnt = 18,
.get_nr_lmacs = cgx_get_nr_lmacs, .get_nr_lmacs = cgx_get_nr_lmacs,
.get_lmac_type = cgx_get_lmac_type,
.mac_lmac_intl_lbk = cgx_lmac_internal_loopback,
.mac_get_rx_stats = cgx_get_rx_stats, .mac_get_rx_stats = cgx_get_rx_stats,
.mac_get_tx_stats = cgx_get_tx_stats, .mac_get_tx_stats = cgx_get_tx_stats,
.mac_enadis_rx_pause_fwding = cgx_lmac_enadis_rx_pause_fwding, .mac_enadis_rx_pause_fwding = cgx_lmac_enadis_rx_pause_fwding,
......
...@@ -204,6 +204,7 @@ enum cgx_cmd_own { ...@@ -204,6 +204,7 @@ enum cgx_cmd_own {
* CGX_STAT_SUCCESS * CGX_STAT_SUCCESS
*/ */
#define RESP_FWD_BASE GENMASK_ULL(56, 9) #define RESP_FWD_BASE GENMASK_ULL(56, 9)
#define RESP_LINKSTAT_LMAC_TYPE GENMASK_ULL(35, 28)
/* Response to cmd ID - CGX_CMD_LINK_BRING_UP/DOWN, event ID CGX_EVT_LINK_CHANGE /* Response to cmd ID - CGX_CMD_LINK_BRING_UP/DOWN, event ID CGX_EVT_LINK_CHANGE
* status can be either CGX_STAT_FAIL or CGX_STAT_SUCCESS * status can be either CGX_STAT_FAIL or CGX_STAT_SUCCESS
......
...@@ -70,7 +70,9 @@ struct mac_ops { ...@@ -70,7 +70,9 @@ struct mac_ops {
* number of setbits in lmac_exist tells number of lmacs * number of setbits in lmac_exist tells number of lmacs
*/ */
int (*get_nr_lmacs)(void *cgx); int (*get_nr_lmacs)(void *cgx);
u8 (*get_lmac_type)(void *cgx, int lmac_id);
int (*mac_lmac_intl_lbk)(void *cgx, int lmac_id,
bool enable);
/* Register Stats related functions */ /* Register Stats related functions */
int (*mac_get_rx_stats)(void *cgx, int lmac_id, int (*mac_get_rx_stats)(void *cgx, int lmac_id,
int idx, u64 *rx_stat); int idx, u64 *rx_stat);
......
...@@ -21,6 +21,8 @@ static struct mac_ops rpm_mac_ops = { ...@@ -21,6 +21,8 @@ static struct mac_ops rpm_mac_ops = {
.rx_stats_cnt = 43, .rx_stats_cnt = 43,
.tx_stats_cnt = 34, .tx_stats_cnt = 34,
.get_nr_lmacs = rpm_get_nr_lmacs, .get_nr_lmacs = rpm_get_nr_lmacs,
.get_lmac_type = rpm_get_lmac_type,
.mac_lmac_intl_lbk = rpm_lmac_internal_loopback,
.mac_get_rx_stats = rpm_get_rx_stats, .mac_get_rx_stats = rpm_get_rx_stats,
.mac_get_tx_stats = rpm_get_tx_stats, .mac_get_tx_stats = rpm_get_tx_stats,
.mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding,
...@@ -226,3 +228,45 @@ int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat) ...@@ -226,3 +228,45 @@ int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat)
mutex_unlock(&rpm->lock); mutex_unlock(&rpm->lock);
return 0; return 0;
} }
u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
{
rpm_t *rpm = rpmd;
u64 req = 0, resp;
int err;
req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req);
err = cgx_fwi_cmd_generic(req, &resp, rpm, 0);
if (!err)
return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp);
return err;
}
int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable)
{
rpm_t *rpm = rpmd;
u8 lmac_type;
u64 cfg;
if (!rpm || lmac_id >= rpm->lmac_count)
return -ENODEV;
lmac_type = rpm->mac_ops->get_lmac_type(rpm, lmac_id);
if (lmac_type == LMAC_MODE_100G_R) {
cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1);
if (enable)
cfg |= RPMX_MTI_PCS_LBK;
else
cfg &= ~RPMX_MTI_PCS_LBK;
rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg);
} else {
cfg = rpm_read(rpm, lmac_id, RPMX_MTI_LPCSX_CONTROL1);
if (enable)
cfg |= RPMX_MTI_PCS_LBK;
else
cfg &= ~RPMX_MTI_PCS_LBK;
rpm_write(rpm, lmac_id, RPMX_MTI_LPCSX_CONTROL1, cfg);
}
return 0;
}
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#define RPMX_CMRX_SW_INT_W1S 0x188 #define RPMX_CMRX_SW_INT_W1S 0x188
#define RPMX_CMRX_SW_INT_ENA_W1S 0x198 #define RPMX_CMRX_SW_INT_ENA_W1S 0x198
#define RPMX_CMRX_LINK_CFG 0x1070 #define RPMX_CMRX_LINK_CFG 0x1070
#define RPMX_MTI_PCS100X_CONTROL1 0x20000
#define RPMX_MTI_LPCSX_CONTROL1 0x30000
#define RPMX_MTI_PCS_LBK BIT_ULL(14)
#define RPMX_MTI_LPCSX_CONTROL(id) (0x30000 | ((id) * 0x100)) #define RPMX_MTI_LPCSX_CONTROL(id) (0x30000 | ((id) * 0x100))
#define RPMX_CMRX_LINK_RANGE_MASK GENMASK_ULL(19, 16) #define RPMX_CMRX_LINK_RANGE_MASK GENMASK_ULL(19, 16)
...@@ -41,6 +44,8 @@ ...@@ -41,6 +44,8 @@
/* Function Declarations */ /* Function Declarations */
int rpm_get_nr_lmacs(void *rpmd); int rpm_get_nr_lmacs(void *rpmd);
u8 rpm_get_lmac_type(void *rpmd, int lmac_id);
int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable);
void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable); void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable);
int rpm_lmac_get_pause_frm_status(void *cgxd, int lmac_id, u8 *tx_pause, int rpm_lmac_get_pause_frm_status(void *cgxd, int lmac_id, u8 *tx_pause,
u8 *rx_pause); u8 *rx_pause);
......
...@@ -722,15 +722,15 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu) ...@@ -722,15 +722,15 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu)
static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en) static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
{ {
int pf = rvu_get_pf(pcifunc); struct mac_ops *mac_ops;
u8 cgx_id, lmac_id; u8 cgx_id, lmac_id;
if (!is_cgx_config_permitted(rvu, pcifunc)) if (!is_cgx_config_permitted(rvu, pcifunc))
return -EPERM; return -EPERM;
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); mac_ops = get_mac_ops(rvu_cgx_pdata(cgx_id, rvu));
return cgx_lmac_internal_loopback(rvu_cgx_pdata(cgx_id, rvu), return mac_ops->mac_lmac_intl_lbk(rvu_cgx_pdata(cgx_id, rvu),
lmac_id, en); lmac_id, en);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment