Commit 3eaf3ca6 authored by David S. Miller's avatar David S. Miller

Merge branch 'octeontx2-next'

Jerin Jacob says:

====================
octeontx2-af: NIX and NPC enhancements

This patchset is a continuation to earlier submitted four patch
series to add a new driver for Marvell's OcteonTX2 SOC's
Resource virtualization unit (RVU) admin function driver.

1. octeontx2-af: Add RVU Admin Function driver
   https://www.spinics.net/lists/netdev/msg528272.html
2. octeontx2-af: NPA and NIX blocks initialization
   https://www.spinics.net/lists/netdev/msg529163.html
3. octeontx2-af: NPC parser and NIX blocks initialization
   https://www.spinics.net/lists/netdev/msg530252.html
4. octeontx2-af: NPC MCAM support and FLR handling
   https://www.spinics.net/lists/netdev/msg534392.html

This patch series adds support for below

NPC block:
- Add NPC(mkex) profile support for various Key extraction configurations

NIX block:
- Enable dynamic RSS flow key algorithm configuration
- Enhancements on Rx checksum and error checks
- Add support for Tx packet marking support
- TL1 schedule queue allocation enhancements
- Add LSO format configuration mbox
- VLAN TPID configuration
- Skip multicast entry init for broadcast tables

v2:

