Maintaining the state of representor which describes whether it has an active VF and what is the func id of the representee.
Implement a mbox between VF and PF for the VF to know if representors are available. Signed-off-by: Harman Kalra <hka...@marvell.com> --- drivers/common/cnxk/roc_dev.c | 167 +++++++++++++++++++++++------ drivers/common/cnxk/roc_dev_priv.h | 7 +- drivers/common/cnxk/roc_nix.c | 23 ++++ drivers/common/cnxk/roc_nix.h | 22 ++-- drivers/common/cnxk/version.map | 3 + 5 files changed, 182 insertions(+), 40 deletions(-) diff --git a/drivers/common/cnxk/roc_dev.c b/drivers/common/cnxk/roc_dev.c index 4b0ba218ed..4057380eb7 100644 --- a/drivers/common/cnxk/roc_dev.c +++ b/drivers/common/cnxk/roc_dev.c @@ -216,15 +216,120 @@ af_pf_wait_msg(struct dev *dev, uint16_t vf, int num_msg) return req_hdr->num_msgs; } +static int +foward_msg_to_af(struct dev *dev, struct mbox_msghdr *msg, size_t size) +{ + struct mbox_msghdr *af_req; + + /* Reserve AF/PF mbox message */ + size = PLT_ALIGN(size, MBOX_MSG_ALIGN); + af_req = mbox_alloc_msg(dev->mbox, 0, size); + if (af_req == NULL) + return -ENOSPC; + mbox_req_init(msg->id, af_req); + + /* Copy message from VF<->PF mbox to PF<->AF mbox */ + mbox_memcpy((uint8_t *)af_req + sizeof(struct mbox_msghdr), + (uint8_t *)msg + sizeof(struct mbox_msghdr), + size - sizeof(struct mbox_msghdr)); + af_req->pcifunc = msg->pcifunc; + + return 0; +} + +static int +process_vf_ready_msg(struct dev *dev, struct mbox *mbox, struct mbox_msghdr *msg, + uint16_t vf) +{ + uint16_t max_bits = sizeof(dev->active_vfs[0]) * 8; + struct ready_msg_rsp *rsp; + int rc; + + /* Handle READY message in PF */ + dev->active_vfs[vf / max_bits] |= BIT_ULL(vf % max_bits); + rsp = (struct ready_msg_rsp *)mbox_alloc_msg(mbox, vf, sizeof(*rsp)); + if (!rsp) { + plt_err("Failed to alloc VF%d READY message", vf); + return -1; + } + + mbox_rsp_init(msg->id, rsp); + + /* PF/VF function ID */ + rsp->hdr.pcifunc = msg->pcifunc; + rsp->hdr.rc = 0; + + /* Set pffunc value to its representor, op = 0 */ + if (dev->ops && dev->ops->rep_state) { + rc = dev->ops->rep_state(dev->roc_nix, msg->pcifunc, 0); + if (rc < 0) + plt_err("Failed to set repr status, pcifunc 0x%x", + msg->pcifunc); + } + + return 0; +} + +static int +process_vf_read_base_rule_msg(struct dev *dev, struct mbox *mbox, struct mbox_msghdr *msg, + uint16_t vf, size_t size, int *routed) +{ + struct npc_mcam_read_base_rule_rsp *rsp; + int route = *routed; + int rc = 0; + + /* Check if pcifunc has representor, op = 1 */ + if (dev->ops && dev->ops->rep_state) { + rc = dev->ops->rep_state(dev->roc_nix, msg->pcifunc, 1); + if (rc < 0) { + plt_err("Failed to get repr status, pcifunc 0x%x", + msg->pcifunc); + return rc; + } + } + + /* If ret is 1 meaning pci func has a representor, + * return without forwarding base rule mbox + */ + if (rc == 1) { + rsp = (struct npc_mcam_read_base_rule_rsp *)mbox_alloc_msg( + mbox, vf, sizeof(*rsp)); + if (!rsp) { + plt_err("Failed to alloc VF%d rep status message", vf); + return -1; + } + + mbox_rsp_init(msg->id, rsp); + + /* PF/VF function ID */ + rsp->hdr.pcifunc = msg->pcifunc; + rsp->hdr.rc = 0; + } else { + /* If ret is 0, default case i.e. forwarding to AF + * should happen. + */ + rc = foward_msg_to_af(dev, msg, size); + if (rc) { + plt_err("Failed to forward msg ID %d to af, err %d", + msg->id, rc); + return rc; + } + route++; + } + *routed = route; + + return 0; +} + /* PF receives mbox DOWN messages from VF and forwards to AF */ static int vf_pf_process_msgs(struct dev *dev, uint16_t vf) { struct mbox *mbox = &dev->mbox_vfpf; struct mbox_dev *mdev = &mbox->dev[vf]; + int offset, routed = 0, ret = 0; struct mbox_hdr *req_hdr; struct mbox_msghdr *msg; - int offset, routed = 0; size_t size; uint16_t i; @@ -242,42 +347,31 @@ vf_pf_process_msgs(struct dev *dev, uint16_t vf) /* RVU_PF_FUNC_S */ msg->pcifunc = dev_pf_func(dev->pf, vf); - if (msg->id == MBOX_MSG_READY) { - struct ready_msg_rsp *rsp; - uint16_t max_bits = sizeof(dev->active_vfs[0]) * 8; - - /* Handle READY message in PF */ - dev->active_vfs[vf / max_bits] |= - BIT_ULL(vf % max_bits); - rsp = (struct ready_msg_rsp *)mbox_alloc_msg( - mbox, vf, sizeof(*rsp)); - if (!rsp) { - plt_err("Failed to alloc VF%d READY message", - vf); + switch (msg->id) { + case MBOX_MSG_READY: + ret = process_vf_ready_msg(dev, mbox, msg, vf); + if (ret) { + plt_err("Failed to process ready msg for vf %d", vf); continue; } - mbox_rsp_init(msg->id, rsp); + break; + case MBOX_MSG_NPC_MCAM_READ_BASE_RULE: + ret = process_vf_read_base_rule_msg(dev, mbox, msg, vf, size, &routed); + if (ret) { + plt_err("Failed to process base rule for vf %d, err %d", vf, ret); + continue; + } - /* PF/VF function ID */ - rsp->hdr.pcifunc = msg->pcifunc; - rsp->hdr.rc = 0; - } else { - struct mbox_msghdr *af_req; - /* Reserve AF/PF mbox message */ - size = PLT_ALIGN(size, MBOX_MSG_ALIGN); - af_req = mbox_alloc_msg(dev->mbox, 0, size); - if (af_req == NULL) - return -ENOSPC; - mbox_req_init(msg->id, af_req); - - /* Copy message from VF<->PF mbox to PF<->AF mbox */ - mbox_memcpy((uint8_t *)af_req + - sizeof(struct mbox_msghdr), - (uint8_t *)msg + sizeof(struct mbox_msghdr), - size - sizeof(struct mbox_msghdr)); - af_req->pcifunc = msg->pcifunc; + break; + default: { + ret = foward_msg_to_af(dev, msg, size); + if (ret) { + plt_err("Failed to forward msg ID %d to af, err %d", msg->id, ret); + return ret; + } routed++; + } break; } offset = mbox->rx_start + msg->next_msgoff; } @@ -1051,6 +1145,7 @@ vf_flr_handle_msg(void *param, dev_intr_t *flr) { uint16_t vf, max_vf, max_bits; struct dev *dev = param; + int ret; max_bits = sizeof(flr->bits[0]) * sizeof(uint64_t); max_vf = max_bits * MAX_VFPF_DWORD_BITS; @@ -1063,6 +1158,14 @@ vf_flr_handle_msg(void *param, dev_intr_t *flr) vf_flr_send_msg(dev, vf); flr->bits[vf / max_bits] &= ~(BIT_ULL(vf % max_bits)); + /* Reset VF representors state, op = 2 */ + if (dev->ops && dev->ops->rep_state) { + ret = dev->ops->rep_state(dev->roc_nix, dev_pf_func(dev->pf, vf), + 2); + if (ret < 0) + plt_err("Failed to set repr status, for vf %x", vf); + } + /* Signal FLR finish */ plt_write64(BIT_ULL(vf % max_bits), dev->bar2 + RVU_PF_VFTRPENDX(vf / max_bits)); diff --git a/drivers/common/cnxk/roc_dev_priv.h b/drivers/common/cnxk/roc_dev_priv.h index 1f84f74ff3..50a7a67d42 100644 --- a/drivers/common/cnxk/roc_dev_priv.h +++ b/drivers/common/cnxk/roc_dev_priv.h @@ -34,14 +34,17 @@ typedef int (*ptp_info_t)(void *roc_nix, bool enable); typedef void (*q_err_cb_t)(void *roc_nix, void *data); /* Link status get callback */ -typedef void (*link_status_get_t)(void *roc_nix, - struct cgx_link_user_info *link); +typedef void (*link_status_get_t)(void *roc_nix, struct cgx_link_user_info *link); + +/* Process representor status callback */ +typedef int (*rep_state_t)(void *roc_nix, uint16_t pf_func, uint8_t op); struct dev_ops { link_info_t link_status_update; ptp_info_t ptp_info_update; link_status_get_t link_status_get; q_err_cb_t q_err_cb; + rep_state_t rep_state; }; #define dev_is_vf(dev) ((dev)->hwcap & DEV_HWCAP_F_VF) diff --git a/drivers/common/cnxk/roc_nix.c b/drivers/common/cnxk/roc_nix.c index 152ef7269e..0ee534f188 100644 --- a/drivers/common/cnxk/roc_nix.c +++ b/drivers/common/cnxk/roc_nix.c @@ -522,3 +522,26 @@ roc_nix_dev_fini(struct roc_nix *roc_nix) rc |= dev_fini(&nix->dev, nix->pci_dev); return rc; } + +int +roc_nix_process_rep_state_cb_register(struct roc_nix *roc_nix, + process_rep_state_t proc_rep_st) +{ + struct nix *nix = roc_nix_to_nix_priv(roc_nix); + struct dev *dev = &nix->dev; + + if (proc_rep_st == NULL) + return NIX_ERR_PARAM; + + dev->ops->rep_state = (rep_state_t)proc_rep_st; + return 0; +} + +void +roc_nix_process_rep_state_cb_unregister(struct roc_nix *roc_nix) +{ + struct nix *nix = roc_nix_to_nix_priv(roc_nix); + struct dev *dev = &nix->dev; + + dev->ops->rep_state = NULL; +} diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index 9c2ba9a685..47ab3560ea 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -443,8 +443,14 @@ typedef int (*ptp_info_update_t)(struct roc_nix *roc_nix, bool enable); typedef void (*q_err_get_t)(struct roc_nix *roc_nix, void *data); /* Link status get callback */ -typedef void (*link_info_get_t)(struct roc_nix *roc_nix, - struct roc_nix_link_info *link); +typedef void (*link_info_get_t)(struct roc_nix *roc_nix, struct roc_nix_link_info *link); + +/* Process representor status callback: + * op = 0 update pffunc of vf being represented + * op = 1 check if any representor is representing pffunc + * op = 2 vf is going down, reset rep state + */ +typedef int (*process_rep_state_t)(void *roc_nix, uint16_t pf_func, uint8_t op); TAILQ_HEAD(roc_nix_list, roc_nix); @@ -520,6 +526,9 @@ roc_nix_tm_max_shaper_burst_get(void) /* Dev */ int __roc_api roc_nix_dev_init(struct roc_nix *roc_nix); int __roc_api roc_nix_dev_fini(struct roc_nix *roc_nix); +int __roc_api roc_nix_process_rep_state_cb_register(struct roc_nix *roc_nix, + process_rep_state_t proc_rep_st); +void __roc_api roc_nix_process_rep_state_cb_unregister(struct roc_nix *roc_nix); /* Type */ bool __roc_api roc_nix_is_lbk(struct roc_nix *roc_nix); @@ -532,13 +541,14 @@ int __roc_api roc_nix_get_vf(struct roc_nix *roc_nix); uint16_t __roc_api roc_nix_get_pf_func(struct roc_nix *roc_nix); uint16_t __roc_api roc_nix_get_vwqe_interval(struct roc_nix *roc_nix); int __roc_api roc_nix_max_pkt_len(struct roc_nix *roc_nix); +bool __roc_api roc_nix_has_rep(struct roc_nix *roc_nix); /* LF ops */ -int __roc_api roc_nix_lf_alloc(struct roc_nix *roc_nix, uint32_t nb_rxq, - uint32_t nb_txq, uint64_t rx_cfg); +int __roc_api roc_nix_lf_alloc(struct roc_nix *roc_nix, uint32_t nb_rxq, uint32_t nb_txq, + uint64_t rx_cfg); int __roc_api roc_nix_lf_free(struct roc_nix *roc_nix); -int __roc_api roc_nix_lf_inl_ipsec_cfg(struct roc_nix *roc_nix, - struct roc_nix_ipsec_cfg *cfg, bool enb); +int __roc_api roc_nix_lf_inl_ipsec_cfg(struct roc_nix *roc_nix, struct roc_nix_ipsec_cfg *cfg, + bool enb); int __roc_api roc_nix_cpt_ctx_cache_sync(struct roc_nix *roc_nix); int __roc_api roc_nix_rx_drop_re_set(struct roc_nix *roc_nix, bool ena); diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index 1d6e306848..327840429f 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -205,6 +205,8 @@ INTERNAL { roc_nix_cqe_dump; roc_nix_dev_fini; roc_nix_dev_init; + roc_nix_process_rep_state_cb_register; + roc_nix_process_rep_state_cb_unregister; roc_nix_dump; roc_nix_err_intr_ena_dis; roc_nix_fc_config_get; @@ -217,6 +219,7 @@ INTERNAL { roc_nix_get_pf_func; roc_nix_get_vf; roc_nix_get_vwqe_interval; + roc_nix_has_rep; roc_nix_inl_cb_register; roc_nix_inl_cb_unregister; roc_nix_inl_ctx_write; -- 2.18.0