Skip to content

Commit d418619

Browse files
Yuval Shaiadledford
authored andcommitted
IB/core: Add generic function to extract IB speed from netdev
Logic of retrieving netdev speed from net_device and translating it to IB speed is implemented in rxe, in usnic and in bnxt drivers. Define new function which merges all. Signed-off-by: Yuval Shaia <[email protected]> Reviewed-by: Christian Benvenuti <[email protected]> Reviewed-by: Selvin Xavier <[email protected]> Reviewed-by: Moni Shoua <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 44b0b74 commit d418619

File tree

6 files changed

+73
-118
lines changed

6 files changed

+73
-118
lines changed

drivers/infiniband/core/roce_gid_mgmt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444

4545
static struct workqueue_struct *gid_cache_wq;
4646

47+
static struct workqueue_struct *gid_cache_wq;
48+
4749
enum gid_op_type {
4850
GID_DEL = 0,
4951
GID_ADD

drivers/infiniband/core/verbs.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,61 @@ int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
13021302
}
13031303
EXPORT_SYMBOL(ib_modify_qp_with_udata);
13041304

1305+
int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u8 *speed, u8 *width)
1306+
{
1307+
int rc;
1308+
u32 netdev_speed;
1309+
struct net_device *netdev;
1310+
struct ethtool_link_ksettings lksettings;
1311+
1312+
if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET)
1313+
return -EINVAL;
1314+
1315+
if (!dev->get_netdev)
1316+
return -EOPNOTSUPP;
1317+
1318+
netdev = dev->get_netdev(dev, port_num);
1319+
if (!netdev)
1320+
return -ENODEV;
1321+
1322+
rtnl_lock();
1323+
rc = __ethtool_get_link_ksettings(netdev, &lksettings);
1324+
rtnl_unlock();
1325+
1326+
dev_put(netdev);
1327+
1328+
if (!rc) {
1329+
netdev_speed = lksettings.base.speed;
1330+
} else {
1331+
netdev_speed = SPEED_1000;
1332+
pr_warn("%s speed is unknown, defaulting to %d\n", netdev->name,
1333+
netdev_speed);
1334+
}
1335+
1336+
if (netdev_speed <= SPEED_1000) {
1337+
*width = IB_WIDTH_1X;
1338+
*speed = IB_SPEED_SDR;
1339+
} else if (netdev_speed <= SPEED_10000) {
1340+
*width = IB_WIDTH_1X;
1341+
*speed = IB_SPEED_FDR10;
1342+
} else if (netdev_speed <= SPEED_20000) {
1343+
*width = IB_WIDTH_4X;
1344+
*speed = IB_SPEED_DDR;
1345+
} else if (netdev_speed <= SPEED_25000) {
1346+
*width = IB_WIDTH_1X;
1347+
*speed = IB_SPEED_EDR;
1348+
} else if (netdev_speed <= SPEED_40000) {
1349+
*width = IB_WIDTH_4X;
1350+
*speed = IB_SPEED_FDR10;
1351+
} else {
1352+
*width = IB_WIDTH_4X;
1353+
*speed = IB_SPEED_EDR;
1354+
}
1355+
1356+
return 0;
1357+
}
1358+
EXPORT_SYMBOL(ib_get_eth_speed);
1359+
13051360
int ib_modify_qp(struct ib_qp *qp,
13061361
struct ib_qp_attr *qp_attr,
13071362
int qp_attr_mask)

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -223,50 +223,6 @@ int bnxt_re_modify_device(struct ib_device *ibdev,
223223
return 0;
224224
}
225225

