Commit 97791d3c authored by David S. Miller's avatar David S. Miller

Merge branch 'octeontx2-af-fixes'

Hariprasad Kelam says:

====================
octeontx2-af: MAC block fixes for CN10KB

This patch set contains fixes for the issues encountered in testing
CN10KB MAC block RPM_USX.

Patch1: firmware to kernel communication is not working due to wrong
        interrupt configuration. CSR addresses are corrected.

Patch2: NIX to RVU PF mapping errors encountered due to wrong firmware
        config. Corrects this mapping error.

Patch3: Driver is trying to access non exist cgx/lmac which is resulting
        in kernel panic. Address this issue by adding proper checks.

Patch4: MAC features are not getting reset on FLR. Fix the issue by
        resetting the stale config.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c97d3fb9 2e3e94c2
...@@ -169,6 +169,9 @@ void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val) ...@@ -169,6 +169,9 @@ void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val)
{ {
struct cgx *cgx_dev = cgx_get_pdata(cgx_id); struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
/* Software must not access disabled LMAC registers */
if (!is_lmac_valid(cgx_dev, lmac_id))
return;
cgx_write(cgx_dev, lmac_id, offset, val); cgx_write(cgx_dev, lmac_id, offset, val);
} }
...@@ -176,6 +179,10 @@ u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset) ...@@ -176,6 +179,10 @@ u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset)
{ {
struct cgx *cgx_dev = cgx_get_pdata(cgx_id); struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
/* Software must not access disabled LMAC registers */
if (!is_lmac_valid(cgx_dev, lmac_id))
return 0;
return cgx_read(cgx_dev, lmac_id, offset); return cgx_read(cgx_dev, lmac_id, offset);
} }
...@@ -530,14 +537,15 @@ static u32 cgx_get_lmac_fifo_len(void *cgxd, int lmac_id) ...@@ -530,14 +537,15 @@ static u32 cgx_get_lmac_fifo_len(void *cgxd, int lmac_id)
int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable) int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
{ {
struct cgx *cgx = cgxd; struct cgx *cgx = cgxd;
u8 lmac_type; struct lmac *lmac;
u64 cfg; u64 cfg;
if (!is_lmac_valid(cgx, lmac_id)) if (!is_lmac_valid(cgx, lmac_id))
return -ENODEV; return -ENODEV;
lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac_id); lmac = lmac_pdata(lmac_id, cgx);
if (lmac_type == LMAC_MODE_SGMII || lmac_type == LMAC_MODE_QSGMII) { if (lmac->lmac_type == LMAC_MODE_SGMII ||
lmac->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)
cfg |= CGXX_GMP_PCS_MRX_CTL_LBK; cfg |= CGXX_GMP_PCS_MRX_CTL_LBK;
...@@ -1556,6 +1564,23 @@ int cgx_lmac_linkup_start(void *cgxd) ...@@ -1556,6 +1564,23 @@ int cgx_lmac_linkup_start(void *cgxd)
return 0; return 0;
} }
int cgx_lmac_reset(void *cgxd, int lmac_id, u8 pf_req_flr)
{
struct cgx *cgx = cgxd;
u64 cfg;
if (!is_lmac_valid(cgx, lmac_id))
return -ENODEV;
/* Resetting PFC related CSRs */
cfg = 0xff;
cgx_write(cgxd, lmac_id, CGXX_CMRX_RX_LOGL_XON, cfg);
if (pf_req_flr)
cgx_lmac_internal_loopback(cgxd, lmac_id, false);
return 0;
}
static int cgx_configure_interrupt(struct cgx *cgx, struct lmac *lmac, static int cgx_configure_interrupt(struct cgx *cgx, struct lmac *lmac,
int cnt, bool req_free) int cnt, bool req_free)
{ {
...@@ -1675,6 +1700,7 @@ static int cgx_lmac_init(struct cgx *cgx) ...@@ -1675,6 +1700,7 @@ static int cgx_lmac_init(struct cgx *cgx)
cgx->lmac_idmap[lmac->lmac_id] = lmac; cgx->lmac_idmap[lmac->lmac_id] = lmac;
set_bit(lmac->lmac_id, &cgx->lmac_bmap); set_bit(lmac->lmac_id, &cgx->lmac_bmap);
cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, true); 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);
} }
return cgx_lmac_verify_fwi_version(cgx); return cgx_lmac_verify_fwi_version(cgx);
...@@ -1771,6 +1797,7 @@ static struct mac_ops cgx_mac_ops = { ...@@ -1771,6 +1797,7 @@ static struct mac_ops cgx_mac_ops = {
.mac_tx_enable = cgx_lmac_tx_enable, .mac_tx_enable = cgx_lmac_tx_enable,
.pfc_config = cgx_lmac_pfc_config, .pfc_config = cgx_lmac_pfc_config,
.mac_get_pfc_frm_cfg = cgx_lmac_get_pfc_frm_cfg, .mac_get_pfc_frm_cfg = cgx_lmac_get_pfc_frm_cfg,
.mac_reset = cgx_lmac_reset,
}; };
static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#define CGXX_CMRX_INT_ENA_W1S 0x058 #define CGXX_CMRX_INT_ENA_W1S 0x058
#define CGXX_CMRX_RX_ID_MAP 0x060 #define CGXX_CMRX_RX_ID_MAP 0x060
#define CGXX_CMRX_RX_STAT0 0x070 #define CGXX_CMRX_RX_STAT0 0x070
#define CGXX_CMRX_RX_LOGL_XON 0x100
#define CGXX_CMRX_RX_LMACS 0x128 #define CGXX_CMRX_RX_LMACS 0x128
#define CGXX_CMRX_RX_DMAC_CTL0 (0x1F8 + mac_ops->csr_offset) #define CGXX_CMRX_RX_DMAC_CTL0 (0x1F8 + mac_ops->csr_offset)
#define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3) #define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3)
...@@ -181,4 +182,5 @@ int cgx_lmac_get_pfc_frm_cfg(void *cgxd, int lmac_id, u8 *tx_pause, ...@@ -181,4 +182,5 @@ int cgx_lmac_get_pfc_frm_cfg(void *cgxd, int lmac_id, u8 *tx_pause,
u8 *rx_pause); u8 *rx_pause);
int verify_lmac_fc_cfg(void *cgxd, int lmac_id, u8 tx_pause, u8 rx_pause, int verify_lmac_fc_cfg(void *cgxd, int lmac_id, u8 tx_pause, u8 rx_pause,
int pfvf_idx); int pfvf_idx);
int cgx_lmac_reset(void *cgxd, int lmac_id, u8 pf_req_flr);
#endif /* CGX_H */ #endif /* CGX_H */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
* @cgx: parent cgx port * @cgx: parent cgx port
* @mcast_filters_count: Number of multicast filters installed * @mcast_filters_count: Number of multicast filters installed
* @lmac_id: lmac port id * @lmac_id: lmac port id
* @lmac_type: lmac type like SGMII/XAUI
* @cmd_pend: flag set before new command is started * @cmd_pend: flag set before new command is started
* flag cleared after command response is received * flag cleared after command response is received
* @name: lmac port name * @name: lmac port name
...@@ -43,6 +44,7 @@ struct lmac { ...@@ -43,6 +44,7 @@ struct lmac {
struct cgx *cgx; struct cgx *cgx;
u8 mcast_filters_count; u8 mcast_filters_count;
u8 lmac_id; u8 lmac_id;
u8 lmac_type;
bool cmd_pend; bool cmd_pend;
char *name; char *name;
}; };
...@@ -125,6 +127,7 @@ struct mac_ops { ...@@ -125,6 +127,7 @@ struct mac_ops {
int (*mac_get_pfc_frm_cfg)(void *cgxd, int lmac_id, int (*mac_get_pfc_frm_cfg)(void *cgxd, int lmac_id,
u8 *tx_pause, u8 *rx_pause); u8 *tx_pause, u8 *rx_pause);
int (*mac_reset)(void *cgxd, int lmac_id, u8 pf_req_flr);
/* FEC stats */ /* FEC stats */
int (*get_fec_stats)(void *cgxd, int lmac_id, int (*get_fec_stats)(void *cgxd, int lmac_id,
......
...@@ -37,6 +37,7 @@ static struct mac_ops rpm_mac_ops = { ...@@ -37,6 +37,7 @@ static struct mac_ops rpm_mac_ops = {
.mac_tx_enable = rpm_lmac_tx_enable, .mac_tx_enable = rpm_lmac_tx_enable,
.pfc_config = rpm_lmac_pfc_config, .pfc_config = rpm_lmac_pfc_config,
.mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg,
.mac_reset = rpm_lmac_reset,
}; };
static struct mac_ops rpm2_mac_ops = { static struct mac_ops rpm2_mac_ops = {
...@@ -47,7 +48,7 @@ static struct mac_ops rpm2_mac_ops = { ...@@ -47,7 +48,7 @@ static struct mac_ops rpm2_mac_ops = {
.int_set_reg = RPM2_CMRX_SW_INT_ENA_W1S, .int_set_reg = RPM2_CMRX_SW_INT_ENA_W1S,
.irq_offset = 1, .irq_offset = 1,
.int_ena_bit = BIT_ULL(0), .int_ena_bit = BIT_ULL(0),
.lmac_fwi = RPM_LMAC_FWI, .lmac_fwi = RPM2_LMAC_FWI,
.non_contiguous_serdes_lane = true, .non_contiguous_serdes_lane = true,
.rx_stats_cnt = 43, .rx_stats_cnt = 43,
.tx_stats_cnt = 34, .tx_stats_cnt = 34,
...@@ -68,6 +69,7 @@ static struct mac_ops rpm2_mac_ops = { ...@@ -68,6 +69,7 @@ static struct mac_ops rpm2_mac_ops = {
.mac_tx_enable = rpm_lmac_tx_enable, .mac_tx_enable = rpm_lmac_tx_enable,
.pfc_config = rpm_lmac_pfc_config, .pfc_config = rpm_lmac_pfc_config,
.mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg,
.mac_reset = rpm_lmac_reset,
}; };
bool is_dev_rpm2(void *rpmd) bool is_dev_rpm2(void *rpmd)
...@@ -537,14 +539,15 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id) ...@@ -537,14 +539,15 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id)
int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable) int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable)
{ {
rpm_t *rpm = rpmd; rpm_t *rpm = rpmd;
u8 lmac_type; struct lmac *lmac;
u64 cfg; u64 cfg;
if (!is_lmac_valid(rpm, lmac_id)) if (!is_lmac_valid(rpm, lmac_id))
return -ENODEV; return -ENODEV;
lmac_type = rpm->mac_ops->get_lmac_type(rpm, lmac_id);
if (lmac_type == LMAC_MODE_QSGMII || lmac_type == LMAC_MODE_SGMII) { lmac = lmac_pdata(lmac_id, rpm);
if (lmac->lmac_type == LMAC_MODE_QSGMII ||
lmac->lmac_type == LMAC_MODE_SGMII) {
dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n"); dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n");
return 0; return 0;
} }
...@@ -713,3 +716,24 @@ int rpm_get_fec_stats(void *rpmd, int lmac_id, struct cgx_fec_stats_rsp *rsp) ...@@ -713,3 +716,24 @@ int rpm_get_fec_stats(void *rpmd, int lmac_id, struct cgx_fec_stats_rsp *rsp)
return 0; return 0;
} }
int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr)
{
u64 rx_logl_xon, cfg;
rpm_t *rpm = rpmd;
if (!is_lmac_valid(rpm, lmac_id))
return -ENODEV;
/* Resetting PFC related CSRs */
rx_logl_xon = is_dev_rpm2(rpm) ? RPM2_CMRX_RX_LOGL_XON :
RPMX_CMRX_RX_LOGL_XON;
cfg = 0xff;
rpm_write(rpm, lmac_id, rx_logl_xon, cfg);
if (pf_req_flr)
rpm_lmac_internal_loopback(rpm, lmac_id, false);
return 0;
}
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#define RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA 0x80A8 #define RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA 0x80A8
#define RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA 0x8108 #define RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA 0x8108
#define RPM_DEFAULT_PAUSE_TIME 0x7FF #define RPM_DEFAULT_PAUSE_TIME 0x7FF
#define RPMX_CMRX_RX_LOGL_XON 0x4100
#define RPMX_MTI_MAC100X_XIF_MODE 0x8100 #define RPMX_MTI_MAC100X_XIF_MODE 0x8100
#define RPMX_ONESTEP_ENABLE BIT_ULL(5) #define RPMX_ONESTEP_ENABLE BIT_ULL(5)
...@@ -94,7 +95,8 @@ ...@@ -94,7 +95,8 @@
/* CN10KB CSR Declaration */ /* CN10KB CSR Declaration */
#define RPM2_CMRX_SW_INT 0x1b0 #define RPM2_CMRX_SW_INT 0x1b0
#define RPM2_CMRX_SW_INT_ENA_W1S 0x1b8 #define RPM2_CMRX_SW_INT_ENA_W1S 0x1c8
#define RPM2_LMAC_FWI 0x12
#define RPM2_CMR_CHAN_MSK_OR 0x3120 #define RPM2_CMR_CHAN_MSK_OR 0x3120
#define RPM2_CMR_RX_OVR_BP_EN BIT_ULL(2) #define RPM2_CMR_RX_OVR_BP_EN BIT_ULL(2)
#define RPM2_CMR_RX_OVR_BP_BP BIT_ULL(1) #define RPM2_CMR_RX_OVR_BP_BP BIT_ULL(1)
...@@ -131,4 +133,5 @@ int rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause, ...@@ -131,4 +133,5 @@ int rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause,
int rpm2_get_nr_lmacs(void *rpmd); int rpm2_get_nr_lmacs(void *rpmd);
bool is_dev_rpm2(void *rpmd); bool is_dev_rpm2(void *rpmd);
int rpm_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp); int rpm_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr);
#endif /* RPM_H */ #endif /* RPM_H */
...@@ -2629,6 +2629,7 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc) ...@@ -2629,6 +2629,7 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc)
* Since LF is detached use LF number as -1. * Since LF is detached use LF number as -1.
*/ */
rvu_npc_free_mcam_entries(rvu, pcifunc, -1); rvu_npc_free_mcam_entries(rvu, pcifunc, -1);
rvu_mac_reset(rvu, pcifunc);
mutex_unlock(&rvu->flr_lock); mutex_unlock(&rvu->flr_lock);
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define PCI_DEVID_OCTEONTX2_LBK 0xA061 #define PCI_DEVID_OCTEONTX2_LBK 0xA061
/* Subsystem Device ID */ /* Subsystem Device ID */
#define PCI_SUBSYS_DEVID_98XX 0xB100
#define PCI_SUBSYS_DEVID_96XX 0xB200 #define PCI_SUBSYS_DEVID_96XX 0xB200
#define PCI_SUBSYS_DEVID_CN10K_A 0xB900 #define PCI_SUBSYS_DEVID_CN10K_A 0xB900
#define PCI_SUBSYS_DEVID_CNF10K_B 0xBC00 #define PCI_SUBSYS_DEVID_CNF10K_B 0xBC00
...@@ -686,6 +687,16 @@ static inline u16 rvu_nix_chan_cpt(struct rvu *rvu, u8 chan) ...@@ -686,6 +687,16 @@ static inline u16 rvu_nix_chan_cpt(struct rvu *rvu, u8 chan)
return rvu->hw->cpt_chan_base + chan; return rvu->hw->cpt_chan_base + chan;
} }
static inline bool is_rvu_supports_nix1(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
if (pdev->subsystem_device == PCI_SUBSYS_DEVID_98XX)
return true;
return false;
}
/* Function Prototypes /* Function Prototypes
* RVU * RVU
*/ */
...@@ -884,6 +895,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable); ...@@ -884,6 +895,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable);
int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause, int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause,
u16 pfc_en); u16 pfc_en);
int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause); int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);
void rvu_mac_reset(struct rvu *rvu, u16 pcifunc);
u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac); u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf, int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
int type); int type);
......
...@@ -114,7 +114,7 @@ static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf, ...@@ -114,7 +114,7 @@ static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,
p2x = cgx_lmac_get_p2x(cgx_id, lmac_id); p2x = cgx_lmac_get_p2x(cgx_id, lmac_id);
/* Firmware sets P2X_SELECT as either NIX0 or NIX1 */ /* Firmware sets P2X_SELECT as either NIX0 or NIX1 */
pfvf->nix_blkaddr = BLKADDR_NIX0; pfvf->nix_blkaddr = BLKADDR_NIX0;
if (p2x == CMR_P2X_SEL_NIX1) if (is_rvu_supports_nix1(rvu) && p2x == CMR_P2X_SEL_NIX1)
pfvf->nix_blkaddr = BLKADDR_NIX1; pfvf->nix_blkaddr = BLKADDR_NIX1;
} }
...@@ -1250,3 +1250,21 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, ...@@ -1250,3 +1250,21 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause); mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause);
return err; return err;
} }
void rvu_mac_reset(struct rvu *rvu, u16 pcifunc)
{
int pf = rvu_get_pf(pcifunc);
struct mac_ops *mac_ops;
struct cgx *cgxd;
u8 cgx, lmac;
if (!is_pf_cgxmapped(rvu, pf))
return;
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx, &lmac);
cgxd = rvu_cgx_pdata(cgx, rvu);
mac_ops = get_mac_ops(cgxd);
if (mac_ops->mac_reset(cgxd, lmac, !is_vf(pcifunc)))
dev_err(rvu->dev, "Failed to reset MAC\n");
}
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