Commit 809159ee authored by David S. Miller's avatar David S. Miller

Merge branch 'octeontx2-misc-fixes'

Sunil Goutham says:

====================
octeontx2: Miscellaneous fixes

This patch series contains a bunch of miscellaneous fixes
for various issues like
- Free unallocated memory during driver unload
- HW reading transmit descriptor from wrong address
- VF VLAN strip offload MCAM entry installation failure
- Pkts not being distributed across queues in RSS context
- Wrong interface backpressure configuration for NIX1 block on 98xx
- etc
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5d1c5594 623da5ca
...@@ -64,8 +64,8 @@ static inline int qmem_alloc(struct device *dev, struct qmem **q, ...@@ -64,8 +64,8 @@ static inline int qmem_alloc(struct device *dev, struct qmem **q,
qmem->entry_sz = entry_sz; qmem->entry_sz = entry_sz;
qmem->alloc_sz = (qsize * entry_sz) + OTX2_ALIGN; qmem->alloc_sz = (qsize * entry_sz) + OTX2_ALIGN;
qmem->base = dma_alloc_coherent(dev, qmem->alloc_sz, qmem->base = dma_alloc_attrs(dev, qmem->alloc_sz, &qmem->iova,
&qmem->iova, GFP_KERNEL); GFP_KERNEL, DMA_ATTR_FORCE_CONTIGUOUS);
if (!qmem->base) if (!qmem->base)
return -ENOMEM; return -ENOMEM;
...@@ -84,9 +84,10 @@ static inline void qmem_free(struct device *dev, struct qmem *qmem) ...@@ -84,9 +84,10 @@ static inline void qmem_free(struct device *dev, struct qmem *qmem)
return; return;
if (qmem->base) if (qmem->base)
dma_free_coherent(dev, qmem->alloc_sz, dma_free_attrs(dev, qmem->alloc_sz,
qmem->base - qmem->align, qmem->base - qmem->align,
qmem->iova - qmem->align); qmem->iova - qmem->align,
DMA_ATTR_FORCE_CONTIGUOUS);
devm_kfree(dev, qmem); devm_kfree(dev, qmem);
} }
...@@ -192,8 +193,6 @@ enum nix_scheduler { ...@@ -192,8 +193,6 @@ enum nix_scheduler {
#define NIX_CHAN_LBK_CHX(a, b) (0 + 0x100 * (a) + (b)) #define NIX_CHAN_LBK_CHX(a, b) (0 + 0x100 * (a) + (b))
#define NIX_CHAN_SDP_CH_START (0x700ull) #define NIX_CHAN_SDP_CH_START (0x700ull)
#define SDP_CHANNELS 256
/* The mask is to extract lower 10-bits of channel number /* The mask is to extract lower 10-bits of channel number
* which CPT will pass to X2P. * which CPT will pass to X2P.
*/ */
......
...@@ -498,12 +498,15 @@ int rvu_lf_reset(struct rvu *rvu, struct rvu_block *block, int lf) ...@@ -498,12 +498,15 @@ int rvu_lf_reset(struct rvu *rvu, struct rvu_block *block, int lf)
static void rvu_block_reset(struct rvu *rvu, int blkaddr, u64 rst_reg) static void rvu_block_reset(struct rvu *rvu, int blkaddr, u64 rst_reg)
{ {
struct rvu_block *block = &rvu->hw->block[blkaddr]; struct rvu_block *block = &rvu->hw->block[blkaddr];
int err;
if (!block->implemented) if (!block->implemented)
return; return;
rvu_write64(rvu, blkaddr, rst_reg, BIT_ULL(0)); rvu_write64(rvu, blkaddr, rst_reg, BIT_ULL(0));
rvu_poll_reg(rvu, blkaddr, rst_reg, BIT_ULL(63), true); err = rvu_poll_reg(rvu, blkaddr, rst_reg, BIT_ULL(63), true);
if (err)
dev_err(rvu->dev, "HW block:%d reset failed\n", blkaddr);
} }
static void rvu_reset_all_blocks(struct rvu *rvu) static void rvu_reset_all_blocks(struct rvu *rvu)
......
...@@ -82,10 +82,10 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc, ...@@ -82,10 +82,10 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val); dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
return -EIO; return -EIO;
} }
/* PA[51:12] = RVU_AF_SMMU_TLN_FLIT1[60:21] /* PA[51:12] = RVU_AF_SMMU_TLN_FLIT0[57:18]
* PA[11:0] = IOVA[11:0] * PA[11:0] = IOVA[11:0]
*/ */
pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT1) >> 21; pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT0) >> 18;
pa &= GENMASK_ULL(39, 0); pa &= GENMASK_ULL(39, 0);
*lmt_addr = (pa << 12) | (iova & 0xFFF); *lmt_addr = (pa << 12) | (iova & 0xFFF);
...@@ -212,9 +212,10 @@ void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc) ...@@ -212,9 +212,10 @@ void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc)
int rvu_set_channels_base(struct rvu *rvu) int rvu_set_channels_base(struct rvu *rvu)
{ {
u16 nr_lbk_chans, nr_sdp_chans, nr_cgx_chans, nr_cpt_chans;
u16 sdp_chan_base, cgx_chan_base, cpt_chan_base;
struct rvu_hwinfo *hw = rvu->hw; struct rvu_hwinfo *hw = rvu->hw;
u16 cpt_chan_base; u64 nix_const, nix_const1;
u64 nix_const;
int blkaddr; int blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0); blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
...@@ -222,6 +223,7 @@ int rvu_set_channels_base(struct rvu *rvu) ...@@ -222,6 +223,7 @@ int rvu_set_channels_base(struct rvu *rvu)
return blkaddr; return blkaddr;
nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST); nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
nix_const1 = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
hw->cgx = (nix_const >> 12) & 0xFULL; hw->cgx = (nix_const >> 12) & 0xFULL;
hw->lmac_per_cgx = (nix_const >> 8) & 0xFULL; hw->lmac_per_cgx = (nix_const >> 8) & 0xFULL;
...@@ -244,14 +246,24 @@ int rvu_set_channels_base(struct rvu *rvu) ...@@ -244,14 +246,24 @@ int rvu_set_channels_base(struct rvu *rvu)
* channels such that all channel numbers are contiguous * channels such that all channel numbers are contiguous
* leaving no holes. This way the new CPT channels can be * leaving no holes. This way the new CPT channels can be
* accomodated. The order of channel numbers assigned is * accomodated. The order of channel numbers assigned is
* LBK, SDP, CGX and CPT. * LBK, SDP, CGX and CPT. Also the base channel number
* of a block must be multiple of number of channels
* of the block.
*/ */
hw->sdp_chan_base = hw->lbk_chan_base + hw->lbk_links * nr_lbk_chans = (nix_const >> 16) & 0xFFULL;
((nix_const >> 16) & 0xFFULL); nr_sdp_chans = nix_const1 & 0xFFFULL;
hw->cgx_chan_base = hw->sdp_chan_base + hw->sdp_links * SDP_CHANNELS; nr_cgx_chans = nix_const & 0xFFULL;
nr_cpt_chans = (nix_const >> 32) & 0xFFFULL;
cpt_chan_base = hw->cgx_chan_base + hw->cgx_links * sdp_chan_base = hw->lbk_chan_base + hw->lbk_links * nr_lbk_chans;
(nix_const & 0xFFULL); /* Round up base channel to multiple of number of channels */
hw->sdp_chan_base = ALIGN(sdp_chan_base, nr_sdp_chans);
cgx_chan_base = hw->sdp_chan_base + hw->sdp_links * nr_sdp_chans;
hw->cgx_chan_base = ALIGN(cgx_chan_base, nr_cgx_chans);
cpt_chan_base = hw->cgx_chan_base + hw->cgx_links * nr_cgx_chans;
hw->cpt_chan_base = ALIGN(cpt_chan_base, nr_cpt_chans);
/* Out of 4096 channels start CPT from 2048 so /* Out of 4096 channels start CPT from 2048 so
* that MSB for CPT channels is always set * that MSB for CPT channels is always set
...@@ -355,6 +367,7 @@ static void rvu_lbk_set_channels(struct rvu *rvu) ...@@ -355,6 +367,7 @@ static void rvu_lbk_set_channels(struct rvu *rvu)
static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr) static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr)
{ {
u64 nix_const1 = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
u64 nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST); u64 nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
u16 cgx_chans, lbk_chans, sdp_chans, cpt_chans; u16 cgx_chans, lbk_chans, sdp_chans, cpt_chans;
struct rvu_hwinfo *hw = rvu->hw; struct rvu_hwinfo *hw = rvu->hw;
...@@ -364,7 +377,7 @@ static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr) ...@@ -364,7 +377,7 @@ static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr)
cgx_chans = nix_const & 0xFFULL; cgx_chans = nix_const & 0xFFULL;
lbk_chans = (nix_const >> 16) & 0xFFULL; lbk_chans = (nix_const >> 16) & 0xFFULL;
sdp_chans = SDP_CHANNELS; sdp_chans = nix_const1 & 0xFFFULL;
cpt_chans = (nix_const >> 32) & 0xFFFULL; cpt_chans = (nix_const >> 32) & 0xFFFULL;
start = hw->cgx_chan_base; start = hw->cgx_chan_base;
......
...@@ -25,7 +25,7 @@ static int nix_update_mce_rule(struct rvu *rvu, u16 pcifunc, ...@@ -25,7 +25,7 @@ static int nix_update_mce_rule(struct rvu *rvu, u16 pcifunc,
int type, bool add); int type, bool add);
static int nix_setup_ipolicers(struct rvu *rvu, static int nix_setup_ipolicers(struct rvu *rvu,
struct nix_hw *nix_hw, int blkaddr); struct nix_hw *nix_hw, int blkaddr);
static void nix_ipolicer_freemem(struct nix_hw *nix_hw); static void nix_ipolicer_freemem(struct rvu *rvu, struct nix_hw *nix_hw);
static int nix_verify_bandprof(struct nix_cn10k_aq_enq_req *req, static int nix_verify_bandprof(struct nix_cn10k_aq_enq_req *req,
struct nix_hw *nix_hw, u16 pcifunc); struct nix_hw *nix_hw, u16 pcifunc);
static int nix_free_all_bandprof(struct rvu *rvu, u16 pcifunc); static int nix_free_all_bandprof(struct rvu *rvu, u16 pcifunc);
...@@ -3965,7 +3965,7 @@ static void rvu_nix_block_freemem(struct rvu *rvu, int blkaddr, ...@@ -3965,7 +3965,7 @@ static void rvu_nix_block_freemem(struct rvu *rvu, int blkaddr,
kfree(txsch->schq.bmap); kfree(txsch->schq.bmap);
} }
nix_ipolicer_freemem(nix_hw); nix_ipolicer_freemem(rvu, nix_hw);
vlan = &nix_hw->txvlan; vlan = &nix_hw->txvlan;
kfree(vlan->rsrc.bmap); kfree(vlan->rsrc.bmap);
...@@ -4341,11 +4341,14 @@ static int nix_setup_ipolicers(struct rvu *rvu, ...@@ -4341,11 +4341,14 @@ static int nix_setup_ipolicers(struct rvu *rvu,
return 0; return 0;
} }
static void nix_ipolicer_freemem(struct nix_hw *nix_hw) static void nix_ipolicer_freemem(struct rvu *rvu, struct nix_hw *nix_hw)
{ {
struct nix_ipolicer *ipolicer; struct nix_ipolicer *ipolicer;
int layer; int layer;
if (!rvu->hw->cap.ipolicer)
return;
for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) { for (layer = 0; layer < BAND_PROF_NUM_LAYERS; layer++) {
ipolicer = &nix_hw->ipolicer[layer]; ipolicer = &nix_hw->ipolicer[layer];
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#define RVU_AF_SMMU_TXN_REQ (0x6008) #define RVU_AF_SMMU_TXN_REQ (0x6008)
#define RVU_AF_SMMU_ADDR_RSP_STS (0x6010) #define RVU_AF_SMMU_ADDR_RSP_STS (0x6010)
#define RVU_AF_SMMU_ADDR_TLN (0x6018) #define RVU_AF_SMMU_ADDR_TLN (0x6018)
#define RVU_AF_SMMU_TLN_FLIT1 (0x6030) #define RVU_AF_SMMU_TLN_FLIT0 (0x6020)
/* Admin function's privileged PF/VF registers */ /* Admin function's privileged PF/VF registers */
#define RVU_PRIV_CONST (0x8000000) #define RVU_PRIV_CONST (0x8000000)
......
...@@ -208,7 +208,8 @@ int otx2_set_mac_address(struct net_device *netdev, void *p) ...@@ -208,7 +208,8 @@ int otx2_set_mac_address(struct net_device *netdev, void *p)
if (!otx2_hw_set_mac_addr(pfvf, addr->sa_data)) { if (!otx2_hw_set_mac_addr(pfvf, addr->sa_data)) {
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
/* update dmac field in vlan offload rule */ /* update dmac field in vlan offload rule */
if (pfvf->flags & OTX2_FLAG_RX_VLAN_SUPPORT) if (netif_running(netdev) &&
pfvf->flags & OTX2_FLAG_RX_VLAN_SUPPORT)
otx2_install_rxvlan_offload_flow(pfvf); otx2_install_rxvlan_offload_flow(pfvf);
/* update dmac address in ntuple and DMAC filter list */ /* update dmac address in ntuple and DMAC filter list */
if (pfvf->flags & OTX2_FLAG_DMACFLTR_SUPPORT) if (pfvf->flags & OTX2_FLAG_DMACFLTR_SUPPORT)
...@@ -268,6 +269,7 @@ int otx2_config_pause_frm(struct otx2_nic *pfvf) ...@@ -268,6 +269,7 @@ int otx2_config_pause_frm(struct otx2_nic *pfvf)
int otx2_set_flowkey_cfg(struct otx2_nic *pfvf) int otx2_set_flowkey_cfg(struct otx2_nic *pfvf)
{ {
struct otx2_rss_info *rss = &pfvf->hw.rss_info; struct otx2_rss_info *rss = &pfvf->hw.rss_info;
struct nix_rss_flowkey_cfg_rsp *rsp;
struct nix_rss_flowkey_cfg *req; struct nix_rss_flowkey_cfg *req;
int err; int err;
...@@ -282,6 +284,16 @@ int otx2_set_flowkey_cfg(struct otx2_nic *pfvf) ...@@ -282,6 +284,16 @@ int otx2_set_flowkey_cfg(struct otx2_nic *pfvf)
req->group = DEFAULT_RSS_CONTEXT_GROUP; req->group = DEFAULT_RSS_CONTEXT_GROUP;
err = otx2_sync_mbox_msg(&pfvf->mbox); err = otx2_sync_mbox_msg(&pfvf->mbox);
if (err)
goto fail;
rsp = (struct nix_rss_flowkey_cfg_rsp *)
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
if (IS_ERR(rsp))
goto fail;
pfvf->hw.flowkey_alg_idx = rsp->alg_idx;
fail:
mutex_unlock(&pfvf->mbox.lock); mutex_unlock(&pfvf->mbox.lock);
return err; return err;
} }
...@@ -1196,7 +1208,22 @@ static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, ...@@ -1196,7 +1208,22 @@ static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id,
/* Enable backpressure for RQ aura */ /* Enable backpressure for RQ aura */
if (aura_id < pfvf->hw.rqpool_cnt && !is_otx2_lbkvf(pfvf->pdev)) { if (aura_id < pfvf->hw.rqpool_cnt && !is_otx2_lbkvf(pfvf->pdev)) {
aq->aura.bp_ena = 0; aq->aura.bp_ena = 0;
/* If NIX1 LF is attached then specify NIX1_RX.
*
* Below NPA_AURA_S[BP_ENA] is set according to the
* NPA_BPINTF_E enumeration given as:
* 0x0 + a*0x1 where 'a' is 0 for NIX0_RX and 1 for NIX1_RX so
* NIX0_RX is 0x0 + 0*0x1 = 0
* NIX1_RX is 0x0 + 1*0x1 = 1
* But in HRM it is given that
* "NPA_AURA_S[BP_ENA](w1[33:32]) - Enable aura backpressure to
* NIX-RX based on [BP] level. One bit per NIX-RX; index
* enumerated by NPA_BPINTF_E."
*/
if (pfvf->nix_blkaddr == BLKADDR_NIX1)
aq->aura.bp_ena = 1;
aq->aura.nix0_bpid = pfvf->bpid[0]; aq->aura.nix0_bpid = pfvf->bpid[0];
/* Set backpressure level for RQ's Aura */ /* Set backpressure level for RQ's Aura */
aq->aura.bp = RQ_BP_LVL_AURA; aq->aura.bp = RQ_BP_LVL_AURA;
} }
......
...@@ -199,6 +199,9 @@ struct otx2_hw { ...@@ -199,6 +199,9 @@ struct otx2_hw {
u8 lso_udpv4_idx; u8 lso_udpv4_idx;
u8 lso_udpv6_idx; u8 lso_udpv6_idx;
/* RSS */
u8 flowkey_alg_idx;
/* MSI-X */ /* MSI-X */
u8 cint_cnt; /* CQ interrupt count */ u8 cint_cnt; /* CQ interrupt count */
u16 npa_msixoff; /* Offset of NPA vectors */ u16 npa_msixoff; /* Offset of NPA vectors */
......
...@@ -33,9 +33,6 @@ struct otx2_stat { ...@@ -33,9 +33,6 @@ struct otx2_stat {
.index = offsetof(struct otx2_dev_stats, stat) / sizeof(u64), \ .index = offsetof(struct otx2_dev_stats, stat) / sizeof(u64), \
} }
/* Physical link config */
#define OTX2_ETHTOOL_SUPPORTED_MODES 0x638CCBF //110001110001100110010111111
enum link_mode { enum link_mode {
OTX2_MODE_SUPPORTED, OTX2_MODE_SUPPORTED,
OTX2_MODE_ADVERTISED OTX2_MODE_ADVERTISED
...@@ -1086,8 +1083,6 @@ static void otx2_get_link_mode_info(u64 link_mode_bmap, ...@@ -1086,8 +1083,6 @@ static void otx2_get_link_mode_info(u64 link_mode_bmap,
}; };
u8 bit; u8 bit;
link_mode_bmap = link_mode_bmap & OTX2_ETHTOOL_SUPPORTED_MODES;
for_each_set_bit(bit, (unsigned long *)&link_mode_bmap, 27) { for_each_set_bit(bit, (unsigned long *)&link_mode_bmap, 27) {
/* SGMII mode is set */ /* SGMII mode is set */
if (bit == 0) if (bit == 0)
......
...@@ -907,6 +907,7 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow) ...@@ -907,6 +907,7 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow)
if (flow->flow_spec.flow_type & FLOW_RSS) { if (flow->flow_spec.flow_type & FLOW_RSS) {
req->op = NIX_RX_ACTIONOP_RSS; req->op = NIX_RX_ACTIONOP_RSS;
req->index = flow->rss_ctx_id; req->index = flow->rss_ctx_id;
req->flow_key_alg = pfvf->hw.flowkey_alg_idx;
} else { } else {
req->op = NIX_RX_ACTIONOP_UCAST; req->op = NIX_RX_ACTIONOP_UCAST;
req->index = ethtool_get_flow_spec_ring(ring_cookie); req->index = ethtool_get_flow_spec_ring(ring_cookie);
......
...@@ -508,8 +508,8 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, ...@@ -508,8 +508,8 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
match.key->vlan_priority << 13; match.key->vlan_priority << 13;
vlan_tci_mask = match.mask->vlan_id | vlan_tci_mask = match.mask->vlan_id |
match.key->vlan_dei << 12 | match.mask->vlan_dei << 12 |
match.key->vlan_priority << 13; match.mask->vlan_priority << 13;
flow_spec->vlan_tci = htons(vlan_tci); flow_spec->vlan_tci = htons(vlan_tci);
flow_mask->vlan_tci = htons(vlan_tci_mask); flow_mask->vlan_tci = htons(vlan_tci_mask);
......
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