226-
static void __to_ib_speed_width(struct net_device *netdev, u8 *speed, u8 *width)
227-
{
228-
struct ethtool_link_ksettings lksettings;
229-
u32 espeed;
230-
231-
if (netdev->ethtool_ops && netdev->ethtool_ops->get_link_ksettings) {
232-
memset(&lksettings, 0, sizeof(lksettings));
233-
rtnl_lock();
234-
netdev->ethtool_ops->get_link_ksettings(netdev, &lksettings);
235-
rtnl_unlock();
236-
espeed = lksettings.base.speed;
237-
} else {
238-
espeed = SPEED_UNKNOWN;
239-
}
240-
switch (espeed) {
241-
case SPEED_1000:
242-
*speed = IB_SPEED_SDR;
243-
*width = IB_WIDTH_1X;
244-
break;
245-
case SPEED_10000:
246-
*speed = IB_SPEED_QDR;
247-
*width = IB_WIDTH_1X;
248-
break;
249-
case SPEED_20000:
250-
*speed = IB_SPEED_DDR;
251-
*width = IB_WIDTH_4X;
252-
break;
253-
case SPEED_25000:
254-
*speed = IB_SPEED_EDR;
255-
*width = IB_WIDTH_1X;
256-
break;
257-
case SPEED_40000:
258-
*speed = IB_SPEED_QDR;
259-
*width = IB_WIDTH_4X;
260-
break;
261-
case SPEED_50000:
262-
break;
263-
default:
264-
*speed = IB_SPEED_SDR;
265-
*width = IB_WIDTH_1X;
266-
break;
267-
}
268-
}
269-
270226
/* Port */
271227
int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
272228
struct ib_port_attr *port_attr)
@@ -308,8 +264,9 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
308264
* IB stack to avoid race in the NETDEV_UNREG path
309265
*/
310266
if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
311-
__to_ib_speed_width(rdev->netdev, &port_attr->active_speed,
312-
&port_attr->active_width);
267+
if (!ib_get_eth_speed(ibdev, port_num, &port_attr->active_speed,
268+
&port_attr->active_width))
269+
return -EINVAL;
313270
return 0;
314271
}
315272

drivers/infiniband/hw/usnic/usnic_ib_verbs.c

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -226,27 +226,6 @@ static void qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp)
226226
spin_unlock(&vf->lock);
227227
}
228228