- Rename FLOW_* to NIX_FLOW_* to avoid serious global namespace collisions,
as we have various FLOW_* definitions coming from
include/uapi/linux/pkt_cls.h for example.(David Miller)
- Pack the arguments of rvu_get_tl1_schqs() function
as 80 columns allows.(David Miller)
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6e360f73 23705adb
...@@ -498,6 +498,60 @@ static inline bool cgx_event_is_linkevent(u64 event) ...@@ -498,6 +498,60 @@ static inline bool cgx_event_is_linkevent(u64 event)
return false; return false;
} }
static inline int cgx_fwi_get_mkex_prfl_sz(u64 *prfl_sz,
struct cgx *cgx)
{
u64 req = 0;
u64 resp;
int err;
req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_MKEX_PRFL_SIZE, req);
err = cgx_fwi_cmd_generic(req, &resp, cgx, 0);
if (!err)
*prfl_sz = FIELD_GET(RESP_MKEX_PRFL_SIZE, resp);
return err;
}
static inline int cgx_fwi_get_mkex_prfl_addr(u64 *prfl_addr,
struct cgx *cgx)
{
u64 req = 0;
u64 resp;
int err;
req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_MKEX_PRFL_ADDR, req);
err = cgx_fwi_cmd_generic(req, &resp, cgx, 0);
if (!err)
*prfl_addr = FIELD_GET(RESP_MKEX_PRFL_ADDR, resp);
return err;
}
int cgx_get_mkex_prfl_info(u64 *addr, u64 *size)
{
struct cgx *cgx_dev;
int err;
if (!addr || !size)
return -EINVAL;
cgx_dev = list_first_entry(&cgx_list, struct cgx, cgx_list);
if (!cgx_dev)
return -ENXIO;
err = cgx_fwi_get_mkex_prfl_sz(size, cgx_dev);
if (err)
return -EIO;
err = cgx_fwi_get_mkex_prfl_addr(addr, cgx_dev);
if (err)
return -EIO;
return 0;
}
EXPORT_SYMBOL(cgx_get_mkex_prfl_info);
static irqreturn_t cgx_fwi_event_handler(int irq, void *data) static irqreturn_t cgx_fwi_event_handler(int irq, void *data)
{ {
struct lmac *lmac = data; struct lmac *lmac = data;
......
...@@ -111,4 +111,5 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable); ...@@ -111,4 +111,5 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable);
int cgx_get_link_info(void *cgxd, int lmac_id, int cgx_get_link_info(void *cgxd, int lmac_id,
struct cgx_link_user_info *linfo); struct cgx_link_user_info *linfo);
int cgx_lmac_linkup_start(void *cgxd); int cgx_lmac_linkup_start(void *cgxd);
int cgx_get_mkex_prfl_info(u64 *addr, u64 *size);
#endif /* CGX_H */ #endif /* CGX_H */
...@@ -78,6 +78,8 @@ enum cgx_cmd_id { ...@@ -78,6 +78,8 @@ enum cgx_cmd_id {
CGX_CMD_LINK_STATE_CHANGE, CGX_CMD_LINK_STATE_CHANGE,
CGX_CMD_MODE_CHANGE, /* hot plug support */ CGX_CMD_MODE_CHANGE, /* hot plug support */
CGX_CMD_INTF_SHUTDOWN, CGX_CMD_INTF_SHUTDOWN,
CGX_CMD_GET_MKEX_PRFL_SIZE,
CGX_CMD_GET_MKEX_PRFL_ADDR
}; };
/* async event ids */ /* async event ids */
...@@ -137,6 +139,16 @@ enum cgx_cmd_own { ...@@ -137,6 +139,16 @@ enum cgx_cmd_own {
*/ */
#define RESP_MAC_ADDR GENMASK_ULL(56, 9) #define RESP_MAC_ADDR GENMASK_ULL(56, 9)
/* Response to cmd ID as CGX_CMD_GET_MKEX_PRFL_SIZE with cmd status as
* CGX_STAT_SUCCESS
*/
#define RESP_MKEX_PRFL_SIZE GENMASK_ULL(63, 9)
/* Response to cmd ID as CGX_CMD_GET_MKEX_PRFL_ADDR with cmd status as
* CGX_STAT_SUCCESS
*/
#define RESP_MKEX_PRFL_ADDR GENMASK_ULL(63, 9)
/* Response to cmd ID - CGX_CMD_LINK_BRING_UP/DOWN, event ID CGX_EVT_LINK_CHANGE /* Response to cmd ID - CGX_CMD_LINK_BRING_UP/DOWN, event ID CGX_EVT_LINK_CHANGE
* status can be either CGX_STAT_FAIL or CGX_STAT_SUCCESS * status can be either CGX_STAT_FAIL or CGX_STAT_SUCCESS
* *
......
...@@ -143,6 +143,9 @@ enum nix_scheduler { ...@@ -143,6 +143,9 @@ enum nix_scheduler {
NIX_TXSCH_LVL_CNT = 0x5, NIX_TXSCH_LVL_CNT = 0x5,
}; };
#define TXSCH_TL1_DFLT_RR_QTM ((1 << 24) - 1)
#define TXSCH_TL1_DFLT_RR_PRIO (0x1ull)
/* Min/Max packet sizes, excluding FCS */ /* Min/Max packet sizes, excluding FCS */
#define NIC_HW_MIN_FRS 40 #define NIC_HW_MIN_FRS 40
#define NIC_HW_MAX_FRS 9212 #define NIC_HW_MAX_FRS 9212
...@@ -193,26 +196,4 @@ enum nix_scheduler { ...@@ -193,26 +196,4 @@ enum nix_scheduler {
#define DEFAULT_RSS_CONTEXT_GROUP 0 #define DEFAULT_RSS_CONTEXT_GROUP 0
#define MAX_RSS_INDIR_TBL_SIZE 256 /* 1 << Max adder bits */ #define MAX_RSS_INDIR_TBL_SIZE 256 /* 1 << Max adder bits */
/* NIX flow tag, key type flags */
#define FLOW_KEY_TYPE_PORT BIT(0)
#define FLOW_KEY_TYPE_IPV4 BIT(1)
#define FLOW_KEY_TYPE_IPV6 BIT(2)
#define FLOW_KEY_TYPE_TCP BIT(3)
#define FLOW_KEY_TYPE_UDP BIT(4)
#define FLOW_KEY_TYPE_SCTP BIT(5)
/* NIX flow tag algorithm indices, max is 31 */
enum {
FLOW_KEY_ALG_PORT,
FLOW_KEY_ALG_IP,
FLOW_KEY_ALG_TCP,
FLOW_KEY_ALG_UDP,
FLOW_KEY_ALG_SCTP,
FLOW_KEY_ALG_TCP_UDP,
FLOW_KEY_ALG_TCP_SCTP,
FLOW_KEY_ALG_UDP_SCTP,
FLOW_KEY_ALG_TCP_UDP_SCTP,
FLOW_KEY_ALG_MAX,
};
#endif /* COMMON_H */ #endif /* COMMON_H */
...@@ -193,12 +193,20 @@ M(NIX_TXSCHQ_CFG, 0x8006, nix_txschq_cfg, nix_txschq_config, msg_rsp) \ ...@@ -193,12 +193,20 @@ M(NIX_TXSCHQ_CFG, 0x8006, nix_txschq_cfg, nix_txschq_config, msg_rsp) \
M(NIX_STATS_RST, 0x8007, nix_stats_rst, msg_req, msg_rsp) \ M(NIX_STATS_RST, 0x8007, nix_stats_rst, msg_req, msg_rsp) \
M(NIX_VTAG_CFG, 0x8008, nix_vtag_cfg, nix_vtag_config, msg_rsp) \ M(NIX_VTAG_CFG, 0x8008, nix_vtag_cfg, nix_vtag_config, msg_rsp) \
M(NIX_RSS_FLOWKEY_CFG, 0x8009, nix_rss_flowkey_cfg, \ M(NIX_RSS_FLOWKEY_CFG, 0x8009, nix_rss_flowkey_cfg, \
nix_rss_flowkey_cfg, msg_rsp) \ nix_rss_flowkey_cfg, \
nix_rss_flowkey_cfg_rsp) \
M(NIX_SET_MAC_ADDR, 0x800a, nix_set_mac_addr, nix_set_mac_addr, msg_rsp) \ M(NIX_SET_MAC_ADDR, 0x800a, nix_set_mac_addr, nix_set_mac_addr, msg_rsp) \
M(NIX_SET_RX_MODE, 0x800b, nix_set_rx_mode, nix_rx_mode, msg_rsp) \ M(NIX_SET_RX_MODE, 0x800b, nix_set_rx_mode, nix_rx_mode, msg_rsp) \
M(NIX_SET_HW_FRS, 0x800c, nix_set_hw_frs, nix_frs_cfg, msg_rsp) \ M(NIX_SET_HW_FRS, 0x800c, nix_set_hw_frs, nix_frs_cfg, msg_rsp) \
M(NIX_LF_START_RX, 0x800d, nix_lf_start_rx, msg_req, msg_rsp) \ M(NIX_LF_START_RX, 0x800d, nix_lf_start_rx, msg_req, msg_rsp) \
M(NIX_LF_STOP_RX, 0x800e, nix_lf_stop_rx, msg_req, msg_rsp) \ M(NIX_LF_STOP_RX, 0x800e, nix_lf_stop_rx, msg_req, msg_rsp) \
M(NIX_MARK_FORMAT_CFG, 0x800f, nix_mark_format_cfg, \
nix_mark_format_cfg, \
nix_mark_format_cfg_rsp) \
M(NIX_SET_RX_CFG, 0x8010, nix_set_rx_cfg, nix_rx_cfg, msg_rsp) \
M(NIX_LSO_FORMAT_CFG, 0x8011, nix_lso_format_cfg, \
nix_lso_format_cfg, \
nix_lso_format_cfg_rsp) \
M(NIX_RXVLAN_ALLOC, 0x8012, nix_rxvlan_alloc, msg_req, msg_rsp) M(NIX_RXVLAN_ALLOC, 0x8012, nix_rxvlan_alloc, msg_req, msg_rsp)
/* Messages initiated by AF (range 0xC00 - 0xDFF) */ /* Messages initiated by AF (range 0xC00 - 0xDFF) */
...@@ -413,6 +421,10 @@ enum nix_af_status { ...@@ -413,6 +421,10 @@ enum nix_af_status {
NIX_AF_INVAL_TXSCHQ_CFG = -412, NIX_AF_INVAL_TXSCHQ_CFG = -412,
NIX_AF_SMQ_FLUSH_FAILED = -413, NIX_AF_SMQ_FLUSH_FAILED = -413,
NIX_AF_ERR_LF_RESET = -414, NIX_AF_ERR_LF_RESET = -414,
NIX_AF_ERR_RSS_NOSPC_FIELD = -415,
NIX_AF_ERR_RSS_NOSPC_ALGO = -416,
NIX_AF_ERR_MARK_CFG_FAIL = -417,
NIX_AF_ERR_LSO_CFG_FAIL = -418,
NIX_AF_INVAL_NPA_PF_FUNC = -419, NIX_AF_INVAL_NPA_PF_FUNC = -419,
NIX_AF_INVAL_SSO_PF_FUNC = -420, NIX_AF_INVAL_SSO_PF_FUNC = -420,
}; };
...@@ -560,15 +572,40 @@ struct nix_vtag_config { ...@@ -560,15 +572,40 @@ struct nix_vtag_config {
struct nix_rss_flowkey_cfg { struct nix_rss_flowkey_cfg {
struct mbox_msghdr hdr; struct mbox_msghdr hdr;
int mcam_index; /* MCAM entry index to modify */ int mcam_index; /* MCAM entry index to modify */
#define NIX_FLOW_KEY_TYPE_PORT BIT(0)
#define NIX_FLOW_KEY_TYPE_IPV4 BIT(1)
#define NIX_FLOW_KEY_TYPE_IPV6 BIT(2)
#define NIX_FLOW_KEY_TYPE_TCP BIT(3)
#define NIX_FLOW_KEY_TYPE_UDP BIT(4)
#define NIX_FLOW_KEY_TYPE_SCTP BIT(5)
u32 flowkey_cfg; /* Flowkey types selected */ u32 flowkey_cfg; /* Flowkey types selected */
u8 group; /* RSS context or group */ u8 group; /* RSS context or group */
}; };
struct nix_rss_flowkey_cfg_rsp {
struct mbox_msghdr hdr;
u8 alg_idx; /* Selected algo index */
};
struct nix_set_mac_addr { struct nix_set_mac_addr {
struct mbox_msghdr hdr; struct mbox_msghdr hdr;
u8 mac_addr[ETH_ALEN]; /* MAC address to be set for this pcifunc */ u8 mac_addr[ETH_ALEN]; /* MAC address to be set for this pcifunc */
}; };
struct nix_mark_format_cfg {
struct mbox_msghdr hdr;
u8 offset;
u8 y_mask;
u8 y_val;
u8 r_mask;
u8 r_val;
};
struct nix_mark_format_cfg_rsp {
struct mbox_msghdr hdr;
u8 mark_format_idx;
};
struct nix_rx_mode { struct nix_rx_mode {
struct mbox_msghdr hdr; struct mbox_msghdr hdr;
#define NIX_RX_MODE_UCAST BIT(0) #define NIX_RX_MODE_UCAST BIT(0)
...@@ -577,6 +614,15 @@ struct nix_rx_mode { ...@@ -577,6 +614,15 @@ struct nix_rx_mode {
u16 mode; u16 mode;
}; };
struct nix_rx_cfg {
struct mbox_msghdr hdr;
#define NIX_RX_OL3_VERIFY BIT(0)
#define NIX_RX_OL4_VERIFY BIT(1)
u8 len_verify; /* Outer L3/L4 len check */
#define NIX_RX_CSUM_OL4_VERIFY BIT(0)
u8 csum_verify; /* Outer L4 checksum verification */
};
struct nix_frs_cfg { struct nix_frs_cfg {
struct mbox_msghdr hdr; struct mbox_msghdr hdr;
u8 update_smq; /* Update SMQ's min/max lens */ u8 update_smq; /* Update SMQ's min/max lens */
...@@ -586,6 +632,18 @@ struct nix_frs_cfg { ...@@ -586,6 +632,18 @@ struct nix_frs_cfg {
u16 minlen; u16 minlen;
}; };
struct nix_lso_format_cfg {
struct mbox_msghdr hdr;
u64 field_mask;
#define NIX_LSO_FIELD_MAX 8
u64 fields[NIX_LSO_FIELD_MAX];
};
struct nix_lso_format_cfg_rsp {
struct mbox_msghdr hdr;
u8 lso_format_idx;
};
/* NPC mbox message structs */ /* NPC mbox message structs */
#define NPC_MCAM_ENTRY_INVALID 0xFFFF #define NPC_MCAM_ENTRY_INVALID 0xFFFF
...@@ -730,6 +788,8 @@ struct npc_get_kex_cfg_rsp { ...@@ -730,6 +788,8 @@ struct npc_get_kex_cfg_rsp {
u64 intf_lid_lt_ld[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD]; u64 intf_lid_lt_ld[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];
/* NPC_AF_INTF(0..1)_LDATA(0..1)_FLAGS(0..15)_CFG */ /* NPC_AF_INTF(0..1)_LDATA(0..1)_FLAGS(0..15)_CFG */
u64 intf_ld_flags[NPC_MAX_INTF][NPC_MAX_LD][NPC_MAX_LFL]; u64 intf_ld_flags[NPC_MAX_INTF][NPC_MAX_LD][NPC_MAX_LFL];
#define MKEX_NAME_LEN 128
u8 mkex_pfl_name[MKEX_NAME_LEN];
}; };
#endif /* MBOX_H */ #endif /* MBOX_H */
...@@ -265,4 +265,22 @@ struct nix_rx_action { ...@@ -265,4 +265,22 @@ struct nix_rx_action {
#define VTAG0_LID_MASK GENMASK_ULL(10, 8) #define VTAG0_LID_MASK GENMASK_ULL(10, 8)
#define VTAG0_RELPTR_MASK GENMASK_ULL(7, 0) #define VTAG0_RELPTR_MASK GENMASK_ULL(7, 0)
struct npc_mcam_kex {
/* MKEX Profle Header */
u64 mkex_sign; /* "mcam-kex-profile" (8 bytes/ASCII characters) */
u8 name[MKEX_NAME_LEN]; /* MKEX Profile name */
u64 cpu_model; /* Format as profiled by CPU hardware */
u64 kpu_version; /* KPU firmware/profile version */
u64 reserved; /* Reserved for extension */
/* MKEX Profle Data */
u64 keyx_cfg[NPC_MAX_INTF]; /* NPC_AF_INTF(0..1)_KEX_CFG */
/* NPC_AF_KEX_LDATA(0..1)_FLAGS_CFG */
u64 kex_ld_flags[NPC_MAX_LD];
/* NPC_AF_INTF(0..1)_LID(0..7)_LT(0..15)_LD(0..1)_CFG */
u64 intf_lid_lt_ld[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD];
/* NPC_AF_INTF(0..1)_LDATA(0..1)_FLAGS(0..15)_CFG */
u64 intf_ld_flags[NPC_MAX_INTF][NPC_MAX_LD][NPC_MAX_LFL];
} __packed;
#endif /* NPC_H */ #endif /* NPC_H */
...@@ -52,6 +52,10 @@ MODULE_LICENSE("GPL v2"); ...@@ -52,6 +52,10 @@ MODULE_LICENSE("GPL v2");
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
MODULE_DEVICE_TABLE(pci, rvu_id_table); MODULE_DEVICE_TABLE(pci, rvu_id_table);
static char *mkex_profile; /* MKEX profile name */
module_param(mkex_profile, charp, 0000);
MODULE_PARM_DESC(mkex_profile, "MKEX profile name string");
/* Poll a RVU block's register 'offset', for a 'zero' /* Poll a RVU block's register 'offset', for a 'zero'
* or 'nonzero' at bits specified by 'mask' * or 'nonzero' at bits specified by 'mask'
*/ */
...@@ -2359,6 +2363,14 @@ static void rvu_disable_sriov(struct rvu *rvu) ...@@ -2359,6 +2363,14 @@ static void rvu_disable_sriov(struct rvu *rvu)
pci_disable_sriov(rvu->pdev); pci_disable_sriov(rvu->pdev);
} }
static void rvu_update_module_params(struct rvu *rvu)
{
const char *default_pfl_name = "default";
strscpy(rvu->mkex_pfl_name,
mkex_profile ? mkex_profile : default_pfl_name, MKEX_NAME_LEN);
}
static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -2412,6 +2424,9 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2412,6 +2424,9 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_release_regions; goto err_release_regions;
} }
/* Store module params in rvu structure */
rvu_update_module_params(rvu);
/* Check which blocks the HW supports */ /* Check which blocks the HW supports */
rvu_check_block_implemented(rvu); rvu_check_block_implemented(rvu);
......
...@@ -156,7 +156,17 @@ struct rvu_pfvf { ...@@ -156,7 +156,17 @@ struct rvu_pfvf {
struct nix_txsch { struct nix_txsch {
struct rsrc_bmap schq; struct rsrc_bmap schq;
u8 lvl; u8 lvl;
u16 *pfvf_map; #define NIX_TXSCHQ_TL1_CFG_DONE BIT_ULL(0)
#define TXSCH_MAP_FUNC(__pfvf_map) ((__pfvf_map) & 0xFFFF)
#define TXSCH_MAP_FLAGS(__pfvf_map) ((__pfvf_map) >> 16)
#define TXSCH_MAP(__func, __flags) (((__func) & 0xFFFF) | ((__flags) << 16))
u32 *pfvf_map;
};
struct nix_mark_format {
u8 total;
u8 in_use;
u32 *cfg;
}; };
struct npc_pkind { struct npc_pkind {
...@@ -164,9 +174,23 @@ struct npc_pkind { ...@@ -164,9 +174,23 @@ struct npc_pkind {
u32 *pfchan_map; u32 *pfchan_map;
}; };
struct nix_flowkey {
#define NIX_FLOW_KEY_ALG_MAX 32
u32 flowkey[NIX_FLOW_KEY_ALG_MAX];
int in_use;
};
struct nix_lso {
u8 total;
u8 in_use;
};
struct nix_hw { struct nix_hw {
struct nix_txsch txsch[NIX_TXSCH_LVL_CNT]; /* Tx schedulers */ struct nix_txsch txsch[NIX_TXSCH_LVL_CNT]; /* Tx schedulers */
struct nix_mcast mcast; struct nix_mcast mcast;
struct nix_flowkey flowkey;
struct nix_mark_format mark_format;
struct nix_lso lso;
}; };
struct rvu_hwinfo { struct rvu_hwinfo {
...@@ -237,6 +261,8 @@ struct rvu { ...@@ -237,6 +261,8 @@ struct rvu {
struct workqueue_struct *cgx_evh_wq; struct workqueue_struct *cgx_evh_wq;
spinlock_t cgx_evq_lock; /* cgx event queue lock */ spinlock_t cgx_evq_lock; /* cgx event queue lock */
struct list_head cgx_evq_head; /* cgx event queue head */ struct list_head cgx_evq_head; /* cgx event queue head */
char mkex_pfl_name[MKEX_NAME_LEN]; /* Configured MKEX profile name */
}; };
static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
...@@ -366,6 +392,8 @@ int rvu_mbox_handler_npa_lf_free(struct rvu *rvu, struct msg_req *req, ...@@ -366,6 +392,8 @@ int rvu_mbox_handler_npa_lf_free(struct rvu *rvu, struct msg_req *req,
/* NIX APIs */ /* NIX APIs */
bool is_nixlf_attached(struct rvu *rvu, u16 pcifunc); bool is_nixlf_attached(struct rvu *rvu, u16 pcifunc);
int rvu_nix_init(struct rvu *rvu); int rvu_nix_init(struct rvu *rvu);
int rvu_nix_reserve_mark_format(struct rvu *rvu, struct nix_hw *nix_hw,
int blkaddr, u32 cfg);
void rvu_nix_freemem(struct rvu *rvu); void rvu_nix_freemem(struct rvu *rvu);
int rvu_get_nixlf_count(struct rvu *rvu); int rvu_get_nixlf_count(struct rvu *rvu);
void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int npalf); void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int npalf);
...@@ -398,7 +426,7 @@ int rvu_mbox_handler_nix_rxvlan_alloc(struct rvu *rvu, struct msg_req *req, ...@@ -398,7 +426,7 @@ int rvu_mbox_handler_nix_rxvlan_alloc(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp); struct msg_rsp *rsp);
int rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu *rvu, int rvu_mbox_handler_nix_rss_flowkey_cfg(struct rvu *rvu,
struct nix_rss_flowkey_cfg *req, struct nix_rss_flowkey_cfg *req,
struct msg_rsp *rsp); struct nix_rss_flowkey_cfg_rsp *rsp);
int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu, int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
struct nix_set_mac_addr *req, struct nix_set_mac_addr *req,
struct msg_rsp *rsp); struct msg_rsp *rsp);
...@@ -410,6 +438,14 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req, ...@@ -410,6 +438,14 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp); struct msg_rsp *rsp);
int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req, int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
struct msg_rsp *rsp); struct msg_rsp *rsp);
int rvu_mbox_handler_nix_mark_format_cfg(struct rvu *rvu,
struct nix_mark_format_cfg *req,
struct nix_mark_format_cfg_rsp *rsp);
int rvu_mbox_handler_nix_set_rx_cfg(struct rvu *rvu, struct nix_rx_cfg *req,
struct msg_rsp *rsp);
int rvu_mbox_handler_nix_lso_format_cfg(struct rvu *rvu,
struct nix_lso_format_cfg *req,
struct nix_lso_format_cfg_rsp *rsp);
/* NPC APIs */ /* NPC APIs */
int rvu_npc_init(struct rvu *rvu); int rvu_npc_init(struct rvu *rvu);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "rvu_reg.h" #include "rvu_reg.h"
#include "rvu.h" #include "rvu.h"
#include "npc.h" #include "npc.h"
#include "cgx.h"
#include "npc_profile.h" #include "npc_profile.h"
#define RSVD_MCAM_ENTRIES_PER_PF 2 /* Bcast & Promisc */ #define RSVD_MCAM_ENTRIES_PER_PF 2 /* Bcast & Promisc */
...@@ -368,9 +369,9 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, ...@@ -368,9 +369,9 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
int nixlf, u64 chan, bool allmulti) int nixlf, u64 chan, bool allmulti)
{ {
struct npc_mcam *mcam = &rvu->hw->mcam; struct npc_mcam *mcam = &rvu->hw->mcam;
int blkaddr, ucast_idx, index, kwi;
struct mcam_entry entry = { {0} }; struct mcam_entry entry = { {0} };
struct nix_rx_action action = { }; struct nix_rx_action action = { };
int blkaddr, index, kwi;
/* Only PF or AF VF can add a promiscuous entry */ /* Only PF or AF VF can add a promiscuous entry */
if ((pcifunc & RVU_PFVF_FUNC_MASK) && !is_afvf(pcifunc)) if ((pcifunc & RVU_PFVF_FUNC_MASK) && !is_afvf(pcifunc))
...@@ -392,9 +393,21 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, ...@@ -392,9 +393,21 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
entry.kw_mask[kwi] = BIT_ULL(40); entry.kw_mask[kwi] = BIT_ULL(40);
} }
ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_UCAST_ENTRY);
/* If the corresponding PF's ucast action is RSS,
* use the same action for promisc also
*/
if (is_mcam_entry_enabled(rvu, mcam, blkaddr, ucast_idx))
*(u64 *)&action = npc_get_mcam_action(rvu, mcam,
blkaddr, ucast_idx);
if (action.op != NIX_RX_ACTIONOP_RSS) {
*(u64 *)&action = 0x00; *(u64 *)&action = 0x00;
action.op = NIX_RX_ACTIONOP_UCAST; action.op = NIX_RX_ACTIONOP_UCAST;
action.pf_func = pcifunc; action.pf_func = pcifunc;
}
entry.action = *(u64 *)&action; entry.action = *(u64 *)&action;
npc_config_mcam_entry(rvu, mcam, blkaddr, index, npc_config_mcam_entry(rvu, mcam, blkaddr, index,
...@@ -476,7 +489,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc, ...@@ -476,7 +489,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
* *
*/ */
entry.kw[0] = BIT_ULL(13) | chan; entry.kw[0] = BIT_ULL(13) | chan;
entry.kw_mask[0] = ~entry.kw[0] & (BIT_ULL(13) | 0xFFFULL); entry.kw_mask[0] = BIT_ULL(13) | 0xFFFULL;
*(u64 *)&action = 0x00; *(u64 *)&action = 0x00;
#ifdef MCAST_MCE #ifdef MCAST_MCE
...@@ -539,6 +552,21 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, ...@@ -539,6 +552,21 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
rvu_write64(rvu, blkaddr, rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
index = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_PROMISC_ENTRY);
/* If PF's promiscuous entry is enabled,
* Set RSS action for that entry as well
*/
if (is_mcam_entry_enabled(rvu, mcam, blkaddr, index)) {
bank = npc_get_bank(mcam, index);
index &= (mcam->banksize - 1);
rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index, bank),
*(u64 *)&action);
}
rvu_npc_update_rxvlan(rvu, pcifunc, nixlf); rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
} }
...@@ -704,6 +732,111 @@ static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr) ...@@ -704,6 +732,111 @@ static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr)
SET_KEX_LD(NIX_INTF_RX, NPC_LID_LD, NPC_LT_LD_TCP, 1, cfg); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LD, NPC_LT_LD_TCP, 1, cfg);
} }
static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr,
struct npc_mcam_kex *mkex)
{
int lid, lt, ld, fl;
rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX),
mkex->keyx_cfg[NIX_INTF_RX]);
rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_TX),
mkex->keyx_cfg[NIX_INTF_TX]);
for (ld = 0; ld < NPC_MAX_LD; ld++)
rvu_write64(rvu, blkaddr, NPC_AF_KEX_LDATAX_FLAGS_CFG(ld),
mkex->kex_ld_flags[ld]);
for (lid = 0; lid < NPC_MAX_LID; lid++) {
for (lt = 0; lt < NPC_MAX_LT; lt++) {
for (ld = 0; ld < NPC_MAX_LD; ld++) {
SET_KEX_LD(NIX_INTF_RX, lid, lt, ld,
mkex->intf_lid_lt_ld[NIX_INTF_RX]
[lid][lt][ld]);
SET_KEX_LD(NIX_INTF_TX, lid, lt, ld,
mkex->intf_lid_lt_ld[NIX_INTF_TX]
[lid][lt][ld]);
}
}
}
for (ld = 0; ld < NPC_MAX_LD; ld++) {
for (fl = 0; fl < NPC_MAX_LFL; fl++) {
SET_KEX_LDFLAGS(NIX_INTF_RX, ld, fl,
mkex->intf_ld_flags[NIX_INTF_RX]
[ld][fl]);
SET_KEX_LDFLAGS(NIX_INTF_TX, ld, fl,
mkex->intf_ld_flags[NIX_INTF_TX]
[ld][fl]);
}
}
}
/* strtoull of "mkexprof" with base:36 */
#define MKEX_SIGN 0x19bbfdbd15f
#define MKEX_END_SIGN 0xdeadbeef
static void npc_load_mkex_profile(struct rvu *rvu, int blkaddr)
{
const char *mkex_profile = rvu->mkex_pfl_name;
struct device *dev = &rvu->pdev->dev;
void __iomem *mkex_prfl_addr = NULL;
struct npc_mcam_kex *mcam_kex;
u64 prfl_addr;
u64 prfl_sz;
/* If user not selected mkex profile */
if (!strncmp(mkex_profile, "default", MKEX_NAME_LEN))
goto load_default;
if (cgx_get_mkex_prfl_info(&prfl_addr, &prfl_sz))
goto load_default;
if (!prfl_addr || !prfl_sz)
goto load_default;
mkex_prfl_addr = ioremap_wc(prfl_addr, prfl_sz);
if (!mkex_prfl_addr)
goto load_default;
mcam_kex = (struct npc_mcam_kex *)mkex_prfl_addr;
while (((s64)prfl_sz > 0) && (mcam_kex->mkex_sign != MKEX_END_SIGN)) {
/* Compare with mkex mod_param name string */
if (mcam_kex->mkex_sign == MKEX_SIGN &&
!strncmp(mcam_kex->name, mkex_profile, MKEX_NAME_LEN)) {
/* Due to an errata (35786) in A0 pass silicon,
* parse nibble enable configuration has to be
* identical for both Rx and Tx interfaces.
*/
if (is_rvu_9xxx_A0(rvu) &&
mcam_kex->keyx_cfg[NIX_INTF_RX] !=
mcam_kex->keyx_cfg[NIX_INTF_TX])
goto load_default;
/* Program selected mkex profile */
npc_program_mkex_profile(rvu, blkaddr, mcam_kex);
goto unmap;
}
mcam_kex++;
prfl_sz -= sizeof(struct npc_mcam_kex);
}
dev_warn(dev, "Failed to load requested profile: %s\n",
rvu->mkex_pfl_name);
load_default:
dev_info(rvu->dev, "Using default mkex profile\n");
/* Config packet data and flags extraction into PARSE result */
npc_config_ldata_extract(rvu, blkaddr);
unmap:
if (mkex_prfl_addr)
iounmap(mkex_prfl_addr);
}
static void npc_config_kpuaction(struct rvu *rvu, int blkaddr, static void npc_config_kpuaction(struct rvu *rvu, int blkaddr,
struct npc_kpu_profile_action *kpuaction, struct npc_kpu_profile_action *kpuaction,
int kpu, int entry, bool pkind) int kpu, int entry, bool pkind)
...@@ -1008,13 +1141,20 @@ int rvu_npc_init(struct rvu *rvu) ...@@ -1008,13 +1141,20 @@ int rvu_npc_init(struct rvu *rvu)
rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_OIP4, rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_OIP4,
(NPC_LID_LC << 8) | (NPC_LT_LC_IP << 4) | 0x0F); (NPC_LID_LC << 8) | (NPC_LT_LC_IP << 4) | 0x0F);
/* Config Inner IPV4 NPC layer info */
rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_IIP4,
(NPC_LID_LF << 8) | (NPC_LT_LF_TU_IP << 4) | 0x0F);
/* Enable below for Rx pkts. /* Enable below for Rx pkts.
* - Outer IPv4 header checksum validation. * - Outer IPv4 header checksum validation.
* - Detect outer L2 broadcast address and set NPC_RESULT_S[L2M]. * - Detect outer L2 broadcast address and set NPC_RESULT_S[L2M].
* - Inner IPv4 header checksum validation.
* - Set non zero checksum error code value
*/ */
rvu_write64(rvu, blkaddr, NPC_AF_PCK_CFG, rvu_write64(rvu, blkaddr, NPC_AF_PCK_CFG,
rvu_read64(rvu, blkaddr, NPC_AF_PCK_CFG) | rvu_read64(rvu, blkaddr, NPC_AF_PCK_CFG) |
BIT_ULL(6) | BIT_ULL(2)); BIT_ULL(32) | BIT_ULL(24) | BIT_ULL(6) |
BIT_ULL(2) | BIT_ULL(1));
/* Set RX and TX side MCAM search key size. /* Set RX and TX side MCAM search key size.
* LA..LD (ltype only) + Channel * LA..LD (ltype only) + Channel
...@@ -1034,8 +1174,8 @@ int rvu_npc_init(struct rvu *rvu) ...@@ -1034,8 +1174,8 @@ int rvu_npc_init(struct rvu *rvu)
if (err) if (err)
return err; return err;
/* Config packet data and flags extraction into PARSE result */ /* Configure MKEX profile */
npc_config_ldata_extract(rvu, blkaddr); npc_load_mkex_profile(rvu, blkaddr);
/* Set TX miss action to UCAST_DEFAULT i.e /* Set TX miss action to UCAST_DEFAULT i.e
* transmit the packet on NIX LF SQ's default channel. * transmit the packet on NIX LF SQ's default channel.
...@@ -2043,6 +2183,7 @@ int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req, ...@@ -2043,6 +2183,7 @@ int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req,
GET_KEX_LDFLAGS(NIX_INTF_TX, ld, fl); GET_KEX_LDFLAGS(NIX_INTF_TX, ld, fl);
} }
} }
memcpy(rsp->mkex_pfl_name, rvu->mkex_pfl_name, MKEX_NAME_LEN);
return 0; return 0;
} }
......
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