git: ea44c37d0bd1 - main - OFED: Add generic function to extract IB speed from netdev
Date: Wed, 29 Jul 2026 18:44:55 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=ea44c37d0bd15e796c85f84b57c211ac220c550c
commit ea44c37d0bd15e796c85f84b57c211ac220c550c
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-07-29 18:42:19 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-07-29 18:42:19 +0000
OFED: Add generic function to extract IB speed from netdev
Reviewed by: kib
Obtained from: Linux commit d41861942fc55c14b6280d9568a0d0112037f065
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D57952
---
sys/dev/irdma/fbsd_kcompat.h | 1 -
sys/dev/irdma/irdma_kcompat.c | 102 ----------------------------
sys/ofed/drivers/infiniband/core/ib_verbs.c | 48 +++++++++++++
sys/ofed/include/rdma/ib_verbs.h | 2 +
4 files changed, 50 insertions(+), 103 deletions(-)
diff --git a/sys/dev/irdma/fbsd_kcompat.h b/sys/dev/irdma/fbsd_kcompat.h
index 8050d528a9c0..c5ca18204d49 100644
--- a/sys/dev/irdma/fbsd_kcompat.h
+++ b/sys/dev/irdma/fbsd_kcompat.h
@@ -147,7 +147,6 @@ void irdma_destroy_ah(struct ib_ah *ibah, u32 flags);
void irdma_destroy_ah_stub(struct ib_ah *ibah, u32 flags);
int irdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
-int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width);
enum rdma_link_layer irdma_get_link_layer(struct ib_device *ibdev,
u8 port_num);
int irdma_roce_port_immutable(struct ib_device *ibdev, u8 port_num,
diff --git a/sys/dev/irdma/irdma_kcompat.c b/sys/dev/irdma/irdma_kcompat.c
index 03ddae317d58..7ee81ab5add6 100644
--- a/sys/dev/irdma/irdma_kcompat.c
+++ b/sys/dev/irdma/irdma_kcompat.c
@@ -1768,108 +1768,6 @@ kc_set_rdma_uverbs_cmd_mask(struct irdma_device *iwdev)
iwdev->ibdev.uverbs_ex_cmd_mask |= BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_CQ);
}
-static void
-ib_get_width_and_speed(u32 netdev_speed, u32 lanes,
- u16 *speed, u8 *width)
-{
- if (!lanes) {
- if (netdev_speed <= SPEED_1000) {
- *width = IB_WIDTH_1X;
- *speed = IB_SPEED_SDR;
- } else if (netdev_speed <= SPEED_10000) {
- *width = IB_WIDTH_1X;
- *speed = IB_SPEED_FDR10;
- } else if (netdev_speed <= SPEED_20000) {
- *width = IB_WIDTH_4X;
- *speed = IB_SPEED_DDR;
- } else if (netdev_speed <= SPEED_25000) {
- *width = IB_WIDTH_1X;
- *speed = IB_SPEED_EDR;
- } else if (netdev_speed <= SPEED_40000) {
- *width = IB_WIDTH_4X;
- *speed = IB_SPEED_FDR10;
- } else if (netdev_speed <= SPEED_50000) {
- *width = IB_WIDTH_2X;
- *speed = IB_SPEED_EDR;
- } else if (netdev_speed <= SPEED_100000) {
- *width = IB_WIDTH_4X;
- *speed = IB_SPEED_EDR;
- } else if (netdev_speed <= SPEED_200000) {
- *width = IB_WIDTH_4X;
- *speed = IB_SPEED_HDR;
- } else {
- *width = IB_WIDTH_4X;
- *speed = IB_SPEED_NDR;
- }
-
- return;
- }
-
- switch (lanes) {
- case 1:
- *width = IB_WIDTH_1X;
- break;
- case 2:
- *width = IB_WIDTH_2X;
- break;
- case 4:
- *width = IB_WIDTH_4X;
- break;
- case 8:
- *width = IB_WIDTH_8X;
- break;
- case 12:
- *width = IB_WIDTH_12X;
- break;
- default:
- *width = IB_WIDTH_1X;
- }
-
- switch (netdev_speed / lanes) {
- case SPEED_2500:
- *speed = IB_SPEED_SDR;
- break;
- case SPEED_5000:
- *speed = IB_SPEED_DDR;
- break;
- case SPEED_10000:
- *speed = IB_SPEED_FDR10;
- break;
- case SPEED_14000:
- *speed = IB_SPEED_FDR;
- break;
- case SPEED_25000:
- *speed = IB_SPEED_EDR;
- break;
- case SPEED_50000:
- *speed = IB_SPEED_HDR;
- break;
- case SPEED_100000:
- *speed = IB_SPEED_NDR;
- break;
- default:
- *speed = IB_SPEED_SDR;
- }
-}
-
-int
-ib_get_eth_speed(struct ib_device *ibdev, u32 port_num, u16 *speed, u8 *width)
-{
- if_t netdev = ibdev->get_netdev(ibdev, port_num);
- u32 netdev_speed, lanes;
-
- if (!netdev)
- return -ENODEV;
-
- netdev_speed = (u32)if_getbaudrate(netdev);
- dev_put(netdev);
- lanes = 0;
-
- ib_get_width_and_speed(netdev_speed, lanes, speed, width);
-
- return 0;
-}
-
u64
irdma_mac_to_u64(const u8 *eth_add)
{
diff --git a/sys/ofed/drivers/infiniband/core/ib_verbs.c b/sys/ofed/drivers/infiniband/core/ib_verbs.c
index 532bba6325de..35e6ace39a01 100644
--- a/sys/ofed/drivers/infiniband/core/ib_verbs.c
+++ b/sys/ofed/drivers/infiniband/core/ib_verbs.c
@@ -1698,6 +1698,54 @@ int ib_modify_qp_with_udata(struct ib_qp *ib_qp, struct ib_qp_attr *attr,
}
EXPORT_SYMBOL(ib_modify_qp_with_udata);
+int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u16 *speed, u8 *width)
+{
+ uint64_t netdev_speed;
+ if_t netdev;
+
+ if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET)
+ return -EINVAL;
+
+ if (!dev->get_netdev)
+ return -EOPNOTSUPP;
+
+ netdev = dev->get_netdev(dev, port_num);
+ if (!netdev)
+ return -ENODEV;
+
+ netdev_speed = if_getbaudrate(netdev);
+
+ dev_put(netdev);
+
+ if (netdev_speed == 0) {
+ netdev_speed = IF_Mbps(1000);
+ if_printf(netdev, "speed is unknown, defaulting to 1Gbps\n");
+ }
+
+ if (netdev_speed <= IF_Mbps(1000)) {
+ *width = IB_WIDTH_1X;
+ *speed = IB_SPEED_SDR;
+ } else if (netdev_speed <= IF_Mbps(10000)) {
+ *width = IB_WIDTH_1X;
+ *speed = IB_SPEED_FDR10;
+ } else if (netdev_speed <= IF_Mbps(20000)) {
+ *width = IB_WIDTH_4X;
+ *speed = IB_SPEED_DDR;
+ } else if (netdev_speed <= IF_Mbps(25000)) {
+ *width = IB_WIDTH_1X;
+ *speed = IB_SPEED_EDR;
+ } else if (netdev_speed <= IF_Mbps(40000)) {
+ *width = IB_WIDTH_4X;
+ *speed = IB_SPEED_FDR10;
+ } else {
+ *width = IB_WIDTH_4X;
+ *speed = IB_SPEED_EDR;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(ib_get_eth_speed);
+
int ib_modify_qp(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask)
diff --git a/sys/ofed/include/rdma/ib_verbs.h b/sys/ofed/include/rdma/ib_verbs.h
index 8ac13023020b..3c81440e782f 100644
--- a/sys/ofed/include/rdma/ib_verbs.h
+++ b/sys/ofed/include/rdma/ib_verbs.h
@@ -3972,6 +3972,8 @@ struct ib_ucontext *ib_uverbs_get_ucontext_file(struct ib_uverbs_file *ufile);
int uverbs_destroy_def_handler(struct uverbs_attr_bundle *attrs);
+int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u16 *speed, u8 *width);
+
static inline u8 *rdma_ah_retrieve_dmac(struct rdma_ah_attr *attr)
{
if (attr->type == RDMA_AH_ATTR_TYPE_ROCE)