mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
Merge branch 'octeontx2-exact-match-table'
Ratheesh Kannoth says: ==================== octeontx2: Exact Match Table. Exact match table and Field hash support for CN10KB silicon ==================== Link: https://lore.kernel.org/r/20220708044151.2972645-1-rkannoth@marvell.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
b205c1b423
@ -11,4 +11,4 @@ rvu_mbox-y := mbox.o rvu_trace.o
|
||||
rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
|
||||
rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \
|
||||
rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o \
|
||||
rvu_sdp.o
|
||||
rvu_sdp.o rvu_npc_hash.o
|
||||
|
@ -169,9 +169,10 @@ M(CGX_GET_PHY_FEC_STATS, 0x219, cgx_get_phy_fec_stats, msg_req, msg_rsp) \
|
||||
M(CGX_FEATURES_GET, 0x21B, cgx_features_get, msg_req, \
|
||||
cgx_features_info_msg) \
|
||||
M(RPM_STATS, 0x21C, rpm_stats, msg_req, rpm_stats_rsp) \
|
||||
M(CGX_MAC_ADDR_RESET, 0x21D, cgx_mac_addr_reset, msg_req, msg_rsp) \
|
||||
M(CGX_MAC_ADDR_RESET, 0x21D, cgx_mac_addr_reset, cgx_mac_addr_reset_req, \
|
||||
msg_rsp) \
|
||||
M(CGX_MAC_ADDR_UPDATE, 0x21E, cgx_mac_addr_update, cgx_mac_addr_update_req, \
|
||||
msg_rsp) \
|
||||
cgx_mac_addr_update_rsp) \
|
||||
M(CGX_PRIO_FLOW_CTRL_CFG, 0x21F, cgx_prio_flow_ctrl_cfg, cgx_pfc_cfg, \
|
||||
cgx_pfc_rsp) \
|
||||
/* NPA mbox IDs (range 0x400 - 0x5FF) */ \
|
||||
@ -241,6 +242,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) \
|
||||
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
|
||||
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, \
|
||||
nix_lf_alloc_req, nix_lf_alloc_rsp) \
|
||||
@ -428,6 +432,7 @@ struct get_hw_cap_rsp {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 nix_fixed_txschq_mapping; /* Schq mapping fixed or flexible */
|
||||
u8 nix_shaping; /* Is shaping and coloring supported */
|
||||
u8 npc_hash_extract; /* Is hash extract supported */
|
||||
};
|
||||
|
||||
/* CGX mbox message formats */
|
||||
@ -451,6 +456,7 @@ struct cgx_fec_stats_rsp {
|
||||
struct cgx_mac_addr_set_or_get {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u32 index;
|
||||
};
|
||||
|
||||
/* Structure for requesting the operation to
|
||||
@ -466,7 +472,7 @@ struct cgx_mac_addr_add_req {
|
||||
*/
|
||||
struct cgx_mac_addr_add_rsp {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 index;
|
||||
u32 index;
|
||||
};
|
||||
|
||||
/* Structure for requesting the operation to
|
||||
@ -474,7 +480,7 @@ struct cgx_mac_addr_add_rsp {
|
||||
*/
|
||||
struct cgx_mac_addr_del_req {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 index;
|
||||
u32 index;
|
||||
};
|
||||
|
||||
/* Structure for response against the operation to
|
||||
@ -482,7 +488,7 @@ struct cgx_mac_addr_del_req {
|
||||
*/
|
||||
struct cgx_max_dmac_entries_get_rsp {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 max_dmac_filters;
|
||||
u32 max_dmac_filters;
|
||||
};
|
||||
|
||||
struct cgx_link_user_info {
|
||||
@ -583,10 +589,20 @@ struct cgx_set_link_mode_rsp {
|
||||
int status;
|
||||
};
|
||||
|
||||
struct cgx_mac_addr_reset_req {
|
||||
struct mbox_msghdr hdr;
|
||||
u32 index;
|
||||
};
|
||||
|
||||
struct cgx_mac_addr_update_req {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 index;
|
||||
u32 index;
|
||||
};
|
||||
|
||||
struct cgx_mac_addr_update_rsp {
|
||||
struct mbox_msghdr hdr;
|
||||
u32 index;
|
||||
};
|
||||
|
||||
#define RVU_LMAC_FEAT_FC BIT_ULL(0) /* pause frames */
|
||||
@ -1440,6 +1456,16 @@ struct npc_mcam_get_stats_rsp {
|
||||
u8 stat_ena; /* enabled */
|
||||
};
|
||||
|
||||
struct npc_get_secret_key_req {
|
||||
struct mbox_msghdr hdr;
|
||||
u8 intf;
|
||||
};
|
||||
|
||||
struct npc_get_secret_key_rsp {
|
||||
struct mbox_msghdr hdr;
|
||||
u64 secret_key[3];
|
||||
};
|
||||
|
||||
enum ptp_op {
|
||||
PTP_OP_ADJFINE = 0,
|
||||
PTP_OP_GET_CLOCK = 1,
|
||||
@ -1622,6 +1648,9 @@ enum cgx_af_status {
|
||||
LMAC_AF_ERR_PERM_DENIED = -1103,
|
||||
LMAC_AF_ERR_PFC_ENADIS_PERM_DENIED = -1104,
|
||||
LMAC_AF_ERR_8023PAUSE_ENADIS_PERM_DENIED = -1105,
|
||||
LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED = -1108,
|
||||
LMAC_AF_ERR_EXACT_MATCH_TBL_DEL_FAILED = -1109,
|
||||
LMAC_AF_ERR_EXACT_MATCH_TBL_LOOK_UP_FAILED = -1110,
|
||||
};
|
||||
|
||||
#endif /* MBOX_H */
|
||||
|
@ -10,6 +10,14 @@
|
||||
|
||||
#define NPC_KEX_CHAN_MASK 0xFFFULL
|
||||
|
||||
#define SET_KEX_LD(intf, lid, ltype, ld, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, ltype, ld), cfg)
|
||||
|
||||
#define SET_KEX_LDFLAGS(intf, ld, flags, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_LDATAX_FLAGSX_CFG(intf, ld, flags), cfg)
|
||||
|
||||
enum NPC_LID_E {
|
||||
NPC_LID_LA = 0,
|
||||
NPC_LID_LB,
|
||||
@ -200,6 +208,7 @@ enum key_fields {
|
||||
NPC_ERRLEV,
|
||||
NPC_ERRCODE,
|
||||
NPC_LXMB,
|
||||
NPC_EXACT_RESULT,
|
||||
NPC_LA,
|
||||
NPC_LB,
|
||||
NPC_LC,
|
||||
@ -380,6 +389,22 @@ struct nix_rx_action {
|
||||
#endif
|
||||
};
|
||||
|
||||
/* NPC_AF_INTFX_KEX_CFG field masks */
|
||||
#define NPC_EXACT_NIBBLE_START 40
|
||||
#define NPC_EXACT_NIBBLE_END 43
|
||||
#define NPC_EXACT_NIBBLE GENMASK_ULL(43, 40)
|
||||
|
||||
/* NPC_EXACT_KEX_S nibble definitions for each field */
|
||||
#define NPC_EXACT_NIBBLE_HIT BIT_ULL(40)
|
||||
#define NPC_EXACT_NIBBLE_OPC BIT_ULL(40)
|
||||
#define NPC_EXACT_NIBBLE_WAY BIT_ULL(40)
|
||||
#define NPC_EXACT_NIBBLE_INDEX GENMASK_ULL(43, 41)
|
||||
|
||||
#define NPC_EXACT_RESULT_HIT BIT_ULL(0)
|
||||
#define NPC_EXACT_RESULT_OPC GENMASK_ULL(2, 1)
|
||||
#define NPC_EXACT_RESULT_WAY GENMASK_ULL(4, 3)
|
||||
#define NPC_EXACT_RESULT_IDX GENMASK_ULL(15, 5)
|
||||
|
||||
/* NPC_AF_INTFX_KEX_CFG field masks */
|
||||
#define NPC_PARSE_NIBBLE GENMASK_ULL(30, 0)
|
||||
|
||||
|
@ -155,7 +155,7 @@
|
||||
|
||||
/* Rx parse key extract nibble enable */
|
||||
#define NPC_PARSE_NIBBLE_INTF_RX (NPC_PARSE_NIBBLE_CHAN | \
|
||||
NPC_PARSE_NIBBLE_ERRCODE | \
|
||||
NPC_PARSE_NIBBLE_L2L3_BCAST | \
|
||||
NPC_PARSE_NIBBLE_LA_LTYPE | \
|
||||
NPC_PARSE_NIBBLE_LB_LTYPE | \
|
||||
NPC_PARSE_NIBBLE_LC_LTYPE | \
|
||||
@ -15123,7 +15123,8 @@ static struct npc_mcam_kex npc_mkex_default = {
|
||||
.kpu_version = NPC_KPU_PROFILE_VER,
|
||||
.keyx_cfg = {
|
||||
/* nibble: LA..LE (ltype only) + Error code + Channel */
|
||||
[NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_RX,
|
||||
[NIX_INTF_RX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_RX |
|
||||
(u64)NPC_EXACT_NIBBLE_HIT,
|
||||
/* nibble: LA..LE (ltype only) */
|
||||
[NIX_INTF_TX] = ((u64)NPC_MCAM_KEY_X2 << 32) | NPC_PARSE_NIBBLE_INTF_TX,
|
||||
},
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ptp.h"
|
||||
|
||||
#include "rvu_trace.h"
|
||||
#include "rvu_npc_hash.h"
|
||||
|
||||
#define DRV_NAME "rvu_af"
|
||||
#define DRV_STRING "Marvell OcteonTX2 RVU Admin Function Driver"
|
||||
@ -68,6 +69,8 @@ static void rvu_setup_hw_capabilities(struct rvu *rvu)
|
||||
hw->cap.nix_tx_link_bp = true;
|
||||
hw->cap.nix_rx_multicast = true;
|
||||
hw->cap.nix_shaper_toggle_wait = false;
|
||||
hw->cap.npc_hash_extract = false;
|
||||
hw->cap.npc_exact_match_enabled = false;
|
||||
hw->rvu = rvu;
|
||||
|
||||
if (is_rvu_pre_96xx_C0(rvu)) {
|
||||
@ -85,6 +88,9 @@ static void rvu_setup_hw_capabilities(struct rvu *rvu)
|
||||
|
||||
if (!is_rvu_otx2(rvu))
|
||||
hw->cap.per_pf_mbox_regs = true;
|
||||
|
||||
if (is_rvu_npc_hash_extract_en(rvu))
|
||||
hw->cap.npc_hash_extract = true;
|
||||
}
|
||||
|
||||
/* Poll a RVU block's register 'offset', for a 'zero'
|
||||
@ -1122,6 +1128,12 @@ cpt:
|
||||
goto cgx_err;
|
||||
}
|
||||
|
||||
err = rvu_npc_exact_init(rvu);
|
||||
if (err) {
|
||||
dev_err(rvu->dev, "failed to initialize exact match table\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Assign MACs for CGX mapped functions */
|
||||
rvu_setup_pfvf_macaddress(rvu);
|
||||
|
||||
@ -1991,6 +2003,7 @@ int rvu_mbox_handler_get_hw_cap(struct rvu *rvu, struct msg_req *req,
|
||||
|
||||
rsp->nix_fixed_txschq_mapping = hw->cap.nix_fixed_txschq_mapping;
|
||||
rsp->nix_shaping = hw->cap.nix_shaping;
|
||||
rsp->npc_hash_extract = hw->cap.npc_hash_extract;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2548,6 +2561,9 @@ static void rvu_blklf_teardown(struct rvu *rvu, u16 pcifunc, u8 blkaddr)
|
||||
|
||||
static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc)
|
||||
{
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
rvu_npc_exact_reset(rvu, pcifunc);
|
||||
|
||||
mutex_lock(&rvu->flr_lock);
|
||||
/* Reset order should reflect inter-block dependencies:
|
||||
* 1. Reset any packet/work sources (NIX, CPT, TIM)
|
||||
|
@ -338,6 +338,8 @@ struct hw_cap {
|
||||
bool per_pf_mbox_regs; /* PF mbox specified in per PF registers ? */
|
||||
bool programmable_chans; /* Channels programmable ? */
|
||||
bool ipolicer;
|
||||
bool npc_hash_extract; /* Hash extract enabled ? */
|
||||
bool npc_exact_match_enabled; /* Exact match supported ? */
|
||||
};
|
||||
|
||||
struct rvu_hwinfo {
|
||||
@ -369,6 +371,7 @@ struct rvu_hwinfo {
|
||||
struct rvu *rvu;
|
||||
struct npc_pkind pkind;
|
||||
struct npc_mcam mcam;
|
||||
struct npc_exact_table *table;
|
||||
};
|
||||
|
||||
struct mbox_wq_info {
|
||||
@ -419,6 +422,7 @@ struct npc_kpu_profile_adapter {
|
||||
const struct npc_kpu_profile_action *ikpu; /* array[pkinds] */
|
||||
const struct npc_kpu_profile *kpu; /* array[kpus] */
|
||||
struct npc_mcam_kex *mkex;
|
||||
struct npc_mcam_kex_hash *mkex_hash;
|
||||
bool custom;
|
||||
size_t pkinds;
|
||||
size_t kpus;
|
||||
@ -575,6 +579,17 @@ static inline bool is_rvu_otx2(struct rvu *rvu)
|
||||
midr == PCI_REVISION_ID_95XXMM || midr == PCI_REVISION_ID_95XXO);
|
||||
}
|
||||
|
||||
static inline bool is_rvu_npc_hash_extract_en(struct rvu *rvu)
|
||||
{
|
||||
u64 npc_const3;
|
||||
|
||||
npc_const3 = rvu_read64(rvu, BLKADDR_NPC, NPC_AF_CONST3);
|
||||
if (!(npc_const3 & BIT_ULL(62)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline u16 rvu_nix_chan_cgx(struct rvu *rvu, u8 cgxid,
|
||||
u8 lmacid, u8 chan)
|
||||
{
|
||||
@ -754,7 +769,6 @@ u32 convert_dwrr_mtu_to_bytes(u8 dwrr_mtu);
|
||||
u32 convert_bytes_to_dwrr_mtu(u32 bytes);
|
||||
|
||||
/* NPC APIs */
|
||||
int rvu_npc_init(struct rvu *rvu);
|
||||
void rvu_npc_freemem(struct rvu *rvu);
|
||||
int rvu_npc_get_pkind(struct rvu *rvu, u16 pf);
|
||||
void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf);
|
||||
@ -773,14 +787,17 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf,
|
||||
u64 chan);
|
||||
void rvu_npc_enable_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf,
|
||||
bool enable);
|
||||
|
||||
void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
|
||||
int nixlf, int type, bool enable);
|
||||
void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
bool rvu_npc_enable_mcam_by_entry_index(struct rvu *rvu, int entry, int intf, bool enable);
|
||||
void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
|
||||
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
|
||||
int group, int alg_idx, int mcam_index);
|
||||
|
||||
void rvu_npc_get_mcam_entry_alloc_info(struct rvu *rvu, u16 pcifunc,
|
||||
int blkaddr, int *alloc_cnt,
|
||||
int *enable_cnt);
|
||||
@ -815,6 +832,11 @@ int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
|
||||
int type);
|
||||
bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
|
||||
int index);
|
||||
int rvu_npc_init(struct rvu *rvu);
|
||||
int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
|
||||
u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask,
|
||||
u64 bcast_mcast_val, u64 bcast_mcast_mask);
|
||||
void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx);
|
||||
|
||||
/* CPT APIs */
|
||||
int rvu_cpt_register_interrupts(struct rvu *rvu);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "lmac_common.h"
|
||||
#include "rvu_reg.h"
|
||||
#include "rvu_trace.h"
|
||||
#include "rvu_npc_hash.h"
|
||||
|
||||
struct cgx_evq_entry {
|
||||
struct list_head evq_node;
|
||||
@ -474,6 +475,11 @@ void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc)
|
||||
if (!is_cgx_config_permitted(rvu, pcifunc))
|
||||
return;
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu)) {
|
||||
rvu_npc_exact_reset(rvu, pcifunc);
|
||||
return;
|
||||
}
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
cgx_dev = cgx_get_pdata(cgx_id);
|
||||
lmac_count = cgx_get_lmac_cnt(cgx_dev);
|
||||
@ -584,6 +590,9 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return -EPERM;
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_mac_addr_set(rvu, req, rsp);
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
|
||||
cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr);
|
||||
@ -602,6 +611,9 @@ int rvu_mbox_handler_cgx_mac_addr_add(struct rvu *rvu,
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return -EPERM;
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_mac_addr_add(rvu, req, rsp);
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
rc = cgx_lmac_addr_add(cgx_id, lmac_id, req->mac_addr);
|
||||
if (rc >= 0) {
|
||||
@ -622,6 +634,9 @@ int rvu_mbox_handler_cgx_mac_addr_del(struct rvu *rvu,
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return -EPERM;
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_mac_addr_del(rvu, req, rsp);
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
return cgx_lmac_addr_del(cgx_id, lmac_id, req->index);
|
||||
}
|
||||
@ -643,6 +658,11 @@ int rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu *rvu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu)) {
|
||||
rsp->max_dmac_filters = rvu_npc_exact_get_max_entries(rvu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
rsp->max_dmac_filters = cgx_lmac_addr_max_entries_get(cgx_id, lmac_id);
|
||||
return 0;
|
||||
@ -680,6 +700,10 @@ int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return -EPERM;
|
||||
|
||||
/* Disable drop on non hit rule */
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_promisc_enable(rvu, req->hdr.pcifunc);
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
|
||||
cgx_lmac_promisc_config(cgx_id, lmac_id, true);
|
||||
@ -695,6 +719,10 @@ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return -EPERM;
|
||||
|
||||
/* Disable drop on non hit rule */
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_promisc_disable(rvu, req->hdr.pcifunc);
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
|
||||
cgx_lmac_promisc_config(cgx_id, lmac_id, false);
|
||||
@ -1088,7 +1116,7 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct msg_req *req,
|
||||
int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
|
||||
struct msg_rsp *rsp)
|
||||
{
|
||||
int pf = rvu_get_pf(req->hdr.pcifunc);
|
||||
@ -1098,12 +1126,16 @@ int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct msg_req *req,
|
||||
return LMAC_AF_ERR_PERM_DENIED;
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_mac_addr_reset(rvu, req, rsp);
|
||||
|
||||
return cgx_lmac_addr_reset(cgx_id, lmac_id);
|
||||
}
|
||||
|
||||
int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
|
||||
struct cgx_mac_addr_update_req *req,
|
||||
struct msg_rsp *rsp)
|
||||
struct cgx_mac_addr_update_rsp *rsp)
|
||||
{
|
||||
int pf = rvu_get_pf(req->hdr.pcifunc);
|
||||
u8 cgx_id, lmac_id;
|
||||
@ -1111,6 +1143,9 @@ int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
|
||||
if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
|
||||
return LMAC_AF_ERR_PERM_DENIED;
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
return rvu_npc_exact_mac_addr_update(rvu, req, rsp);
|
||||
|
||||
rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
|
||||
return cgx_lmac_addr_update(cgx_id, lmac_id, req->mac_addr, req->index);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "cgx.h"
|
||||
#include "lmac_common.h"
|
||||
#include "npc.h"
|
||||
#include "rvu_npc_hash.h"
|
||||
|
||||
#define DEBUGFS_DIR_NAME "octeontx2"
|
||||
|
||||
@ -2600,6 +2601,170 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
|
||||
|
||||
RVU_DEBUG_SEQ_FOPS(npc_mcam_rules, npc_mcam_show_rules, NULL);
|
||||
|
||||
static int rvu_dbg_npc_exact_show_entries(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct npc_exact_table_entry *mem_entry[NPC_EXACT_TBL_MAX_WAYS] = { 0 };
|
||||
struct npc_exact_table_entry *cam_entry;
|
||||
struct npc_exact_table *table;
|
||||
struct rvu *rvu = s->private;
|
||||
int i, j;
|
||||
|
||||
u8 bitmap = 0;
|
||||
|
||||
table = rvu->hw->table;
|
||||
|
||||
mutex_lock(&table->lock);
|
||||
|
||||
/* Check if there is at least one entry in mem table */
|
||||
if (!table->mem_tbl_entry_cnt)
|
||||
goto dump_cam_table;
|
||||
|
||||
/* Print table headers */
|
||||
seq_puts(s, "\n\tExact Match MEM Table\n");
|
||||
seq_puts(s, "Index\t");
|
||||
|
||||
for (i = 0; i < table->mem_table.ways; i++) {
|
||||
mem_entry[i] = list_first_entry_or_null(&table->lhead_mem_tbl_entry[i],
|
||||
struct npc_exact_table_entry, list);
|
||||
|
||||
seq_printf(s, "Way-%d\t\t\t\t\t", i);
|
||||
}
|
||||
|
||||
seq_puts(s, "\n");
|
||||
for (i = 0; i < table->mem_table.ways; i++)
|
||||
seq_puts(s, "\tChan MAC \t");
|
||||
|
||||
seq_puts(s, "\n\n");
|
||||
|
||||
/* Print mem table entries */
|
||||
for (i = 0; i < table->mem_table.depth; i++) {
|
||||
bitmap = 0;
|
||||
for (j = 0; j < table->mem_table.ways; j++) {
|
||||
if (!mem_entry[j])
|
||||
continue;
|
||||
|
||||
if (mem_entry[j]->index != i)
|
||||
continue;
|
||||
|
||||
bitmap |= BIT(j);
|
||||
}
|
||||
|
||||
/* No valid entries */
|
||||
if (!bitmap)
|
||||
continue;
|
||||
|
||||
seq_printf(s, "%d\t", i);
|
||||
for (j = 0; j < table->mem_table.ways; j++) {
|
||||
if (!(bitmap & BIT(j))) {
|
||||
seq_puts(s, "nil\t\t\t\t\t");
|
||||
continue;
|
||||
}
|
||||
|
||||
seq_printf(s, "0x%x %pM\t\t\t", mem_entry[j]->chan,
|
||||
mem_entry[j]->mac);
|
||||
mem_entry[j] = list_next_entry(mem_entry[j], list);
|
||||
}
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
|
||||
dump_cam_table:
|
||||
|
||||
if (!table->cam_tbl_entry_cnt)
|
||||
goto done;
|
||||
|
||||
seq_puts(s, "\n\tExact Match CAM Table\n");
|
||||
seq_puts(s, "index\tchan\tMAC\n");
|
||||
|
||||
/* Traverse cam table entries */
|
||||
list_for_each_entry(cam_entry, &table->lhead_cam_tbl_entry, list) {
|
||||
seq_printf(s, "%d\t0x%x\t%pM\n", cam_entry->index, cam_entry->chan,
|
||||
cam_entry->mac);
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&table->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RVU_DEBUG_SEQ_FOPS(npc_exact_entries, npc_exact_show_entries, NULL);
|
||||
|
||||
static int rvu_dbg_npc_exact_show_info(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct npc_exact_table *table;
|
||||
struct rvu *rvu = s->private;
|
||||
int i;
|
||||
|
||||
table = rvu->hw->table;
|
||||
|
||||
seq_puts(s, "\n\tExact Table Info\n");
|
||||
seq_printf(s, "Exact Match Feature : %s\n",
|
||||
rvu->hw->cap.npc_exact_match_enabled ? "enabled" : "disable");
|
||||
if (!rvu->hw->cap.npc_exact_match_enabled)
|
||||
return 0;
|
||||
|
||||
seq_puts(s, "\nMCAM Index\tMAC Filter Rules Count\n");
|
||||
for (i = 0; i < table->num_drop_rules; i++)
|
||||
seq_printf(s, "%d\t\t%d\n", i, table->cnt_cmd_rules[i]);
|
||||
|
||||
seq_puts(s, "\nMcam Index\tPromisc Mode Status\n");
|
||||
for (i = 0; i < table->num_drop_rules; i++)
|
||||
seq_printf(s, "%d\t\t%s\n", i, table->promisc_mode[i] ? "on" : "off");
|
||||
|
||||
seq_puts(s, "\n\tMEM Table Info\n");
|
||||
seq_printf(s, "Ways : %d\n", table->mem_table.ways);
|
||||
seq_printf(s, "Depth : %d\n", table->mem_table.depth);
|
||||
seq_printf(s, "Mask : 0x%llx\n", table->mem_table.mask);
|
||||
seq_printf(s, "Hash Mask : 0x%x\n", table->mem_table.hash_mask);
|
||||
seq_printf(s, "Hash Offset : 0x%x\n", table->mem_table.hash_offset);
|
||||
|
||||
seq_puts(s, "\n\tCAM Table Info\n");
|
||||
seq_printf(s, "Depth : %d\n", table->cam_table.depth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RVU_DEBUG_SEQ_FOPS(npc_exact_info, npc_exact_show_info, NULL);
|
||||
|
||||
static int rvu_dbg_npc_exact_drop_cnt(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct npc_exact_table *table;
|
||||
struct rvu *rvu = s->private;
|
||||
struct npc_key_field *field;
|
||||
u16 chan, pcifunc;
|
||||
int blkaddr, i;
|
||||
u64 cfg, cam1;
|
||||
char *str;
|
||||
|
||||
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
|
||||
table = rvu->hw->table;
|
||||
|
||||
field = &rvu->hw->mcam.rx_key_fields[NPC_CHAN];
|
||||
|
||||
seq_puts(s, "\n\t Exact Hit on drop status\n");
|
||||
seq_puts(s, "\npcifunc\tmcam_idx\tHits\tchan\tstatus\n");
|
||||
|
||||
for (i = 0; i < table->num_drop_rules; i++) {
|
||||
pcifunc = rvu_npc_exact_drop_rule_to_pcifunc(rvu, i);
|
||||
cfg = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_CFG(i, 0));
|
||||
|
||||
/* channel will be always in keyword 0 */
|
||||
cam1 = rvu_read64(rvu, blkaddr,
|
||||
NPC_AF_MCAMEX_BANKX_CAMX_W0(i, 0, 1));
|
||||
chan = field->kw_mask[0] & cam1;
|
||||
|
||||
str = (cfg & 1) ? "enabled" : "disabled";
|
||||
|
||||
seq_printf(s, "0x%x\t%d\t\t%llu\t0x%x\t%s\n", pcifunc, i,
|
||||
rvu_read64(rvu, blkaddr,
|
||||
NPC_AF_MATCH_STATX(table->counter_idx[i])),
|
||||
chan, str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RVU_DEBUG_SEQ_FOPS(npc_exact_drop_cnt, npc_exact_drop_cnt, NULL);
|
||||
|
||||
static void rvu_dbg_npc_init(struct rvu *rvu)
|
||||
{
|
||||
rvu->rvu_dbg.npc = debugfs_create_dir("npc", rvu->rvu_dbg.root);
|
||||
@ -2608,8 +2773,22 @@ static void rvu_dbg_npc_init(struct rvu *rvu)
|
||||
&rvu_dbg_npc_mcam_info_fops);
|
||||
debugfs_create_file("mcam_rules", 0444, rvu->rvu_dbg.npc, rvu,
|
||||
&rvu_dbg_npc_mcam_rules_fops);
|
||||
|
||||
debugfs_create_file("rx_miss_act_stats", 0444, rvu->rvu_dbg.npc, rvu,
|
||||
&rvu_dbg_npc_rx_miss_act_fops);
|
||||
|
||||
if (!rvu->hw->cap.npc_exact_match_enabled)
|
||||
return;
|
||||
|
||||
debugfs_create_file("exact_entries", 0444, rvu->rvu_dbg.npc, rvu,
|
||||
&rvu_dbg_npc_exact_entries_fops);
|
||||
|
||||
debugfs_create_file("exact_info", 0444, rvu->rvu_dbg.npc, rvu,
|
||||
&rvu_dbg_npc_exact_info_fops);
|
||||
|
||||
debugfs_create_file("exact_drop_cnt", 0444, rvu->rvu_dbg.npc, rvu,
|
||||
&rvu_dbg_npc_exact_drop_cnt_fops);
|
||||
|
||||
}
|
||||
|
||||
static int cpt_eng_sts_display(struct seq_file *filp, u8 eng_type)
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "rvu.h"
|
||||
#include "rvu_reg.h"
|
||||
#include "rvu_struct.h"
|
||||
#include "rvu_npc_hash.h"
|
||||
|
||||
#define DRV_NAME "octeontx2-af"
|
||||
|
||||
@ -1436,14 +1437,75 @@ static int rvu_af_dl_dwrr_mtu_get(struct devlink *devlink, u32 id,
|
||||
enum rvu_af_dl_param_id {
|
||||
RVU_AF_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
|
||||
RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
|
||||
RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
|
||||
};
|
||||
|
||||
static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
|
||||
struct rvu *rvu = rvu_dl->rvu;
|
||||
bool enabled;
|
||||
|
||||
enabled = rvu_npc_exact_has_match_table(rvu);
|
||||
|
||||
snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s",
|
||||
enabled ? "enabled" : "disabled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rvu_af_npc_exact_feature_disable(struct devlink *devlink, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
|
||||
struct rvu *rvu = rvu_dl->rvu;
|
||||
|
||||
rvu_npc_exact_disable_feature(rvu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rvu_af_npc_exact_feature_validate(struct devlink *devlink, u32 id,
|
||||
union devlink_param_value val,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
|
||||
struct rvu *rvu = rvu_dl->rvu;
|
||||
u64 enable;
|
||||
|
||||
if (kstrtoull(val.vstr, 10, &enable)) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Only 1 value is supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (enable != 1) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Only disabling exact match feature is supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rvu_npc_exact_can_disable_feature(rvu))
|
||||
return 0;
|
||||
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Can't disable exact match feature; Please try before any configuration");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static const struct devlink_param rvu_af_dl_params[] = {
|
||||
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
|
||||
"dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
|
||||
rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set,
|
||||
rvu_af_dl_dwrr_mtu_validate),
|
||||
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
|
||||
"npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
|
||||
rvu_af_npc_exact_feature_get,
|
||||
rvu_af_npc_exact_feature_disable,
|
||||
rvu_af_npc_exact_feature_validate),
|
||||
};
|
||||
|
||||
/* Devlink switch mode */
|
||||
@ -1501,6 +1563,7 @@ int rvu_register_dl(struct rvu *rvu)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl;
|
||||
struct devlink *dl;
|
||||
size_t size;
|
||||
int err;
|
||||
|
||||
dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
|
||||
@ -1522,8 +1585,12 @@ int rvu_register_dl(struct rvu *rvu)
|
||||
goto err_dl_health;
|
||||
}
|
||||
|
||||
err = devlink_params_register(dl, rvu_af_dl_params,
|
||||
ARRAY_SIZE(rvu_af_dl_params));
|
||||
/* Register exact match devlink only for CN10K-B */
|
||||
size = ARRAY_SIZE(rvu_af_dl_params);
|
||||
if (!rvu_npc_exact_has_match_table(rvu))
|
||||
size -= 1;
|
||||
|
||||
err = devlink_params_register(dl, rvu_af_dl_params, size);
|
||||
if (err) {
|
||||
dev_err(rvu->dev,
|
||||
"devlink params register failed with error %d", err);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "npc.h"
|
||||
#include "cgx.h"
|
||||
#include "lmac_common.h"
|
||||
#include "rvu_npc_hash.h"
|
||||
|
||||
static void nix_free_tx_vtag_entries(struct rvu *rvu, u16 pcifunc);
|
||||
static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req,
|
||||
@ -3792,9 +3793,15 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
|
||||
rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
|
||||
pfvf->rx_chan_base,
|
||||
pfvf->rx_chan_cnt);
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
rvu_npc_exact_promisc_enable(rvu, pcifunc);
|
||||
} else {
|
||||
if (!nix_rx_multicast)
|
||||
rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf, false);
|
||||
|
||||
if (rvu_npc_exact_has_match_table(rvu))
|
||||
rvu_npc_exact_promisc_disable(rvu, pcifunc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "npc.h"
|
||||
#include "cgx.h"
|
||||
#include "npc_profile.h"
|
||||
#include "rvu_npc_hash.h"
|
||||
|
||||
#define RSVD_MCAM_ENTRIES_PER_PF 3 /* Broadcast, Promisc and AllMulticast */
|
||||
#define RSVD_MCAM_ENTRIES_PER_NIXLF 1 /* Ucast for LFs */
|
||||
@ -1105,6 +1106,34 @@ void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
|
||||
NIXLF_PROMISC_ENTRY, false);
|
||||
}
|
||||
|
||||
bool rvu_npc_enable_mcam_by_entry_index(struct rvu *rvu, int entry, int intf, bool enable)
|
||||
{
|
||||
int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
struct rvu_npc_mcam_rule *rule, *tmp;
|
||||
|
||||
mutex_lock(&mcam->lock);
|
||||
|
||||
list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
|
||||
if (rule->intf != intf)
|
||||
continue;
|
||||
|
||||
if (rule->entry != entry)
|
||||
continue;
|
||||
|
||||
rule->enable = enable;
|
||||
mutex_unlock(&mcam->lock);
|
||||
|
||||
npc_enable_mcam_entry(rvu, mcam, blkaddr,
|
||||
entry, enable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
mutex_unlock(&mcam->lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
|
||||
{
|
||||
/* Enables only broadcast match entry. Promisc/Allmulti are enabled
|
||||
@ -1181,14 +1210,6 @@ void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
|
||||
rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
|
||||
}
|
||||
|
||||
#define SET_KEX_LD(intf, lid, ltype, ld, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, ltype, ld), cfg)
|
||||
|
||||
#define SET_KEX_LDFLAGS(intf, ld, flags, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_LDATAX_FLAGSX_CFG(intf, ld, flags), cfg)
|
||||
|
||||
static void npc_program_mkex_rx(struct rvu *rvu, int blkaddr,
|
||||
struct npc_mcam_kex *mkex, u8 intf)
|
||||
{
|
||||
@ -1262,6 +1283,9 @@ static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr,
|
||||
npc_program_mkex_rx(rvu, blkaddr, mkex, intf);
|
||||
npc_program_mkex_tx(rvu, blkaddr, mkex, intf);
|
||||
}
|
||||
|
||||
/* Programme mkex hash profile */
|
||||
npc_program_mkex_hash(rvu, blkaddr);
|
||||
}
|
||||
|
||||
static int npc_fwdb_prfl_img_map(struct rvu *rvu, void __iomem **prfl_img_addr,
|
||||
@ -1463,6 +1487,7 @@ static int npc_prepare_default_kpu(struct npc_kpu_profile_adapter *profile)
|
||||
profile->kpus = ARRAY_SIZE(npc_kpu_profiles);
|
||||
profile->lt_def = &npc_lt_defaults;
|
||||
profile->mkex = &npc_mkex_default;
|
||||
profile->mkex_hash = &npc_mkex_hash_default;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1819,7 +1844,6 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
mcam->hprio_count = mcam->lprio_count;
|
||||
mcam->hprio_end = mcam->hprio_count;
|
||||
|
||||
|
||||
/* Allocate bitmap for managing MCAM counters and memory
|
||||
* for saving counter to RVU PFFUNC allocation mapping.
|
||||
*/
|
||||
@ -2047,6 +2071,7 @@ int rvu_npc_init(struct rvu *rvu)
|
||||
|
||||
rvu_npc_setup_interfaces(rvu, blkaddr);
|
||||
|
||||
npc_config_secret_key(rvu, blkaddr);
|
||||
/* Configure MKEX profile */
|
||||
npc_load_mkex_profile(rvu, blkaddr, rvu->mkex_pfl_name);
|
||||
|
||||
@ -2562,6 +2587,14 @@ alloc:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Marks bitmaps to reserved the mcam slot */
|
||||
void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
|
||||
npc_mcam_set_bit(mcam, entry_idx);
|
||||
}
|
||||
|
||||
int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu,
|
||||
struct npc_mcam_alloc_entry_req *req,
|
||||
struct npc_mcam_alloc_entry_rsp *rsp)
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "rvu_reg.h"
|
||||
#include "rvu.h"
|
||||
#include "npc.h"
|
||||
#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)
|
||||
@ -227,6 +229,25 @@ static bool npc_check_field(struct rvu *rvu, int blkaddr, enum key_fields type,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void npc_scan_exact_result(struct npc_mcam *mcam, u8 bit_number,
|
||||
u8 key_nibble, u8 intf)
|
||||
{
|
||||
u8 offset = (key_nibble * 4) % 64; /* offset within key word */
|
||||
u8 kwi = (key_nibble * 4) / 64; /* which word in key */
|
||||
u8 nr_bits = 4; /* bits in a nibble */
|
||||
u8 type;
|
||||
|
||||
switch (bit_number) {
|
||||
case 40 ... 43:
|
||||
type = NPC_EXACT_RESULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
npc_set_kw_masks(mcam, type, nr_bits, kwi, offset, intf);
|
||||
}
|
||||
|
||||
static void npc_scan_parse_result(struct npc_mcam *mcam, u8 bit_number,
|
||||
u8 key_nibble, u8 intf)
|
||||
{
|
||||
@ -276,6 +297,7 @@ static void npc_scan_parse_result(struct npc_mcam *mcam, u8 bit_number,
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
npc_set_kw_masks(mcam, type, nr_bits, kwi, offset, intf);
|
||||
}
|
||||
|
||||
@ -509,8 +531,8 @@ static int npc_scan_kex(struct rvu *rvu, int blkaddr, u8 intf)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
u8 lid, lt, ld, bitnr;
|
||||
u64 cfg, masked_cfg;
|
||||
u8 key_nibble = 0;
|
||||
u64 cfg;
|
||||
|
||||
/* Scan and note how parse result is going to be in key.
|
||||
* A bit set in PARSE_NIBBLE_ENA corresponds to a nibble from
|
||||
@ -518,12 +540,24 @@ static int npc_scan_kex(struct rvu *rvu, int blkaddr, u8 intf)
|
||||
* will be concatenated in key.
|
||||
*/
|
||||
cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf));
|
||||
cfg &= NPC_PARSE_NIBBLE;
|
||||
for_each_set_bit(bitnr, (unsigned long *)&cfg, 31) {
|
||||
masked_cfg = cfg & NPC_PARSE_NIBBLE;
|
||||
for_each_set_bit(bitnr, (unsigned long *)&masked_cfg, 31) {
|
||||
npc_scan_parse_result(mcam, bitnr, key_nibble, intf);
|
||||
key_nibble++;
|
||||
}
|
||||
|
||||
/* Ignore exact match bits for mcam entries except the first rule
|
||||
* which is drop on hit. This first rule is configured explitcitly by
|
||||
* exact match code.
|
||||
*/
|
||||
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) {
|
||||
npc_scan_exact_result(mcam, bitnr, key_nibble, intf);
|
||||
key_nibble++;
|
||||
}
|
||||
|
||||
/* Scan and note how layer data is going to be in key */
|
||||
for (lid = 0; lid < NPC_MAX_LID; lid++) {
|
||||
for (lt = 0; lt < NPC_MAX_LT; lt++) {
|
||||
@ -624,9 +658,9 @@ static int npc_check_unsupported_flows(struct rvu *rvu, u64 features, u8 intf)
|
||||
* If any bits in mask are 0 then corresponding bits in value are
|
||||
* dont care.
|
||||
*/
|
||||
static void npc_update_entry(struct rvu *rvu, enum key_fields type,
|
||||
struct mcam_entry *entry, u64 val_lo,
|
||||
u64 val_hi, u64 mask_lo, u64 mask_hi, u8 intf)
|
||||
void npc_update_entry(struct rvu *rvu, enum key_fields type,
|
||||
struct mcam_entry *entry, u64 val_lo,
|
||||
u64 val_hi, u64 mask_lo, u64 mask_hi, u8 intf)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
struct mcam_entry dummy = { {0} };
|
||||
@ -705,8 +739,6 @@ static void npc_update_entry(struct rvu *rvu, enum key_fields type,
|
||||
}
|
||||
}
|
||||
|
||||
#define IPV6_WORDS 4
|
||||
|
||||
static void npc_update_ipv6_flow(struct rvu *rvu, struct mcam_entry *entry,
|
||||
u64 features, struct flow_msg *pkt,
|
||||
struct flow_msg *mask,
|
||||
@ -779,7 +811,8 @@ static void npc_update_vlan_features(struct rvu *rvu, struct mcam_entry *entry,
|
||||
static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,
|
||||
u64 features, struct flow_msg *pkt,
|
||||
struct flow_msg *mask,
|
||||
struct rvu_npc_mcam_rule *output, u8 intf)
|
||||
struct rvu_npc_mcam_rule *output, u8 intf,
|
||||
int blkaddr)
|
||||
{
|
||||
u64 dmac_mask = ether_addr_to_u64(mask->dmac);
|
||||
u64 smac_mask = ether_addr_to_u64(mask->smac);
|
||||
@ -828,6 +861,7 @@ do { \
|
||||
} while (0)
|
||||
|
||||
NPC_WRITE_FLOW(NPC_DMAC, dmac, dmac_val, 0, dmac_mask, 0);
|
||||
|
||||
NPC_WRITE_FLOW(NPC_SMAC, smac, smac_val, 0, smac_mask, 0);
|
||||
NPC_WRITE_FLOW(NPC_ETYPE, etype, ntohs(pkt->etype), 0,
|
||||
ntohs(mask->etype), 0);
|
||||
@ -854,10 +888,12 @@ do { \
|
||||
|
||||
npc_update_ipv6_flow(rvu, entry, features, pkt, mask, output, intf);
|
||||
npc_update_vlan_features(rvu, entry, features, intf);
|
||||
|
||||
npc_update_field_hash(rvu, intf, entry, blkaddr, features,
|
||||
pkt, mask, opkt, omask);
|
||||
}
|
||||
|
||||
static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam,
|
||||
u16 entry)
|
||||
static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam, u16 entry)
|
||||
{
|
||||
struct rvu_npc_mcam_rule *iter;
|
||||
|
||||
@ -1023,8 +1059,9 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
|
||||
u16 owner = req->hdr.pcifunc;
|
||||
struct msg_rsp write_rsp;
|
||||
struct mcam_entry *entry;
|
||||
int entry_index, err;
|
||||
bool new = false;
|
||||
u16 entry_index;
|
||||
int err;
|
||||
|
||||
installed_features = req->features;
|
||||
features = req->features;
|
||||
@ -1032,7 +1069,7 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
|
||||
entry_index = req->entry;
|
||||
|
||||
npc_update_flow(rvu, entry, features, &req->packet, &req->mask, &dummy,
|
||||
req->intf);
|
||||
req->intf, blkaddr);
|
||||
|
||||
if (is_npc_intf_rx(req->intf))
|
||||
npc_update_rx_entry(rvu, pfvf, entry, req, target, pf_set_vfs_mac);
|
||||
@ -1057,7 +1094,8 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
|
||||
npc_update_flow(rvu, entry, missing_features,
|
||||
&def_ucast_rule->packet,
|
||||
&def_ucast_rule->mask,
|
||||
&dummy, req->intf);
|
||||
&dummy, req->intf,
|
||||
blkaddr);
|
||||
installed_features = req->features | missing_features;
|
||||
}
|
||||
|
||||
@ -1424,3 +1462,98 @@ void npc_mcam_disable_flows(struct rvu *rvu, u16 target)
|
||||
}
|
||||
mutex_unlock(&mcam->lock);
|
||||
}
|
||||
|
||||
/* single drop on non hit rule starting from 0th index. This an extension
|
||||
* to RPM mac filter to support more rules.
|
||||
*/
|
||||
int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
|
||||
u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask,
|
||||
u64 bcast_mcast_val, u64 bcast_mcast_mask)
|
||||
{
|
||||
struct npc_mcam_alloc_counter_req cntr_req = { 0 };
|
||||
struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 };
|
||||
struct npc_mcam_write_entry_req req = { 0 };
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
struct rvu_npc_mcam_rule *rule;
|
||||
struct msg_rsp rsp;
|
||||
bool enabled;
|
||||
int blkaddr;
|
||||
int err;
|
||||
|
||||
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
|
||||
if (blkaddr < 0) {
|
||||
dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Bail out if no exact match support */
|
||||
if (!rvu_npc_exact_has_match_table(rvu)) {
|
||||
dev_info(rvu->dev, "%s: No support for exact match feature\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If 0th entry is already used, return err */
|
||||
enabled = is_mcam_entry_enabled(rvu, mcam, blkaddr, mcam_idx);
|
||||
if (enabled) {
|
||||
dev_err(rvu->dev, "%s: failed to add single drop on non hit rule at %d th index\n",
|
||||
__func__, mcam_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Add this entry to mcam rules list */
|
||||
rule = kzalloc(sizeof(*rule), GFP_KERNEL);
|
||||
if (!rule)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Disable rule by default. Enable rule when first dmac filter is
|
||||
* installed
|
||||
*/
|
||||
rule->enable = false;
|
||||
rule->chan = chan_val;
|
||||
rule->chan_mask = chan_mask;
|
||||
rule->entry = mcam_idx;
|
||||
rvu_mcam_add_rule(mcam, rule);
|
||||
|
||||
/* Reserve slot 0 */
|
||||
npc_mcam_rsrcs_reserve(rvu, blkaddr, mcam_idx);
|
||||
|
||||
/* Allocate counter for this single drop on non hit rule */
|
||||
cntr_req.hdr.pcifunc = 0; /* AF request */
|
||||
cntr_req.contig = true;
|
||||
cntr_req.count = 1;
|
||||
err = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp);
|
||||
if (err) {
|
||||
dev_err(rvu->dev, "%s: Err to allocate cntr for drop rule (err=%d)\n",
|
||||
__func__, err);
|
||||
return -EFAULT;
|
||||
}
|
||||
*counter_idx = cntr_rsp.cntr;
|
||||
|
||||
/* Fill in fields for this mcam entry */
|
||||
npc_update_entry(rvu, NPC_EXACT_RESULT, &req.entry_data, exact_val, 0,
|
||||
exact_mask, 0, NIX_INTF_RX);
|
||||
npc_update_entry(rvu, NPC_CHAN, &req.entry_data, chan_val, 0,
|
||||
chan_mask, 0, NIX_INTF_RX);
|
||||
npc_update_entry(rvu, NPC_LXMB, &req.entry_data, bcast_mcast_val, 0,
|
||||
bcast_mcast_mask, 0, NIX_INTF_RX);
|
||||
|
||||
req.intf = NIX_INTF_RX;
|
||||
req.set_cntr = true;
|
||||
req.cntr = cntr_rsp.cntr;
|
||||
req.entry = mcam_idx;
|
||||
|
||||
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &req, &rsp);
|
||||
if (err) {
|
||||
dev_err(rvu->dev, "%s: Installation of single drop on non hit rule at %d failed\n",
|
||||
__func__, mcam_idx);
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_err(rvu->dev, "%s: Installed single drop on non hit rule at %d, cntr=%d\n",
|
||||
__func__, mcam_idx, req.cntr);
|
||||
|
||||
/* disable entry at Bank 0, index 0 */
|
||||
npc_enable_mcam_entry(rvu, mcam, blkaddr, mcam_idx, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
17
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.h
Normal file
17
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Marvell RVU Admin Function driver
|
||||
*
|
||||
* Copyright (C) 2022 Marvell.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RVU_NPC_FS_H
|
||||
#define __RVU_NPC_FS_H
|
||||
|
||||
#define IPV6_WORDS 4
|
||||
|
||||
void npc_update_entry(struct rvu *rvu, enum key_fields type,
|
||||
struct mcam_entry *entry, u64 val_lo,
|
||||
u64 val_hi, u64 mask_lo, u64 mask_hi, u8 intf);
|
||||
|
||||
#endif /* RVU_NPC_FS_H */
|
1984
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
Normal file
1984
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
Normal file
File diff suppressed because it is too large
Load Diff
233
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
Normal file
233
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
Normal file
@ -0,0 +1,233 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Marvell RVU Admin Function driver
|
||||
*
|
||||
* Copyright (C) 2022 Marvell.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RVU_NPC_HASH_H
|
||||
#define __RVU_NPC_HASH_H
|
||||
|
||||
#define RVU_NPC_HASH_SECRET_KEY0 0xa9d5af4c9fbc76b1
|
||||
#define RVU_NPC_HASH_SECRET_KEY1 0xa9d5af4c9fbc87b4
|
||||
#define RVU_NPC_HASH_SECRET_KEY2 0x5954c9e7
|
||||
|
||||
#define NPC_MAX_HASH 2
|
||||
#define NPC_MAX_HASH_MASK 2
|
||||
|
||||
#define KEX_LD_CFG_USE_HASH(use_hash, bytesm1, hdr_ofs, ena, flags_ena, key_ofs) \
|
||||
((use_hash) << 20 | ((bytesm1) << 16) | ((hdr_ofs) << 8) | \
|
||||
((ena) << 7) | ((flags_ena) << 6) | ((key_ofs) & 0x3F))
|
||||
#define KEX_LD_CFG_HASH(hdr_ofs, bytesm1, lt_en, lid_en, lid, ltype_match, ltype_mask) \
|
||||
(((hdr_ofs) << 32) | ((bytesm1) << 16) | \
|
||||
((lt_en) << 12) | ((lid_en) << 11) | ((lid) << 8) | \
|
||||
((ltype_match) << 4) | ((ltype_mask) & 0xF))
|
||||
|
||||
#define SET_KEX_LD_HASH(intf, ld, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_HASHX_CFG(intf, ld), cfg)
|
||||
|
||||
#define SET_KEX_LD_HASH_MASK(intf, ld, mask_idx, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_HASHX_MASKX(intf, ld, mask_idx), cfg)
|
||||
|
||||
#define SET_KEX_LD_HASH_CTRL(intf, ld, cfg) \
|
||||
rvu_write64(rvu, blkaddr, \
|
||||
NPC_AF_INTFX_HASHX_RESULT_CTRL(intf, ld), cfg)
|
||||
|
||||
struct npc_mcam_kex_hash {
|
||||
/* NPC_AF_INTF(0..1)_LID(0..7)_LT(0..15)_LD(0..1)_CFG */
|
||||
bool lid_lt_ld_hash_en[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];
|
||||
/* NPC_AF_INTF(0..1)_HASH(0..1)_CFG */
|
||||
u64 hash[NPC_MAX_INTF][NPC_MAX_HASH];
|
||||
/* 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];
|
||||
} __packed;
|
||||
|
||||
void npc_update_field_hash(struct rvu *rvu, u8 intf,
|
||||
struct mcam_entry *entry,
|
||||
int blkaddr,
|
||||
u64 features,
|
||||
struct flow_msg *pkt,
|
||||
struct flow_msg *mask,
|
||||
struct flow_msg *opkt,
|
||||
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);
|
||||
|
||||
static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = {
|
||||
.lid_lt_ld_hash_en = {
|
||||
[NIX_INTF_RX] = {
|
||||
[NPC_LID_LC] = {
|
||||
[NPC_LT_LC_IP6] = {
|
||||
true,
|
||||
true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[NIX_INTF_TX] = {
|
||||
[NPC_LID_LC] = {
|
||||
[NPC_LT_LC_IP6] = {
|
||||
true,
|
||||
true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
.hash = {
|
||||
[NIX_INTF_RX] = {
|
||||
KEX_LD_CFG_HASH(0x8ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf),
|
||||
KEX_LD_CFG_HASH(0x18ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf),
|
||||
},
|
||||
|
||||
[NIX_INTF_TX] = {
|
||||
KEX_LD_CFG_HASH(0x8ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf),
|
||||
KEX_LD_CFG_HASH(0x18ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf),
|
||||
},
|
||||
},
|
||||
|
||||
.hash_mask = {
|
||||
[NIX_INTF_RX] = {
|
||||
[0] = {
|
||||
GENMASK_ULL(63, 0),
|
||||
GENMASK_ULL(63, 0),
|
||||
},
|
||||
[1] = {
|
||||
GENMASK_ULL(63, 0),
|
||||
GENMASK_ULL(63, 0),
|
||||
},
|
||||
},
|
||||
|
||||
[NIX_INTF_TX] = {
|
||||
[0] = {
|
||||
GENMASK_ULL(63, 0),
|
||||
GENMASK_ULL(63, 0),
|
||||
},
|
||||
[1] = {
|
||||
GENMASK_ULL(63, 0),
|
||||
GENMASK_ULL(63, 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
.hash_ctrl = {
|
||||
[NIX_INTF_RX] = {
|
||||
[0] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */
|
||||
[1] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */
|
||||
},
|
||||
|
||||
[NIX_INTF_TX] = {
|
||||
[0] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */
|
||||
[1] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* If exact match table support is enabled, enable drop rules */
|
||||
#define NPC_MCAM_DROP_RULE_MAX 30
|
||||
#define NPC_MCAM_SDP_DROP_RULE_IDX 0
|
||||
|
||||
#define RVU_PFFUNC(pf, func) \
|
||||
((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \
|
||||
(((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT))
|
||||
|
||||
enum npc_exact_opc_type {
|
||||
NPC_EXACT_OPC_MEM,
|
||||
NPC_EXACT_OPC_CAM,
|
||||
};
|
||||
|
||||
struct npc_exact_table_entry {
|
||||
struct list_head list;
|
||||
struct list_head glist;
|
||||
u32 seq_id; /* Sequence number of entry */
|
||||
u32 index; /* Mem table or cam table index */
|
||||
u32 mcam_idx;
|
||||
/* Mcam index. This is valid only if "cmd" field is false */
|
||||
enum npc_exact_opc_type opc_type;
|
||||
u16 chan;
|
||||
u16 pcifunc;
|
||||
u8 ways;
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 ctype;
|
||||
u8 cgx_id;
|
||||
u8 lmac_id;
|
||||
bool cmd; /* Is added by ethtool command ? */
|
||||
};
|
||||
|
||||
struct npc_exact_table {
|
||||
struct mutex lock; /* entries update lock */
|
||||
unsigned long *id_bmap;
|
||||
int num_drop_rules;
|
||||
u32 tot_ids;
|
||||
u16 cnt_cmd_rules[NPC_MCAM_DROP_RULE_MAX];
|
||||
u16 counter_idx[NPC_MCAM_DROP_RULE_MAX];
|
||||
bool promisc_mode[NPC_MCAM_DROP_RULE_MAX];
|
||||
struct {
|
||||
int ways;
|
||||
int depth;
|
||||
unsigned long *bmap;
|
||||
u64 mask; // Masks before hash calculation.
|
||||
u16 hash_mask; // 11 bits for hash mask
|
||||
u16 hash_offset; // 11 bits offset
|
||||
} mem_table;
|
||||
|
||||
struct {
|
||||
int depth;
|
||||
unsigned long *bmap;
|
||||
} cam_table;
|
||||
|
||||
struct {
|
||||
bool valid;
|
||||
u16 chan_val;
|
||||
u16 chan_mask;
|
||||
u16 pcifunc;
|
||||
u8 drop_rule_idx;
|
||||
} drop_rule_map[NPC_MCAM_DROP_RULE_MAX];
|
||||
|
||||
#define NPC_EXACT_TBL_MAX_WAYS 4
|
||||
|
||||
struct list_head lhead_mem_tbl_entry[NPC_EXACT_TBL_MAX_WAYS];
|
||||
int mem_tbl_entry_cnt;
|
||||
|
||||
struct list_head lhead_cam_tbl_entry;
|
||||
int cam_tbl_entry_cnt;
|
||||
|
||||
struct list_head lhead_gbl;
|
||||
};
|
||||
|
||||
bool rvu_npc_exact_has_match_table(struct rvu *rvu);
|
||||
u32 rvu_npc_exact_get_max_entries(struct rvu *rvu);
|
||||
int rvu_npc_exact_init(struct rvu *rvu);
|
||||
int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
|
||||
struct msg_rsp *rsp);
|
||||
|
||||
int rvu_npc_exact_mac_addr_update(struct rvu *rvu,
|
||||
struct cgx_mac_addr_update_req *req,
|
||||
struct cgx_mac_addr_update_rsp *rsp);
|
||||
|
||||
int rvu_npc_exact_mac_addr_add(struct rvu *rvu,
|
||||
struct cgx_mac_addr_add_req *req,
|
||||
struct cgx_mac_addr_add_rsp *rsp);
|
||||
|
||||
int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
|
||||
struct cgx_mac_addr_del_req *req,
|
||||
struct msg_rsp *rsp);
|
||||
|
||||
int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req,
|
||||
struct cgx_mac_addr_set_or_get *rsp);
|
||||
|
||||
void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc);
|
||||
|
||||
bool rvu_npc_exact_can_disable_feature(struct rvu *rvu);
|
||||
void rvu_npc_exact_disable_feature(struct rvu *rvu);
|
||||
void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc);
|
||||
u16 rvu_npc_exact_drop_rule_to_pcifunc(struct rvu *rvu, u32 drop_rule_idx);
|
||||
int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc);
|
||||
int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc);
|
||||
#endif /* RVU_NPC_HASH_H */
|
@ -565,7 +565,13 @@
|
||||
#define NPC_AF_PCK_DEF_OIP4 (0x00620)
|
||||
#define NPC_AF_PCK_DEF_OIP6 (0x00630)
|
||||
#define NPC_AF_PCK_DEF_IIP4 (0x00640)
|
||||
#define NPC_AF_INTFX_HASHX_RESULT_CTRL(a, b) (0x006c0 | (a) << 4 | (b) << 3)
|
||||
#define NPC_AF_INTFX_HASHX_MASKX(a, b, c) (0x00700 | (a) << 5 | (b) << 4 | (c) << 3)
|
||||
#define NPC_AF_KEX_LDATAX_FLAGS_CFG(a) (0x00800 | (a) << 3)
|
||||
#define NPC_AF_INTFX_HASHX_CFG(a, b) (0x00b00 | (a) << 6 | (b) << 4)
|
||||
#define NPC_AF_INTFX_SECRET_KEY0(a) (0x00e00 | (a) << 3)
|
||||
#define NPC_AF_INTFX_SECRET_KEY1(a) (0x00e20 | (a) << 3)
|
||||
#define NPC_AF_INTFX_SECRET_KEY2(a) (0x00e40 | (a) << 3)
|
||||
#define NPC_AF_INTFX_KEX_CFG(a) (0x01010 | (a) << 8)
|
||||
#define NPC_AF_PKINDX_ACTION0(a) (0x80000ull | (a) << 6)
|
||||
#define NPC_AF_PKINDX_ACTION1(a) (0x80008ull | (a) << 6)
|
||||
@ -599,6 +605,15 @@
|
||||
#define NPC_AF_DBG_DATAX(a) (0x3001400 | (a) << 4)
|
||||
#define NPC_AF_DBG_RESULTX(a) (0x3001800 | (a) << 4)
|
||||
|
||||
#define NPC_AF_EXACT_MEM_ENTRY(a, b) (0x300000 | (a) << 15 | (b) << 3)
|
||||
#define NPC_AF_EXACT_CAM_ENTRY(a) (0xC00 | (a) << 3)
|
||||
#define NPC_AF_INTFX_EXACT_MASK(a) (0x660 | (a) << 3)
|
||||
#define NPC_AF_INTFX_EXACT_RESULT_CTL(a)(0x680 | (a) << 3)
|
||||
#define NPC_AF_INTFX_EXACT_CFG(a) (0xA00 | (a) << 3)
|
||||
#define NPC_AF_INTFX_EXACT_SECRET0(a) (0xE00 | (a) << 3)
|
||||
#define NPC_AF_INTFX_EXACT_SECRET1(a) (0xE20 | (a) << 3)
|
||||
#define NPC_AF_INTFX_EXACT_SECRET2(a) (0xE40 | (a) << 3)
|
||||
|
||||
#define NPC_AF_MCAMEX_BANKX_CAMX_INTF(a, b, c) ({ \
|
||||
u64 offset; \
|
||||
\
|
||||
|
@ -314,8 +314,8 @@ struct otx2_flow_config {
|
||||
#define OTX2_VF_VLAN_TX_INDEX 1
|
||||
u16 max_flows;
|
||||
u8 dmacflt_max_flows;
|
||||
u8 *bmap_to_dmacindex;
|
||||
unsigned long dmacflt_bmap;
|
||||
u32 *bmap_to_dmacindex;
|
||||
unsigned long *dmacflt_bmap;
|
||||
struct list_head flow_list;
|
||||
};
|
||||
|
||||
@ -895,9 +895,9 @@ int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
|
||||
int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic);
|
||||
/* CGX/RPM DMAC filters support */
|
||||
int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf);
|
||||
int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
|
||||
int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
|
||||
int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos);
|
||||
int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos);
|
||||
int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, u32 bit_pos);
|
||||
int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u32 bit_pos);
|
||||
void otx2_dmacflt_reinstall_flows(struct otx2_nic *pf);
|
||||
void otx2_dmacflt_update_pfmac_flow(struct otx2_nic *pfvf);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "otx2_common.h"
|
||||
|
||||
static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
|
||||
u8 *dmac_index)
|
||||
u32 *dmac_index)
|
||||
{
|
||||
struct cgx_mac_addr_add_req *req;
|
||||
struct cgx_mac_addr_add_rsp *rsp;
|
||||
@ -35,9 +35,10 @@ static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf)
|
||||
static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf, u32 *dmac_index)
|
||||
{
|
||||
struct cgx_mac_addr_set_or_get *req;
|
||||
struct cgx_mac_addr_set_or_get *rsp;
|
||||
int err;
|
||||
|
||||
mutex_lock(&pf->mbox.lock);
|
||||
@ -48,16 +49,24 @@ static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
req->index = *dmac_index;
|
||||
|
||||
ether_addr_copy(req->mac_addr, pf->netdev->dev_addr);
|
||||
err = otx2_sync_mbox_msg(&pf->mbox);
|
||||
|
||||
if (!err) {
|
||||
rsp = (struct cgx_mac_addr_set_or_get *)
|
||||
otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
|
||||
*dmac_index = rsp->index;
|
||||
}
|
||||
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos)
|
||||
int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos)
|
||||
{
|
||||
u8 *dmacindex;
|
||||
u32 *dmacindex;
|
||||
|
||||
/* Store dmacindex returned by CGX/RPM driver which will
|
||||
* be used for macaddr update/remove
|
||||
@ -65,13 +74,13 @@ int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos)
|
||||
dmacindex = &pf->flow_cfg->bmap_to_dmacindex[bit_pos];
|
||||
|
||||
if (ether_addr_equal(mac, pf->netdev->dev_addr))
|
||||
return otx2_dmacflt_add_pfmac(pf);
|
||||
return otx2_dmacflt_add_pfmac(pf, dmacindex);
|
||||
else
|
||||
return otx2_dmacflt_do_add(pf, mac, dmacindex);
|
||||
}
|
||||
|
||||
static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac,
|
||||
u8 dmac_index)
|
||||
u32 dmac_index)
|
||||
{
|
||||
struct cgx_mac_addr_del_req *req;
|
||||
int err;
|
||||
@ -91,9 +100,9 @@ static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
|
||||
static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf, u32 dmac_index)
|
||||
{
|
||||
struct msg_req *req;
|
||||
struct cgx_mac_addr_reset_req *req;
|
||||
int err;
|
||||
|
||||
mutex_lock(&pf->mbox.lock);
|
||||
@ -102,6 +111,7 @@ static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
req->index = dmac_index;
|
||||
|
||||
err = otx2_sync_mbox_msg(&pf->mbox);
|
||||
|
||||
@ -110,12 +120,12 @@ static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
|
||||
}
|
||||
|
||||
int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac,
|
||||
u8 bit_pos)
|
||||
u32 bit_pos)
|
||||
{
|
||||
u8 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
|
||||
u32 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
|
||||
|
||||
if (ether_addr_equal(mac, pf->netdev->dev_addr))
|
||||
return otx2_dmacflt_remove_pfmac(pf);
|
||||
return otx2_dmacflt_remove_pfmac(pf, dmacindex);
|
||||
else
|
||||
return otx2_dmacflt_do_remove(pf, mac, dmacindex);
|
||||
}
|
||||
@ -151,9 +161,10 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos)
|
||||
int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u32 bit_pos)
|
||||
{
|
||||
struct cgx_mac_addr_update_req *req;
|
||||
struct cgx_mac_addr_update_rsp *rsp;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&pf->mbox.lock);
|
||||
@ -167,8 +178,19 @@ int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos)
|
||||
|
||||
ether_addr_copy(req->mac_addr, mac);
|
||||
req->index = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
|
||||
rc = otx2_sync_mbox_msg(&pf->mbox);
|
||||
|
||||
/* check the response and change index */
|
||||
|
||||
rc = otx2_sync_mbox_msg(&pf->mbox);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rsp = (struct cgx_mac_addr_update_rsp *)
|
||||
otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
|
||||
|
||||
pf->flow_cfg->bmap_to_dmacindex[bit_pos] = rsp->index;
|
||||
|
||||
out:
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
return rc;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ struct otx2_flow {
|
||||
struct ethtool_rx_flow_spec flow_spec;
|
||||
struct list_head list;
|
||||
u32 location;
|
||||
u16 entry;
|
||||
u32 entry;
|
||||
bool is_vf;
|
||||
u8 rss_ctx_id;
|
||||
#define DMAC_FILTER_RULE BIT(0)
|
||||
@ -232,6 +232,9 @@ static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO : revisit on size */
|
||||
#define OTX2_DMAC_FLTR_BITMAP_SZ (4 * 2048 + 32)
|
||||
|
||||
int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)
|
||||
{
|
||||
struct otx2_flow_config *flow_cfg;
|
||||
@ -242,6 +245,12 @@ int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)
|
||||
if (!pfvf->flow_cfg)
|
||||
return -ENOMEM;
|
||||
|
||||
pfvf->flow_cfg->dmacflt_bmap = devm_kcalloc(pfvf->dev,
|
||||
BITS_TO_LONGS(OTX2_DMAC_FLTR_BITMAP_SZ),
|
||||
sizeof(long), GFP_KERNEL);
|
||||
if (!pfvf->flow_cfg->dmacflt_bmap)
|
||||
return -ENOMEM;
|
||||
|
||||
flow_cfg = pfvf->flow_cfg;
|
||||
INIT_LIST_HEAD(&flow_cfg->flow_list);
|
||||
flow_cfg->max_flows = 0;
|
||||
@ -259,6 +268,12 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
|
||||
if (!pf->flow_cfg)
|
||||
return -ENOMEM;
|
||||
|
||||
pf->flow_cfg->dmacflt_bmap = devm_kcalloc(pf->dev,
|
||||
BITS_TO_LONGS(OTX2_DMAC_FLTR_BITMAP_SZ),
|
||||
sizeof(long), GFP_KERNEL);
|
||||
if (!pf->flow_cfg->dmacflt_bmap)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&pf->flow_cfg->flow_list);
|
||||
|
||||
/* Allocate bare minimum number of MCAM entries needed for
|
||||
@ -284,7 +299,7 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
|
||||
return 0;
|
||||
|
||||
pf->flow_cfg->bmap_to_dmacindex =
|
||||
devm_kzalloc(pf->dev, sizeof(u8) *
|
||||
devm_kzalloc(pf->dev, sizeof(u32) *
|
||||
pf->flow_cfg->dmacflt_max_flows,
|
||||
GFP_KERNEL);
|
||||
|
||||
@ -355,7 +370,7 @@ int otx2_add_macfilter(struct net_device *netdev, const u8 *mac)
|
||||
{
|
||||
struct otx2_nic *pf = netdev_priv(netdev);
|
||||
|
||||
if (!bitmap_empty(&pf->flow_cfg->dmacflt_bmap,
|
||||
if (!bitmap_empty(pf->flow_cfg->dmacflt_bmap,
|
||||
pf->flow_cfg->dmacflt_max_flows))
|
||||
netdev_warn(netdev,
|
||||
"Add %pM to CGX/RPM DMAC filters list as well\n",
|
||||
@ -438,7 +453,7 @@ int otx2_get_maxflows(struct otx2_flow_config *flow_cfg)
|
||||
return 0;
|
||||
|
||||
if (flow_cfg->nr_flows == flow_cfg->max_flows ||
|
||||
!bitmap_empty(&flow_cfg->dmacflt_bmap,
|
||||
!bitmap_empty(flow_cfg->dmacflt_bmap,
|
||||
flow_cfg->dmacflt_max_flows))
|
||||
return flow_cfg->max_flows + flow_cfg->dmacflt_max_flows;
|
||||
else
|
||||
@ -1010,7 +1025,7 @@ static int otx2_add_flow_with_pfmac(struct otx2_nic *pfvf,
|
||||
|
||||
otx2_add_flow_to_list(pfvf, pf_mac);
|
||||
pfvf->flow_cfg->nr_flows++;
|
||||
set_bit(0, &pfvf->flow_cfg->dmacflt_bmap);
|
||||
set_bit(0, pfvf->flow_cfg->dmacflt_bmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1064,7 +1079,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
||||
return otx2_dmacflt_update(pfvf, eth_hdr->h_dest,
|
||||
flow->entry);
|
||||
|
||||
if (bitmap_full(&flow_cfg->dmacflt_bmap,
|
||||
if (bitmap_full(flow_cfg->dmacflt_bmap,
|
||||
flow_cfg->dmacflt_max_flows)) {
|
||||
netdev_warn(pfvf->netdev,
|
||||
"Can't insert the rule %d as max allowed dmac filters are %d\n",
|
||||
@ -1078,17 +1093,17 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
||||
}
|
||||
|
||||
/* Install PF mac address to DMAC filter list */
|
||||
if (!test_bit(0, &flow_cfg->dmacflt_bmap))
|
||||
if (!test_bit(0, flow_cfg->dmacflt_bmap))
|
||||
otx2_add_flow_with_pfmac(pfvf, flow);
|
||||
|
||||
flow->rule_type |= DMAC_FILTER_RULE;
|
||||
flow->entry = find_first_zero_bit(&flow_cfg->dmacflt_bmap,
|
||||
flow->entry = find_first_zero_bit(flow_cfg->dmacflt_bmap,
|
||||
flow_cfg->dmacflt_max_flows);
|
||||
fsp->location = flow_cfg->max_flows + flow->entry;
|
||||
flow->flow_spec.location = fsp->location;
|
||||
flow->location = fsp->location;
|
||||
|
||||
set_bit(flow->entry, &flow_cfg->dmacflt_bmap);
|
||||
set_bit(flow->entry, flow_cfg->dmacflt_bmap);
|
||||
otx2_dmacflt_add(pfvf, eth_hdr->h_dest, flow->entry);
|
||||
|
||||
} else {
|
||||
@ -1154,11 +1169,12 @@ static void otx2_update_rem_pfmac(struct otx2_nic *pfvf, int req)
|
||||
if (req == DMAC_ADDR_DEL) {
|
||||
otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,
|
||||
0);
|
||||
clear_bit(0, &pfvf->flow_cfg->dmacflt_bmap);
|
||||
clear_bit(0, pfvf->flow_cfg->dmacflt_bmap);
|
||||
found = true;
|
||||
} else {
|
||||
ether_addr_copy(eth_hdr->h_dest,
|
||||
pfvf->netdev->dev_addr);
|
||||
|
||||
otx2_dmacflt_update(pfvf, eth_hdr->h_dest, 0);
|
||||
}
|
||||
break;
|
||||
@ -1194,12 +1210,12 @@ int otx2_remove_flow(struct otx2_nic *pfvf, u32 location)
|
||||
|
||||
err = otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,
|
||||
flow->entry);
|
||||
clear_bit(flow->entry, &flow_cfg->dmacflt_bmap);
|
||||
clear_bit(flow->entry, flow_cfg->dmacflt_bmap);
|
||||
/* If all dmac filters are removed delete macfilter with
|
||||
* interface mac address and configure CGX/RPM block in
|
||||
* promiscuous mode
|
||||
*/
|
||||
if (bitmap_weight(&flow_cfg->dmacflt_bmap,
|
||||
if (bitmap_weight(flow_cfg->dmacflt_bmap,
|
||||
flow_cfg->dmacflt_max_flows) == 1)
|
||||
otx2_update_rem_pfmac(pfvf, DMAC_ADDR_DEL);
|
||||
} else {
|
||||
|
@ -1120,7 +1120,7 @@ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
|
||||
struct msg_req *msg;
|
||||
int err;
|
||||
|
||||
if (enable && !bitmap_empty(&pf->flow_cfg->dmacflt_bmap,
|
||||
if (enable && !bitmap_empty(pf->flow_cfg->dmacflt_bmap,
|
||||
pf->flow_cfg->dmacflt_max_flows))
|
||||
netdev_warn(pf->netdev,
|
||||
"CGX/RPM internal loopback might not work as DMAC filters are active\n");
|
||||
|
Loading…
Reference in New Issue
Block a user