Commit 2dce08ab authored by David S. Miller's avatar David S. Miller

Merge branch 'octeontx2-af-fixes'

Sai Krishna says:

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

This patchset includes following fixes.

Patch #1 Fix for the race condition while updating APR table

Patch #2 Fix end bit position in NPC scan config

Patch #3 Fix depth of CAM, MEM table entries

Patch #4 Fix in increase the size of DMAC filter flows

Patch #5 Fix driver crash resulting from invalid interface type
information retrieved from firmware

Patch #6 Fix incorrect mask used while installing filters involving
fragmented packets

Patch #7 Fixes for NPC field hash extract w.r.t IPV6 hash reduction,
         IPV6 filed hash configuration.

Patch #8 Fix for NPC hardware parser configuration destination
         address hash, IPV6 endianness issues.

Patch #9 Fix for skipping mbox initialization for PFs disabled by firmware.

Patch #10 Fix disabling packet I/O in case of mailbox timeout.

Patch #11 Fix detaching LF resources in case of VF probe fail.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9e08dcef 99ae1260
......@@ -1231,6 +1231,14 @@ static inline void link_status_user_format(u64 lstat,
linfo->an = FIELD_GET(RESP_LINKSTAT_AN, lstat);
linfo->fec = FIELD_GET(RESP_LINKSTAT_FEC, lstat);
linfo->lmac_type_id = FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, lstat);
if (linfo->lmac_type_id >= LMAC_MODE_MAX) {
dev_err(&cgx->pdev->dev, "Unknown lmac_type_id %d reported by firmware on cgx port%d:%d",
linfo->lmac_type_id, cgx->cgx_id, lmac_id);
strncpy(linfo->lmac_type, "Unknown", LMACTYPE_STR_LEN - 1);
return;
}
lmac_string = cgx_lmactype_string[linfo->lmac_type_id];
strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1);
}
......
......@@ -157,7 +157,7 @@ EXPORT_SYMBOL(otx2_mbox_init);
*/
int otx2_mbox_regions_init(struct otx2_mbox *mbox, void **hwbase,
struct pci_dev *pdev, void *reg_base,
int direction, int ndevs)
int direction, int ndevs, unsigned long *pf_bmap)
{
struct otx2_mbox_dev *mdev;
int devid, err;
......@@ -169,6 +169,9 @@ int otx2_mbox_regions_init(struct otx2_mbox *mbox, void **hwbase,
mbox->hwbase = hwbase[0];
for (devid = 0; devid < ndevs; devid++) {
if (!test_bit(devid, pf_bmap))
continue;
mdev = &mbox->dev[devid];
mdev->mbase = hwbase[devid];
mdev->hwbase = hwbase[devid];
......
......@@ -96,9 +96,10 @@ void otx2_mbox_destroy(struct otx2_mbox *mbox);
int otx2_mbox_init(struct otx2_mbox *mbox, void __force *hwbase,
struct pci_dev *pdev, void __force *reg_base,
int direction, int ndevs);
int otx2_mbox_regions_init(struct otx2_mbox *mbox, void __force **hwbase,
struct pci_dev *pdev, void __force *reg_base,
int direction, int ndevs);
int direction, int ndevs, unsigned long *bmap);
void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid);
int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid);
int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid);
......@@ -245,9 +246,9 @@ M(NPC_MCAM_READ_BASE_RULE, 0x6011, npc_read_base_steer_rule, \
M(NPC_MCAM_GET_STATS, 0x6012, npc_mcam_entry_stats, \
npc_mcam_get_stats_req, \
npc_mcam_get_stats_rsp) \
M(NPC_GET_SECRET_KEY, 0x6013, npc_get_secret_key, \
npc_get_secret_key_req, \
npc_get_secret_key_rsp) \
M(NPC_GET_FIELD_HASH_INFO, 0x6013, npc_get_field_hash_info, \
npc_get_field_hash_info_req, \
npc_get_field_hash_info_rsp) \
M(NPC_GET_FIELD_STATUS, 0x6014, npc_get_field_status, \
npc_get_field_status_req, \
npc_get_field_status_rsp) \
......@@ -1524,14 +1525,20 @@ struct npc_mcam_get_stats_rsp {
u8 stat_ena; /* enabled */
};
struct npc_get_secret_key_req {
struct npc_get_field_hash_info_req {
struct mbox_msghdr hdr;
u8 intf;
};
struct npc_get_secret_key_rsp {
struct npc_get_field_hash_info_rsp {
struct mbox_msghdr hdr;
u64 secret_key[3];
#define NPC_MAX_HASH 2
#define NPC_MAX_HASH_MASK 2
/* NPC_AF_INTF(0..1)_HASH(0..1)_MASK(0..1) */
u64 hash_mask[NPC_MAX_INTF][NPC_MAX_HASH][NPC_MAX_HASH_MASK];
/* NPC_AF_INTF(0..1)_HASH(0..1)_RESULT_CTRL */
u64 hash_ctrl[NPC_MAX_INTF][NPC_MAX_HASH];
};
enum ptp_op {
......
......@@ -2282,7 +2282,7 @@ static inline void rvu_afvf_mbox_up_handler(struct work_struct *work)
}
static int rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
int num, int type)
int num, int type, unsigned long *pf_bmap)
{
struct rvu_hwinfo *hw = rvu->hw;
int region;
......@@ -2294,6 +2294,9 @@ static int rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
*/
if (type == TYPE_AFVF) {
for (region = 0; region < num; region++) {
if (!test_bit(region, pf_bmap))
continue;
if (hw->cap.per_pf_mbox_regs) {
bar4 = rvu_read64(rvu, BLKADDR_RVUM,
RVU_AF_PFX_BAR4_ADDR(0)) +
......@@ -2315,6 +2318,9 @@ static int rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
* RVU_AF_PF_BAR4_ADDR register.
*/
for (region = 0; region < num; region++) {
if (!test_bit(region, pf_bmap))
continue;
if (hw->cap.per_pf_mbox_regs) {
bar4 = rvu_read64(rvu, BLKADDR_RVUM,
RVU_AF_PFX_BAR4_ADDR(region));
......@@ -2343,20 +2349,41 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
int err = -EINVAL, i, dir, dir_up;
void __iomem *reg_base;
struct rvu_work *mwork;
unsigned long *pf_bmap;
void **mbox_regions;
const char *name;
u64 cfg;
mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL);
if (!mbox_regions)
pf_bmap = bitmap_zalloc(num, GFP_KERNEL);
if (!pf_bmap)
return -ENOMEM;
/* RVU VFs */
if (type == TYPE_AFVF)
bitmap_set(pf_bmap, 0, num);
if (type == TYPE_AFPF) {
/* Mark enabled PFs in bitmap */
for (i = 0; i < num; i++) {
cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(i));
if (cfg & BIT_ULL(20))
set_bit(i, pf_bmap);
}
}
mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL);
if (!mbox_regions) {
err = -ENOMEM;
goto free_bitmap;
}
switch (type) {
case TYPE_AFPF:
name = "rvu_afpf_mailbox";
dir = MBOX_DIR_AFPF;
dir_up = MBOX_DIR_AFPF_UP;
reg_base = rvu->afreg_base;
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFPF);
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFPF, pf_bmap);
if (err)
goto free_regions;
break;
......@@ -2365,7 +2392,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
dir = MBOX_DIR_PFVF;
dir_up = MBOX_DIR_PFVF_UP;
reg_base = rvu->pfreg_base;
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFVF);
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFVF, pf_bmap);
if (err)
goto free_regions;
break;
......@@ -2396,16 +2423,19 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
}
err = otx2_mbox_regions_init(&mw->mbox, mbox_regions, rvu->pdev,
reg_base, dir, num);
reg_base, dir, num, pf_bmap);
if (err)
goto exit;
err = otx2_mbox_regions_init(&mw->mbox_up, mbox_regions, rvu->pdev,
reg_base, dir_up, num);
reg_base, dir_up, num, pf_bmap);
if (err)
goto exit;
for (i = 0; i < num; i++) {
if (!test_bit(i, pf_bmap))
continue;
mwork = &mw->mbox_wrk[i];
mwork->rvu = rvu;
INIT_WORK(&mwork->work, mbox_handler);
......@@ -2414,8 +2444,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
mwork->rvu = rvu;
INIT_WORK(&mwork->work, mbox_up_handler);
}
kfree(mbox_regions);
return 0;
goto free_regions;
exit:
destroy_workqueue(mw->mbox_wq);
......@@ -2424,6 +2453,8 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
iounmap((void __iomem *)mbox_regions[num]);
free_regions:
kfree(mbox_regions);
free_bitmap:
bitmap_free(pf_bmap);
return err;
}
......
......@@ -60,13 +60,14 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
u64 iova, u64 *lmt_addr)
{
u64 pa, val, pf;
int err;
int err = 0;
if (!iova) {
dev_err(rvu->dev, "%s Requested Null address for transulation\n", __func__);
return -EINVAL;
}
mutex_lock(&rvu->rsrc_lock);
rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
pf = rvu_get_pf(pcifunc) & 0x1F;
val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
......@@ -76,12 +77,13 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
err = rvu_poll_reg(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS, BIT_ULL(0), false);
if (err) {
dev_err(rvu->dev, "%s LMTLINE iova transulation failed\n", __func__);
return err;
goto exit;
}
val = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS);
if (val & ~0x1ULL) {
dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
return -EIO;
err = -EIO;
goto exit;
}
/* PA[51:12] = RVU_AF_SMMU_TLN_FLIT0[57:18]
* PA[11:0] = IOVA[11:0]
......@@ -89,8 +91,9 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT0) >> 18;
pa &= GENMASK_ULL(39, 0);
*lmt_addr = (pa << 12) | (iova & 0xFFF);
return 0;
exit:
mutex_unlock(&rvu->rsrc_lock);
return err;
}
static int rvu_update_lmtaddr(struct rvu *rvu, u16 pcifunc, u64 lmt_addr)
......
......@@ -13,11 +13,6 @@
#include "rvu_npc_fs.h"
#include "rvu_npc_hash.h"
#define NPC_BYTESM GENMASK_ULL(19, 16)
#define NPC_HDR_OFFSET GENMASK_ULL(15, 8)
#define NPC_KEY_OFFSET GENMASK_ULL(5, 0)
#define NPC_LDATA_EN BIT_ULL(7)
static const char * const npc_flow_names[] = {
[NPC_DMAC] = "dmac",
[NPC_SMAC] = "smac",
......@@ -442,6 +437,7 @@ static void npc_handle_multi_layer_fields(struct rvu *rvu, int blkaddr, u8 intf)
static void npc_scan_ldata(struct rvu *rvu, int blkaddr, u8 lid,
u8 lt, u64 cfg, u8 intf)
{
struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
struct npc_mcam *mcam = &rvu->hw->mcam;
u8 hdr, key, nr_bytes, bit_offset;
u8 la_ltype, la_start;
......@@ -490,8 +486,21 @@ do { \
NPC_SCAN_HDR(NPC_SIP_IPV4, NPC_LID_LC, NPC_LT_LC_IP, 12, 4);
NPC_SCAN_HDR(NPC_DIP_IPV4, NPC_LID_LC, NPC_LT_LC_IP, 16, 4);
NPC_SCAN_HDR(NPC_IPFRAG_IPV6, NPC_LID_LC, NPC_LT_LC_IP6_EXT, 6, 1);
NPC_SCAN_HDR(NPC_SIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 8, 16);
NPC_SCAN_HDR(NPC_DIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 24, 16);
if (rvu->hw->cap.npc_hash_extract) {
if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][0])
NPC_SCAN_HDR(NPC_SIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 8, 4);
else
NPC_SCAN_HDR(NPC_SIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 8, 16);
if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][1])
NPC_SCAN_HDR(NPC_DIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 24, 4);
else
NPC_SCAN_HDR(NPC_DIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 24, 16);
} else {
NPC_SCAN_HDR(NPC_SIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 8, 16);
NPC_SCAN_HDR(NPC_DIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 24, 16);
}
NPC_SCAN_HDR(NPC_SPORT_UDP, NPC_LID_LD, NPC_LT_LD_UDP, 0, 2);
NPC_SCAN_HDR(NPC_DPORT_UDP, NPC_LID_LD, NPC_LT_LD_UDP, 2, 2);
NPC_SCAN_HDR(NPC_SPORT_TCP, NPC_LID_LD, NPC_LT_LD_TCP, 0, 2);
......@@ -594,8 +603,7 @@ static int npc_scan_kex(struct rvu *rvu, int blkaddr, u8 intf)
*/
masked_cfg = cfg & NPC_EXACT_NIBBLE;
bitnr = NPC_EXACT_NIBBLE_START;
for_each_set_bit_from(bitnr, (unsigned long *)&masked_cfg,
NPC_EXACT_NIBBLE_START) {
for_each_set_bit_from(bitnr, (unsigned long *)&masked_cfg, NPC_EXACT_NIBBLE_END + 1) {
npc_scan_exact_result(mcam, bitnr, key_nibble, intf);
key_nibble++;
}
......
......@@ -9,6 +9,10 @@
#define __RVU_NPC_FS_H
#define IPV6_WORDS 4
#define NPC_BYTESM GENMASK_ULL(19, 16)
#define NPC_HDR_OFFSET GENMASK_ULL(15, 8)
#define NPC_KEY_OFFSET GENMASK_ULL(5, 0)
#define NPC_LDATA_EN BIT_ULL(7)
void npc_update_entry(struct rvu *rvu, enum key_fields type,
struct mcam_entry *entry, u64 val_lo,
......
......@@ -78,42 +78,43 @@ static u32 rvu_npc_toeplitz_hash(const u64 *data, u64 *key, size_t data_bit_len,
return hash_out;
}
u32 npc_field_hash_calc(u64 *ldata, struct npc_mcam_kex_hash *mkex_hash,
u64 *secret_key, u8 intf, u8 hash_idx)
u32 npc_field_hash_calc(u64 *ldata, struct npc_get_field_hash_info_rsp rsp,
u8 intf, u8 hash_idx)
{
u64 hash_key[3];
u64 data_padded[2];
u32 field_hash;
hash_key[0] = secret_key[1] << 31;
hash_key[0] |= secret_key[2];
hash_key[1] = secret_key[1] >> 33;
hash_key[1] |= secret_key[0] << 31;
hash_key[2] = secret_key[0] >> 33;
hash_key[0] = rsp.secret_key[1] << 31;
hash_key[0] |= rsp.secret_key[2];
hash_key[1] = rsp.secret_key[1] >> 33;
hash_key[1] |= rsp.secret_key[0] << 31;
hash_key[2] = rsp.secret_key[0] >> 33;
data_padded[0] = mkex_hash->hash_mask[intf][hash_idx][0] & ldata[0];
data_padded[1] = mkex_hash->hash_mask[intf][hash_idx][1] & ldata[1];
data_padded[0] = rsp.hash_mask[intf][hash_idx][0] & ldata[0];
data_padded[1] = rsp.hash_mask[intf][hash_idx][1] & ldata[1];
field_hash = rvu_npc_toeplitz_hash(data_padded, hash_key, 128, 159);
field_hash &= mkex_hash->hash_ctrl[intf][hash_idx] >> 32;
field_hash |= mkex_hash->hash_ctrl[intf][hash_idx];
field_hash &= FIELD_GET(GENMASK(63, 32), rsp.hash_ctrl[intf][hash_idx]);
field_hash += FIELD_GET(GENMASK(31, 0), rsp.hash_ctrl[intf][hash_idx]);
return field_hash;
}
static u64 npc_update_use_hash(int lt, int ld)
static u64 npc_update_use_hash(struct rvu *rvu, int blkaddr,
u8 intf, int lid, int lt, int ld)
{
u64 cfg = 0;
switch (lt) {
case NPC_LT_LC_IP6:
/* Update use_hash(bit-20) and bytesm1 (bit-16:19)
* in KEX_LD_CFG
*/
cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
ld ? 0x8 : 0x18,
0x1, 0x0, 0x10);
break;
}
u8 hdr, key;
u64 cfg;
cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, lt, ld));
hdr = FIELD_GET(NPC_HDR_OFFSET, cfg);
key = FIELD_GET(NPC_KEY_OFFSET, cfg);
/* Update use_hash(bit-20) to 'true' and
* bytesm1(bit-16:19) to '0x3' in KEX_LD_CFG
*/
cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
hdr, 0x1, 0x0, key);
return cfg;
}
......@@ -132,12 +133,13 @@ static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
for (lt = 0; lt < NPC_MAX_LT; lt++) {
for (ld = 0; ld < NPC_MAX_LD; ld++) {
if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
u64 cfg = npc_update_use_hash(lt, ld);
u64 cfg;
hash_cnt++;
if (hash_cnt == NPC_MAX_HASH)
return;
cfg = npc_update_use_hash(rvu, blkaddr,
intf, lid, lt, ld);
/* Set updated KEX configuration */
SET_KEX_LD(intf, lid, lt, ld, cfg);
/* Set HASH configuration */
......@@ -149,6 +151,8 @@ static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
mkex_hash->hash_mask[intf][ld][1]);
SET_KEX_LD_HASH_CTRL(intf, ld,
mkex_hash->hash_ctrl[intf][ld]);
hash_cnt++;
}
}
}
......@@ -169,12 +173,13 @@ static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
for (lt = 0; lt < NPC_MAX_LT; lt++) {
for (ld = 0; ld < NPC_MAX_LD; ld++)
if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
u64 cfg = npc_update_use_hash(lt, ld);
u64 cfg;
hash_cnt++;
if (hash_cnt == NPC_MAX_HASH)
return;
cfg = npc_update_use_hash(rvu, blkaddr,
intf, lid, lt, ld);
/* Set updated KEX configuration */
SET_KEX_LD(intf, lid, lt, ld, cfg);
/* Set HASH configuration */
......@@ -187,8 +192,6 @@ static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
SET_KEX_LD_HASH_CTRL(intf, ld,
mkex_hash->hash_ctrl[intf][ld]);
hash_cnt++;
if (hash_cnt == NPC_MAX_HASH)
return;
}
}
}
......@@ -238,8 +241,8 @@ void npc_update_field_hash(struct rvu *rvu, u8 intf,
struct flow_msg *omask)
{
struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
struct npc_get_secret_key_req req;
struct npc_get_secret_key_rsp rsp;
struct npc_get_field_hash_info_req req;
struct npc_get_field_hash_info_rsp rsp;
u64 ldata[2], cfg;
u32 field_hash;
u8 hash_idx;
......@@ -250,7 +253,7 @@ void npc_update_field_hash(struct rvu *rvu, u8 intf,
}
req.intf = intf;
rvu_mbox_handler_npc_get_secret_key(rvu, &req, &rsp);
rvu_mbox_handler_npc_get_field_hash_info(rvu, &req, &rsp);
for (hash_idx = 0; hash_idx < NPC_MAX_HASH; hash_idx++) {
cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_CFG(intf, hash_idx));
......@@ -266,44 +269,45 @@ void npc_update_field_hash(struct rvu *rvu, u8 intf,
* is hashed to 32 bit value.
*/
case NPC_LT_LC_IP6:
if (features & BIT_ULL(NPC_SIP_IPV6)) {
/* ld[0] == hash_idx[0] == Source IPv6
* ld[1] == hash_idx[1] == Destination IPv6
*/
if ((features & BIT_ULL(NPC_SIP_IPV6)) && !hash_idx) {
u32 src_ip[IPV6_WORDS];
be32_to_cpu_array(src_ip, pkt->ip6src, IPV6_WORDS);
ldata[0] = (u64)src_ip[0] << 32 | src_ip[1];
ldata[1] = (u64)src_ip[2] << 32 | src_ip[3];
ldata[1] = (u64)src_ip[0] << 32 | src_ip[1];
ldata[0] = (u64)src_ip[2] << 32 | src_ip[3];
field_hash = npc_field_hash_calc(ldata,
mkex_hash,
rsp.secret_key,
rsp,
intf,
hash_idx);
npc_update_entry(rvu, NPC_SIP_IPV6, entry,
field_hash, 0, 32, 0, intf);
field_hash, 0,
GENMASK(31, 0), 0, intf);
memcpy(&opkt->ip6src, &pkt->ip6src,
sizeof(pkt->ip6src));
memcpy(&omask->ip6src, &mask->ip6src,
sizeof(mask->ip6src));
break;
}
if (features & BIT_ULL(NPC_DIP_IPV6)) {
} else if ((features & BIT_ULL(NPC_DIP_IPV6)) && hash_idx) {
u32 dst_ip[IPV6_WORDS];
be32_to_cpu_array(dst_ip, pkt->ip6dst, IPV6_WORDS);
ldata[0] = (u64)dst_ip[0] << 32 | dst_ip[1];
ldata[1] = (u64)dst_ip[2] << 32 | dst_ip[3];
ldata[1] = (u64)dst_ip[0] << 32 | dst_ip[1];
ldata[0] = (u64)dst_ip[2] << 32 | dst_ip[3];
field_hash = npc_field_hash_calc(ldata,
mkex_hash,
rsp.secret_key,
rsp,
intf,
hash_idx);
npc_update_entry(rvu, NPC_DIP_IPV6, entry,
field_hash, 0, 32, 0, intf);
field_hash, 0,
GENMASK(31, 0), 0, intf);
memcpy(&opkt->ip6dst, &pkt->ip6dst,
sizeof(pkt->ip6dst));
memcpy(&omask->ip6dst, &mask->ip6dst,
sizeof(mask->ip6dst));
}
break;
}
}
......@@ -311,13 +315,13 @@ void npc_update_field_hash(struct rvu *rvu, u8 intf,
}
}
int rvu_mbox_handler_npc_get_secret_key(struct rvu *rvu,
struct npc_get_secret_key_req *req,
struct npc_get_secret_key_rsp *rsp)
int rvu_mbox_handler_npc_get_field_hash_info(struct rvu *rvu,
struct npc_get_field_hash_info_req *req,
struct npc_get_field_hash_info_rsp *rsp)
{
u64 *secret_key = rsp->secret_key;
u8 intf = req->intf;
int blkaddr;
int i, j, blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0) {
......@@ -329,6 +333,19 @@ int rvu_mbox_handler_npc_get_secret_key(struct rvu *rvu,
secret_key[1] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf));
secret_key[2] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf));
for (i = 0; i < NPC_MAX_HASH; i++) {
for (j = 0; j < NPC_MAX_HASH_MASK; j++) {
rsp->hash_mask[NIX_INTF_RX][i][j] =
GET_KEX_LD_HASH_MASK(NIX_INTF_RX, i, j);
rsp->hash_mask[NIX_INTF_TX][i][j] =
GET_KEX_LD_HASH_MASK(NIX_INTF_TX, i, j);
}
}
for (i = 0; i < NPC_MAX_INTF; i++)
for (j = 0; j < NPC_MAX_HASH; j++)
rsp->hash_ctrl[i][j] = GET_KEX_LD_HASH_CTRL(i, j);
return 0;
}
......@@ -1868,9 +1885,9 @@ int rvu_npc_exact_init(struct rvu *rvu)
rvu->hw->table = table;
/* Read table size, ways and depth */
table->mem_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);
table->mem_table.ways = FIELD_GET(GENMASK_ULL(19, 16), npc_const3);
table->cam_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
table->mem_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
table->cam_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);
dev_dbg(rvu->dev, "%s: NPC exact match 4way_2k table(ways=%d, depth=%d)\n",
__func__, table->mem_table.ways, table->cam_table.depth);
......
......@@ -31,6 +31,12 @@
rvu_write64(rvu, blkaddr, \
NPC_AF_INTFX_HASHX_MASKX(intf, ld, mask_idx), cfg)
#define GET_KEX_LD_HASH_CTRL(intf, ld) \
rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_RESULT_CTRL(intf, ld))
#define GET_KEX_LD_HASH_MASK(intf, ld, mask_idx) \
rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_MASKX(intf, ld, mask_idx))
#define SET_KEX_LD_HASH_CTRL(intf, ld, cfg) \
rvu_write64(rvu, blkaddr, \
NPC_AF_INTFX_HASHX_RESULT_CTRL(intf, ld), cfg)
......@@ -56,8 +62,8 @@ void npc_update_field_hash(struct rvu *rvu, u8 intf,
struct flow_msg *omask);
void npc_config_secret_key(struct rvu *rvu, int blkaddr);
void npc_program_mkex_hash(struct rvu *rvu, int blkaddr);
u32 npc_field_hash_calc(u64 *ldata, struct npc_mcam_kex_hash *mkex_hash,
u64 *secret_key, u8 intf, u8 hash_idx);
u32 npc_field_hash_calc(u64 *ldata, struct npc_get_field_hash_info_rsp rsp,
u8 intf, u8 hash_idx);
static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = {
.lid_lt_ld_hash_en = {
......
......@@ -335,11 +335,11 @@ struct otx2_flow_config {
#define OTX2_PER_VF_VLAN_FLOWS 2 /* Rx + Tx per VF */
#define OTX2_VF_VLAN_RX_INDEX 0
#define OTX2_VF_VLAN_TX_INDEX 1
u16 max_flows;
u8 dmacflt_max_flows;
u32 *bmap_to_dmacindex;
unsigned long *dmacflt_bmap;
struct list_head flow_list;
u32 dmacflt_max_flows;
u16 max_flows;
};
struct otx2_tc_info {
......
......@@ -1835,13 +1835,22 @@ int otx2_open(struct net_device *netdev)
otx2_dmacflt_reinstall_flows(pf);
err = otx2_rxtx_enable(pf, true);
if (err)
/* If a mbox communication error happens at this point then interface
* will end up in a state such that it is in down state but hardware
* mcam entries are enabled to receive the packets. Hence disable the
* packet I/O.
*/
if (err == EIO)
goto err_disable_rxtx;
else if (err)
goto err_tx_stop_queues;
otx2_do_set_rx_mode(pf);
return 0;
err_disable_rxtx:
otx2_rxtx_enable(pf, false);
err_tx_stop_queues:
netif_tx_stop_all_queues(netdev);
netif_carrier_off(netdev);
......
......@@ -544,7 +544,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
if (match.mask->flags & FLOW_DIS_IS_FRAGMENT) {
if (ntohs(flow_spec->etype) == ETH_P_IP) {
flow_spec->ip_flag = IPV4_FLAG_MORE;
flow_mask->ip_flag = 0xff;
flow_mask->ip_flag = IPV4_FLAG_MORE;
req->features |= BIT_ULL(NPC_IPFRAG_IPV4);
} else if (ntohs(flow_spec->etype) == ETH_P_IPV6) {
flow_spec->next_header = IPPROTO_FRAGMENT;
......
......@@ -621,7 +621,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err = otx2vf_realloc_msix_vectors(vf);
if (err)
goto err_mbox_destroy;
goto err_detach_rsrc;
err = otx2_set_real_num_queues(netdev, qcount, qcount);
if (err)
......
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