229-
static void eth_speed_to_ib_speed(int speed, u8 *active_speed,
230-
u8 *active_width)
231-
{
232-
if (speed <= 10000) {
233-
*active_width = IB_WIDTH_1X;
234-
*active_speed = IB_SPEED_FDR10;
235-
} else if (speed <= 20000) {
236-
*active_width = IB_WIDTH_4X;
237-
*active_speed = IB_SPEED_DDR;
238-
} else if (speed <= 30000) {
239-
*active_width = IB_WIDTH_4X;
240-
*active_speed = IB_SPEED_QDR;
241-
} else if (speed <= 40000) {
242-
*active_width = IB_WIDTH_4X;
243-
*active_speed = IB_SPEED_FDR10;
244-
} else {
245-
*active_width = IB_WIDTH_4X;
246-
*active_speed = IB_SPEED_EDR;
247-
}
248-
}
249-
250229
static int create_qp_validate_user_data(struct usnic_ib_create_qp_cmd cmd)
251230
{
252231
if (cmd.spec.trans_type <= USNIC_TRANSPORT_UNKNOWN ||
@@ -326,12 +305,16 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
326305
struct ib_port_attr *props)
327306
{
328307
struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
329-
struct ethtool_link_ksettings cmd;
330308

331309
usnic_dbg("\n");
332310

333311
mutex_lock(&us_ibdev->usdev_lock);
334-
__ethtool_get_link_ksettings(us_ibdev->netdev, &cmd);
312+
if (!ib_get_eth_speed(ibdev, port, &props->active_speed,
313+
&props->active_width)) {
314+
mutex_unlock(&us_ibdev->usdev_lock);
315+
return -EINVAL;
316+
}
317+
335318
/* props being zeroed by the caller, avoid zeroing it here */
336319

337320
props->lid = 0;
@@ -355,8 +338,6 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
355338
props->pkey_tbl_len = 1;
356339
props->bad_pkey_cntr = 0;
357340
props->qkey_viol_cntr = 0;
358-
eth_speed_to_ib_speed(cmd.base.speed, &props->active_speed,
359-
&props->active_width);
360341
props->max_mtu = IB_MTU_4096;
361342
props->active_mtu = iboe_get_mtu(us_ibdev->ufdev->mtu);
362343
/* Userspace will adjust for hdrs */

drivers/infiniband/sw/rxe/rxe_verbs.c

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -51,40 +51,16 @@ static int rxe_query_device(struct ib_device *dev,
5151
return 0;
5252
}
5353

54-
static void rxe_eth_speed_to_ib_speed(int speed, u8 *active_speed,
55-
u8 *active_width)
56-
{
57-
if (speed <= 1000) {
58-
*active_width = IB_WIDTH_1X;
59-
*active_speed = IB_SPEED_SDR;
60-
} else if (speed <= 10000) {
61-
*active_width = IB_WIDTH_1X;
62-
*active_speed = IB_SPEED_FDR10;
63-
} else if (speed <= 20000) {
64-
*active_width = IB_WIDTH_4X;
65-
*active_speed = IB_SPEED_DDR;
66-
} else if (speed <= 30000) {
67-
*active_width = IB_WIDTH_4X;
68-
*active_speed = IB_SPEED_QDR;
69-
} else if (speed <= 40000) {
70-
*active_width = IB_WIDTH_4X;
71-
*active_speed = IB_SPEED_FDR10;
72-
} else {
73-
*active_width = IB_WIDTH_4X;
74-
*active_speed = IB_SPEED_EDR;
75-
}
76-
}
77-
7854
static int rxe_query_port(struct ib_device *dev,
7955
u8 port_num, struct ib_port_attr *attr)
8056
{
8157
struct rxe_dev *rxe = to_rdev(dev);
8258
struct rxe_port *port;
83-
u32 speed;
59+
int rc = -EINVAL;
8460

8561
if (unlikely(port_num != 1)) {
8662
pr_warn("invalid port_number %d\n", port_num);
87-
goto err1;
63+
goto out;
8864
}
8965

9066
port = &rxe->port;
@@ -93,29 +69,12 @@ static int rxe_query_port(struct ib_device *dev,
9369
*attr = port->attr;
9470

9571
mutex_lock(&rxe->usdev_lock);
96-
if (rxe->ndev->ethtool_ops->get_link_ksettings) {
97-
struct ethtool_link_ksettings ks;
98-
99-
rxe->ndev->ethtool_ops->get_link_ksettings(rxe->ndev, &ks);
100-
speed = ks.base.speed;
101-
} else if (rxe->ndev->ethtool_ops->get_settings) {
102-
struct ethtool_cmd cmd;
103-
104-
rxe->ndev->ethtool_ops->get_settings(rxe->ndev, &cmd);
105-
speed = cmd.speed;
106-
} else {
107-
pr_warn("%s speed is unknown, defaulting to 1000\n",
108-
rxe->ndev->name);
109-
speed = 1000;
110-
}
111-
rxe_eth_speed_to_ib_speed(speed, &attr->active_speed,
112-
&attr->active_width);
72+
rc = ib_get_eth_speed(dev, port_num, &attr->active_speed,
73+
&attr->active_width);
11374
mutex_unlock(&rxe->usdev_lock);
11475

115-
return 0;
116-
117-
err1:
118-
return -EINVAL;
76+
out:
77+
return rc;
11978
}
12079

12180
static int rxe_query_gid(struct ib_device *device,

include/rdma/ib_verbs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,6 +3555,7 @@ void ib_drain_qp(struct ib_qp *qp);
35553555

35563556
int ib_resolve_eth_dmac(struct ib_device *device,
35573557
struct rdma_ah_attr *ah_attr);
3558+
int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u8 *speed, u8 *width);
35583559

35593560
static inline u8 *rdma_ah_retrieve_dmac(struct rdma_ah_attr *attr)
35603561
{

0 commit comments

Comments
 (0)