[PATCH net] octeontx2: fix PTP RX enable mbox failure on VF
Ratheesh Kannoth <[email protected]>
| Newsgroups | gmane.linux.network,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Sai Krishna <[email protected]> When a VF enables PTP RX timestamping, the AF must notify the parent PF so it can adjust its RX data offset before CGX prepends the 8-byte timestamp header. Use the correct upcall mailbox pattern (wait for zero, then msg_send_up) instead of msg_send/wait_for_rsp, which causes the mbox to fail on VF. Add the CGX_PTP_RX_INFO upcall message and PF/VF handlers to propagate the PTP enable state to VFs. Fixes: 30e7ecb6441d ("octeontx2-af: Support for PTP notification to PF") Signed-off-by: Sai Krishna <[email protected]> Signed-off-by: Ratheesh Kannoth <[email protected]> --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 8 ++- .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 20 +++++++ .../marvell/octeontx2/nic/otx2_common.h | 2 + .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 59 +++++++++++++++++++ .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 14 +++++ 5 files changed, 102 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index 714e47f68d93..96e1b93f8122 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -427,7 +427,8 @@ M(MCS_CUSTOM_TAG_CFG_GET, 0xa021, mcs_custom_tag_cfg_get, \ /* Messages initiated by AF (range 0xC00 - 0xEFF) */ #define MBOX_UP_CGX_MESSAGES \ -M(CGX_LINK_EVENT, 0xC00, cgx_link_event, cgx_link_info_msg, msg_rsp) +M(CGX_LINK_EVENT, 0xC00, cgx_link_event, cgx_link_info_msg, msg_rsp) \ +M(CGX_PTP_RX_INFO, 0xC01, cgx_ptp_rx_info, cgx_ptp_rx_info_msg, msg_rsp) #define MBOX_UP_CPT_MESSAGES \ M(CPT_INST_LMTST, 0xD00, cpt_inst_lmtst, cpt_inst_lmtst_req, msg_rsp) @@ -647,6 +648,11 @@ struct cgx_link_info_msg { struct cgx_link_user_info link_info; }; +struct cgx_ptp_rx_info_msg { + struct mbox_msghdr hdr; + u8 ptp_en; +}; + struct cgx_pause_frm_cfg { struct mbox_msghdr hdr; u8 set; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c index 87d21889dc49..cb95f3fb60ae 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c @@ -820,6 +820,24 @@ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req, return 0; } +static void cgx_notify_up_ptp_info(struct rvu *rvu, int pf, bool enable) +{ + struct cgx_ptp_rx_info_msg *msg; + + /* Send mbox message to PF */ + msg = otx2_mbox_alloc_msg_cgx_ptp_rx_info(rvu, pf); + if (!msg) { + dev_err(rvu->dev, "failed to alloc message\n"); + return; + } + + msg->ptp_en = enable; + + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf); + + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf); +} + static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable) { struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); @@ -837,6 +855,8 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable) if (!is_pf_cgxmapped(rvu, pf)) return -EPERM; + cgx_notify_up_ptp_info(rvu, pf, enable); + rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); cgxd = rvu_cgx_pdata(cgx_id, rvu); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index eecee612b7b2..13b54287facf 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -286,6 +286,7 @@ enum vfperm { struct otx2_vf_config { struct otx2_nic *pf; struct delayed_work link_event_work; + struct delayed_work ptp_info_work; bool intf_down; /* interface was either configured or not */ u8 mac[ETH_ALEN]; u16 vlan; @@ -324,6 +325,7 @@ struct otx2_ptp { u64 thresh; struct ptp_pin_desc extts_config; + bool ptp_en; u64 (*convert_rx_ptp_tstmp)(u64 timestamp); u64 (*convert_tx_ptp_tstmp)(u64 timestamp); u64 (*ptp_tstamp2nsec)(const struct timecounter *time_counter, u64 timestamp); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index c995f2900859..8e2443041ee8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -44,6 +44,7 @@ MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(pci, otx2_pf_id_table); static void otx2_vf_link_event_task(struct work_struct *work); +static void otx2_vf_ptp_info_task(struct work_struct *work); enum { TYPE_PFAF, @@ -960,6 +961,30 @@ int otx2_mbox_up_handler_cgx_link_event(struct otx2_nic *pf, return 0; } +int otx2_mbox_up_handler_cgx_ptp_rx_info(struct otx2_nic *pf, + struct cgx_ptp_rx_info_msg *msg, + struct msg_rsp *rsp) +{ + int i; + + if (!pf->ptp) + return 0; + + pf->ptp->ptp_en = msg->ptp_en; + + /* notify VFs about ptp event */ + for (i = 0; i < pci_num_vf(pf->pdev); i++) { + struct otx2_vf_config *config = &pf->vf_configs[i]; + struct delayed_work *dwork = &config->ptp_info_work; + + if (config->intf_down) + continue; + + schedule_delayed_work(dwork, msecs_to_jiffies(100)); + } + return 0; +} + static int otx2_process_mbox_msg_up(struct otx2_nic *pf, struct mbox_msghdr *req) { @@ -3041,6 +3066,8 @@ static int otx2_sriov_vfcfg_init(struct otx2_nic *pf) pf->vf_configs[i].trusted = false; INIT_DELAYED_WORK(&pf->vf_configs[i].link_event_work, otx2_vf_link_event_task); + INIT_DELAYED_WORK(&pf->vf_configs[i].ptp_info_work, + otx2_vf_ptp_info_task); } return 0; @@ -3055,6 +3082,7 @@ static void otx2_sriov_vfcfg_cleanup(struct otx2_nic *pf) for (i = 0; i < pf->total_vfs; i++) { cancel_delayed_work_sync(&pf->vf_configs[i].link_event_work); + cancel_delayed_work_sync(&pf->vf_configs[i].ptp_info_work); otx2_set_vf_permissions(pf, i, OTX2_RESET_VF_PERM); } } @@ -3417,6 +3445,37 @@ static void otx2_vf_link_event_task(struct work_struct *work) mutex_unlock(&pf->mbox.lock); } +static void otx2_vf_ptp_info_task(struct work_struct *work) +{ + struct cgx_ptp_rx_info_msg *req; + struct otx2_vf_config *config; + struct mbox_msghdr *msghdr; + struct otx2_nic *pf; + int vf_idx; + + config = container_of(work, struct otx2_vf_config, + ptp_info_work.work); + vf_idx = config - config->pf->vf_configs; + pf = config->pf; + + if (config->intf_down || !pf->ptp) + return; + + msghdr = otx2_mbox_alloc_msg_rsp(&pf->mbox_pfvf[0].mbox_up, vf_idx, + sizeof(*req), sizeof(struct msg_rsp)); + if (!msghdr) { + dev_err(pf->dev, "Failed to create VF%d ptp info event\n", vf_idx); + return; + } + + req = (struct cgx_ptp_rx_info_msg *)msghdr; + req->hdr.id = MBOX_MSG_CGX_PTP_RX_INFO; + req->hdr.sig = OTX2_MBOX_REQ_SIG; + req->ptp_en = pf->ptp->ptp_en; + + otx2_sync_mbox_up_msg(&pf->mbox_pfvf[0], vf_idx); +} + static int otx2_sriov_enable(struct pci_dev *pdev, int numvfs) { struct net_device *netdev = pci_get_drvdata(pdev); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index b022f52c6845..60f81062007b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -141,6 +141,20 @@ static int otx2vf_process_mbox_msg_up(struct otx2_nic *vf, err = otx2_mbox_up_handler_cgx_link_event( vf, (struct cgx_link_info_msg *)req, rsp); return err; + case MBOX_MSG_CGX_PTP_RX_INFO: + rsp = (struct msg_rsp *)otx2_mbox_alloc_msg(&vf->mbox.mbox_up, + 0, sizeof(struct msg_rsp)); + if (!rsp) + return -ENOMEM; + + rsp->hdr.id = MBOX_MSG_CGX_PTP_RX_INFO; + rsp->hdr.sig = OTX2_MBOX_RSP_SIG; + rsp->hdr.pcifunc = req->pcifunc; + rsp->hdr.rc = 0; + err = otx2_mbox_up_handler_cgx_ptp_rx_info(vf, + (struct cgx_ptp_rx_info_msg *)req, + rsp); + return err; default: otx2_reply_invalid_msg(&vf->mbox.mbox_up, 0, 0, req->id); return -ENODEV; -- 2.43.0