diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-26 22:07:35 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-26 22:07:35 +0100 |
| commit | b4669b7a027d6cb271dc4ebf44b7f7a7186119ad (patch) | |
| tree | fd55b5345d39c35c5676a2e67edd3e486dab2147 /drivers/net/ethernet/pensando/ionic | |
| parent | 531c5716ada91d2f852ac1b9447cb29095a0003b (diff) | |
| parent | 9b66c9af7172ffcf727214fa0ebe9a5e1ed6eb16 (diff) | |
| download | linux-next-b4669b7a027d6cb271dc4ebf44b7f7a7186119ad.tar.gz linux-next-b4669b7a027d6cb271dc4ebf44b7f7a7186119ad.zip | |
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git
# Conflicts:
# drivers/infiniband/hw/irdma/verbs.c
Diffstat (limited to 'drivers/net/ethernet/pensando/ionic')
| -rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_if.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_lif.c | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_lif.h | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_phc.c | 63 |
5 files changed, 71 insertions, 13 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c index c4ab4b5caa0a..fc8c50e8f365 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c @@ -1041,10 +1041,14 @@ static int ionic_get_ts_info(struct net_device *netdev, info->phc_index = ptp_clock_index(lif->phc->ptp); - info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_TX_HARDWARE | - SOF_TIMESTAMPING_RX_HARDWARE | - SOF_TIMESTAMPING_RAW_HARDWARE; + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE; + + if (!(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) + return 0; + + info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; /* tx modes */ diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h index 0a201422d0c5..6afc1fc3c7ed 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_if.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h @@ -1181,6 +1181,7 @@ enum ionic_eth_hw_features { IONIC_ETH_HW_TX_CSUM_GENEVE = BIT(18), IONIC_ETH_HW_TSO_GENEVE = BIT(19), IONIC_ETH_HW_TIMESTAMP = BIT(20), + IONIC_ETH_HW_RDMA_TIMESTAMP = BIT(21), }; /** diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index fd3ee9820531..af4aadd96cb9 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -1500,7 +1500,8 @@ static int ionic_set_nic_features(struct ionic_lif *lif, ctx.cmd.lif_setattr.features = ionic_netdev_features_to_nic(features); if (lif->phc) - ctx.cmd.lif_setattr.features |= cpu_to_le64(IONIC_ETH_HW_TIMESTAMP); + ctx.cmd.lif_setattr.features |= lif->ionic->ident.lif.eth.config.features & + cpu_to_le64(IONIC_ETH_HW_TIMESTAMP | IONIC_ETH_HW_RDMA_TIMESTAMP); err = ionic_adminq_post_wait(lif, &ctx); if (err) @@ -1551,6 +1552,8 @@ static int ionic_set_nic_features(struct ionic_lif *lif, dev_dbg(dev, "feature ETH_HW_TSO_UDP_CSUM\n"); if (lif->hw_features & IONIC_ETH_HW_TIMESTAMP) dev_dbg(dev, "feature ETH_HW_TIMESTAMP\n"); + if (lif->hw_features & IONIC_ETH_HW_RDMA_TIMESTAMP) + dev_dbg(dev, "feature ETH_HW_RDMA_TIMESTAMP\n"); return 0; } diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h index d34692462036..e790f6b9441e 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h @@ -248,7 +248,7 @@ struct ionic_lif { }; struct ionic_phc { - spinlock_t lock; /* lock for cc and tc */ + spinlock_t lock; /* lock for state_page, cc and tc */ struct cyclecounter cc; struct timecounter tc; @@ -261,6 +261,7 @@ struct ionic_phc { long aux_work_delay; struct ptp_clock_info ptp_info; + struct ib_uverbs_clock_info *state_page; struct ptp_clock *ptp; struct ionic_lif *lif; }; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c b/drivers/net/ethernet/pensando/ionic/ionic_phc.c index 05b44fc482f8..4b8d80a55b72 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_phc.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c @@ -3,6 +3,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> +#include <uapi/rdma/ib_user_verbs.h> #include "ionic.h" #include "ionic_bus.h" @@ -77,7 +78,8 @@ static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif, bool rx_all; __le64 mask; - if (!lif->phc || !lif->phc->ptp) + if (!lif->phc || !lif->phc->ptp || + !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) return -EOPNOTSUPP; mutex_lock(&lif->phc->config_lock); @@ -210,7 +212,8 @@ int ionic_hwstamp_set(struct net_device *netdev, struct ionic_lif *lif = netdev_priv(netdev); int err; - if (!lif->phc || !lif->phc->ptp) + if (!lif->phc || !lif->phc->ptp || + !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) return -EOPNOTSUPP; mutex_lock(&lif->queue_lock); @@ -228,7 +231,8 @@ void ionic_lif_hwstamp_replay(struct ionic_lif *lif) { int err; - if (!lif->phc || !lif->phc->ptp) + if (!lif->phc || !lif->phc->ptp || + !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) return; mutex_lock(&lif->queue_lock); @@ -242,7 +246,8 @@ void ionic_lif_hwstamp_recreate_queues(struct ionic_lif *lif) { int err; - if (!lif->phc || !lif->phc->ptp) + if (!lif->phc || !lif->phc->ptp || + !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) return; mutex_lock(&lif->phc->config_lock); @@ -267,7 +272,8 @@ int ionic_hwstamp_get(struct net_device *netdev, { struct ionic_lif *lif = netdev_priv(netdev); - if (!lif->phc || !lif->phc->ptp) + if (!lif->phc || !lif->phc->ptp || + !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) return -EOPNOTSUPP; mutex_lock(&lif->phc->config_lock); @@ -329,6 +335,26 @@ static int ionic_setphc_cmd(struct ionic_phc *phc, struct ionic_admin_ctx *ctx) return ionic_adminq_post(phc->lif, ctx); } +static void ionic_phc_state_page_update(struct ionic_phc *phc) +{ + struct ib_uverbs_clock_info *state = phc->state_page; + u32 sign; + + /* read current sign */ + sign = smp_load_acquire(&state->sign) & ~1; + + /* make sign odd for updating */ + smp_store_mb(state->sign, sign | 1); + + state->cycles = phc->tc.cycle_last; + state->nsec = phc->tc.nsec; + state->frac = phc->tc.frac; + state->mult = phc->cc.mult; + + /* make sign the next even number for update completed */ + smp_store_release(&state->sign, sign + 2); +} + static int ionic_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm) { struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info); @@ -356,6 +382,8 @@ static int ionic_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm) timecounter_read(&phc->tc); phc->cc.mult = adj; + ionic_phc_state_page_update(phc); + /* Setphc commands are posted in-order, sequenced by phc->lock. We * need to drop the lock before waiting for the command to complete. */ @@ -381,6 +409,8 @@ static int ionic_phc_adjtime(struct ptp_clock_info *info, s64 delta) timecounter_adjtime(&phc->tc, delta); + ionic_phc_state_page_update(phc); + /* Setphc commands are posted in-order, sequenced by phc->lock. We * need to drop the lock before waiting for the command to complete. */ @@ -410,6 +440,8 @@ static int ionic_phc_settime64(struct ptp_clock_info *info, timecounter_init(&phc->tc, &phc->cc, ns); + ionic_phc_state_page_update(phc); + /* Setphc commands are posted in-order, sequenced by phc->lock. We * need to drop the lock before waiting for the command to complete. */ @@ -467,6 +499,8 @@ static long ionic_phc_aux_work(struct ptp_clock_info *info) /* update point-in-time basis to now */ timecounter_read(&phc->tc); + ionic_phc_state_page_update(phc); + /* Setphc commands are posted in-order, sequenced by phc->lock. We * need to drop the lock before waiting for the command to complete. */ @@ -506,7 +540,8 @@ static const struct ptp_clock_info ionic_ptp_info = { void ionic_lif_register_phc(struct ionic_lif *lif) { - if (!lif->phc || !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) + if (!lif->phc || + !(lif->hw_features & (IONIC_ETH_HW_TIMESTAMP | IONIC_ETH_HW_RDMA_TIMESTAMP))) return; lif->phc->ptp = ptp_clock_register(&lif->phc->ptp_info, lif->ionic->dev); @@ -545,13 +580,19 @@ void ionic_lif_alloc_phc(struct ionic_lif *lif) return; features = le64_to_cpu(ionic->ident.lif.eth.config.features); - if (!(features & IONIC_ETH_HW_TIMESTAMP)) + if (!(features & (IONIC_ETH_HW_TIMESTAMP | IONIC_ETH_HW_RDMA_TIMESTAMP))) return; phc = devm_kzalloc(ionic->dev, sizeof(*phc), GFP_KERNEL); if (!phc) return; + phc->state_page = (void *)get_zeroed_page(GFP_KERNEL); + if (!phc->state_page) { + devm_kfree(ionic->dev, phc); + return; + } + phc->lif = lif; phc->cc.read = ionic_cc_read; @@ -563,6 +604,7 @@ void ionic_lif_alloc_phc(struct ionic_lif *lif) dev_err(lif->ionic->dev, "Invalid device PHC mask multiplier %u, disabling HW timestamp support\n", phc->cc.mult); + free_page((unsigned long)phc->state_page); devm_kfree(lif->ionic->dev, phc); lif->phc = NULL; return; @@ -646,6 +688,12 @@ void ionic_lif_alloc_phc(struct ionic_lif *lif) */ phc->ptp_info.max_adj = NORMAL_PPB; + phc->state_page->mask = phc->cc.mask; + phc->state_page->shift = phc->cc.shift; + phc->state_page->overflow_period = delay; + + ionic_phc_state_page_update(phc); + lif->phc = phc; } @@ -656,6 +704,7 @@ void ionic_lif_free_phc(struct ionic_lif *lif) mutex_destroy(&lif->phc->config_lock); + free_page((unsigned long)lif->phc->state_page); devm_kfree(lif->ionic->dev, lif->phc); lif->phc = NULL; } |
