[PATCH net] octeontx2: fix PTP RX enable mbox failure on VF
From: Ratheesh Kannoth <rkannoth@marvell.com>
Date: 2026-08-18 03:47:43
Also in:
lkml
Subsystem:
marvell octeontx2 physical function driver, marvell octeontx2 rvu admin function driver, networking drivers, the rest · Maintainers:
Sunil Goutham, Geetha sowjanya, Ratheesh Kannoth, Subbaraya Sundeep, Bharat Bhushan, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
From: Sai Krishna <redacted>
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 <redacted>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../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