Skip to content

Commit 7074e2a

Browse files
committed
ionic: Add ionic provider
Introduce a provider for AMD pensando ionic device to user applications. Co-developed-by: Andrew Boyer <[email protected]> Signed-off-by: Andrew Boyer <[email protected]> Co-developed-by: Allen Hubbe <[email protected]> Signed-off-by: Allen Hubbe <[email protected]> Signed-off-by: Abhijit Gangurde <[email protected]>
1 parent e0cc03f commit 7074e2a

File tree

20 files changed

+4889
-3
lines changed

20 files changed

+4889
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ add_subdirectory(providers/efa/man)
731731
add_subdirectory(providers/erdma)
732732
add_subdirectory(providers/hns)
733733
add_subdirectory(providers/hns/man)
734+
add_subdirectory(providers/ionic)
734735
add_subdirectory(providers/irdma)
735736
add_subdirectory(providers/mana)
736737
add_subdirectory(providers/mana/man)

MAINTAINERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ M: Chengchang Tang <[email protected]>
7777
S: Supported
7878
F: providers/hns/
7979

80+
IONIC USERSPACE PROVIDER (for ionic_rdma.ko)
81+
M: Allen Hubbe <[email protected]>
82+
M: Andrew Boyer <[email protected]>
83+
M: Abhijit Gangurde <[email protected]>
84+
S: Supported
85+
F: providers/ionic/
86+
8087
IRDMA USERSPACE PROVIDER (for i40iw.ko and irdma.ko)
8188
M: Sindhu Devale <[email protected]>
8289
M: Tatyana Nikolova <[email protected]>

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ is included:
2020
- iw_cxgb4.ko
2121
- hfi1.ko
2222
- hns-roce-hw-v2.ko
23+
- ionic_rdma.ko
2324
- irdma.ko
2425
- ib_qib.ko
2526
- mana_ib.ko

debian/control

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ Description: User space provider drivers for libibverbs
8888
- erdma: Alibaba Elastic RDMA (iWarp) Adapter
8989
- hfi1verbs: Intel Omni-Path HFI
9090
- hns: HiSilicon Hip06 SoC
91+
- ionic: AMD Pensando Distributed Services Card (DSC) RDMA/RoCE Support
9192
- ipathverbs: QLogic InfiniPath HCAs
9293
- irdma: Intel Ethernet Connection RDMA
9394
- mana: Microsoft Azure Network Adapter

debian/copyright

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ Copyright: 2006-2010, QLogic Corp.
177177
2013, Intel Corporation
178178
License: BSD-MIT or GPL-2
179179

180+
Files: providers/ionic/*
181+
Copyright: 2018-2025, Advanced Micro Devices, Inc.
182+
License: BSD-MIT or GPL-2
183+
180184
Files: providers/irdma/*
181185
Copyright: 2015-2023, Intel Corporation.
182186
License: BSD-MIT or GPL-2

libibverbs/verbs.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,7 +2251,7 @@ struct ibv_device **ibv_get_device_list(int *num_devices);
22512251
*/
22522252
#ifdef RDMA_STATIC_PROVIDERS
22532253
#define _RDMA_STATIC_PREFIX_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, \
2254-
_12, _13, _14, _15, _16, _17, _18, _19, ...) \
2254+
_12, _13, _14, _15, _16, _17, _18, _19, _20, ...) \
22552255
&verbs_provider_##_1, &verbs_provider_##_2, &verbs_provider_##_3, \
22562256
&verbs_provider_##_4, &verbs_provider_##_5, \
22572257
&verbs_provider_##_6, &verbs_provider_##_7, \
@@ -2260,11 +2260,12 @@ struct ibv_device **ibv_get_device_list(int *num_devices);
22602260
&verbs_provider_##_12, &verbs_provider_##_13, \
22612261
&verbs_provider_##_14, &verbs_provider_##_15, \
22622262
&verbs_provider_##_16, &verbs_provider_##_17, \
2263-
&verbs_provider_##_18, &verbs_provider_##_19
2263+
&verbs_provider_##_18, &verbs_provider_##_19, \
2264+
&verbs_provider_##_20
22642265
#define _RDMA_STATIC_PREFIX(arg) \
22652266
_RDMA_STATIC_PREFIX_(arg, none, none, none, none, none, none, none, \
22662267
none, none, none, none, none, none, none, none, \
2267-
none, none, none)
2268+
none, none, none, none)
22682269

22692270
struct verbs_devices_ops;
22702271
extern const struct verbs_device_ops verbs_provider_bnxt_re;
@@ -2284,6 +2285,7 @@ extern const struct verbs_device_ops verbs_provider_qedr;
22842285
extern const struct verbs_device_ops verbs_provider_rxe;
22852286
extern const struct verbs_device_ops verbs_provider_siw;
22862287
extern const struct verbs_device_ops verbs_provider_vmw_pvrdma;
2288+
extern const struct verbs_device_ops verbs_provider_ionic;
22872289
extern const struct verbs_device_ops verbs_provider_all;
22882290
extern const struct verbs_device_ops verbs_provider_none;
22892291
void ibv_static_providers(void *unused, ...);

providers/ionic/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
rdma_provider(ionic
2+
ionic.c
3+
ionic_verbs.c
4+
ionic_memory.c
5+
ionic_queue.c
6+
)

providers/ionic/ionic-abi.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2+
/*
3+
* Copyright (c) 2018-2025 Advanced Micro Devices, Inc. All rights reserved.
4+
*/
5+
6+
#ifndef __IONIC_ABI_H__
7+
#define __IONIC_ABI_H__
8+
9+
#include <infiniband/kern-abi.h>
10+
#include <infiniband/verbs.h>
11+
#include <rdma/ionic-abi.h>
12+
#include <kernel-abi/ionic-abi.h>
13+
14+
#include "ionic_fw_types.h"
15+
16+
DECLARE_DRV_CMD(uionic_ctx, IB_USER_VERBS_CMD_GET_CONTEXT,
17+
ionic_ctx_req, ionic_ctx_resp);
18+
DECLARE_DRV_CMD(uionic_ah, IB_USER_VERBS_CMD_CREATE_AH,
19+
empty, ionic_ah_resp);
20+
DECLARE_DRV_CMD(uionic_cq, IB_USER_VERBS_CMD_CREATE_CQ,
21+
ionic_cq_req, ionic_cq_resp);
22+
DECLARE_DRV_CMD(uionic_qp, IB_USER_VERBS_EX_CMD_CREATE_QP,
23+
ionic_qp_req, ionic_qp_resp);
24+
25+
#endif /* __IONIC_ABI_H__ */

providers/ionic/ionic.c

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2+
/*
3+
* Copyright (c) 2018-2025 Advanced Micro Devices, Inc. All rights reserved.
4+
*/
5+
6+
#include <stdio.h>
7+
#include <stdlib.h>
8+
9+
#include "ionic.h"
10+
11+
extern const struct verbs_context_ops ionic_ctx_ops;
12+
struct ionic_global ionic_g;
13+
FILE *IONIC_DEBUG_FILE;
14+
15+
static int ionic_env_val_def(const char *name, int def)
16+
{
17+
const char *env = getenv(name);
18+
19+
if (!env)
20+
return def;
21+
22+
return atoi(env);
23+
}
24+
25+
static int ionic_env_val(const char *name)
26+
{
27+
return ionic_env_val_def(name, 0);
28+
}
29+
30+
static int ionic_env_ovrd_cmb(const char *name)
31+
{
32+
const char *env = getenv(name);
33+
int val;
34+
35+
if (!env)
36+
return -1;
37+
38+
/* flags can be represented as one number or as characters */
39+
val = atoi(env);
40+
if (strchr(env, 'e'))
41+
val |= IONIC_CMB_ENABLE;
42+
if (strchr(env, 'x'))
43+
val |= IONIC_CMB_ENABLE | IONIC_CMB_EXPDB;
44+
if (strchr(env, 'r'))
45+
val |= IONIC_CMB_REQUIRE;
46+
if (strchr(env, 'w'))
47+
val |= IONIC_CMB_WC;
48+
if (strchr(env, 'u'))
49+
val |= IONIC_CMB_UC;
50+
51+
return val;
52+
}
53+
54+
static int ionic_env_ovrd_sq_cmb(void)
55+
{
56+
return ionic_env_ovrd_cmb("IONIC_SQ_CMB");
57+
}
58+
59+
static int ionic_env_ovrd_rq_cmb(void)
60+
{
61+
return ionic_env_ovrd_cmb("IONIC_RQ_CMB");
62+
}
63+
64+
static int ionic_env_debug(void)
65+
{
66+
if (!(IONIC_DEBUG))
67+
return 0;
68+
69+
return ionic_env_val("IONIC_DEBUG");
70+
}
71+
72+
static void ionic_debug_file_close(void)
73+
{
74+
fclose(IONIC_DEBUG_FILE);
75+
}
76+
77+
static void ionic_debug_file_open(void)
78+
{
79+
const char *name = getenv("IONIC_DEBUG_FILE");
80+
81+
pthread_mutex_init(&ionic_g.mut, NULL);
82+
list_head_init(&ionic_g.cq_list);
83+
list_head_init(&ionic_g.qp_list);
84+
ionic_g.init = true;
85+
86+
if (!name)
87+
IONIC_DEBUG_FILE = IONIC_DEFAULT_DEBUG_FILE;
88+
else
89+
IONIC_DEBUG_FILE = fopen(name, "w");
90+
91+
if (!IONIC_DEBUG_FILE) {
92+
perror("ionic debug file: ");
93+
return;
94+
}
95+
96+
if (ionic_env_debug())
97+
_ionic_dbg(IONIC_DEBUG_FILE, "Initialized");
98+
99+
atexit(ionic_debug_file_close);
100+
}
101+
102+
static void ionic_debug_file_init(void)
103+
{
104+
static pthread_once_t once = PTHREAD_ONCE_INIT;
105+
106+
pthread_once(&once, ionic_debug_file_open);
107+
}
108+
109+
static struct verbs_context *ionic_alloc_context(struct ibv_device *ibdev,
110+
int cmd_fd,
111+
void *private_data)
112+
{
113+
struct ionic_dev *dev;
114+
struct ionic_ctx *ctx;
115+
struct uionic_ctx req = {};
116+
struct uionic_ctx_resp resp = {};
117+
uint64_t mask;
118+
int rc;
119+
120+
ionic_debug_file_init();
121+
122+
dev = to_ionic_dev(ibdev);
123+
ctx = verbs_init_and_alloc_context(ibdev, cmd_fd, ctx, vctx,
124+
RDMA_DRIVER_IONIC);
125+
if (!ctx) {
126+
rc = errno;
127+
goto err_ctx;
128+
}
129+
130+
rc = ibv_cmd_get_context(&ctx->vctx, &req.ibv_cmd, sizeof(req),
131+
NULL, &resp.ibv_resp, sizeof(resp));
132+
if (rc)
133+
goto err_cmd;
134+
135+
ctx->pg_shift = resp.page_shift;
136+
137+
if (resp.version < IONIC_MIN_RDMA_VERSION) {
138+
fprintf(stderr, "ionic: Firmware RDMA Version %u\n",
139+
resp.version);
140+
fprintf(stderr, "ionic: Driver Min RDMA Version %u\n",
141+
IONIC_MIN_RDMA_VERSION);
142+
rc = EINVAL;
143+
goto err_cmd;
144+
}
145+
146+
if (resp.version > IONIC_MAX_RDMA_VERSION) {
147+
fprintf(stderr, "ionic: Firmware RDMA Version %u\n",
148+
resp.version);
149+
fprintf(stderr, "ionic: Driver Max RDMA Version %u\n",
150+
IONIC_MAX_RDMA_VERSION);
151+
rc = EINVAL;
152+
goto err_cmd;
153+
}
154+
155+
ctx->version = resp.version;
156+
ctx->opcodes = resp.qp_opcodes;
157+
if (ctx->version == 1 && ctx->opcodes <= IONIC_V1_OP_BIND_MW) {
158+
fprintf(stderr, "ionic: qp opcodes %d want min %d\n",
159+
ctx->opcodes, IONIC_V1_OP_BIND_MW + 1);
160+
rc = EINVAL;
161+
goto err_cmd;
162+
}
163+
164+
if (resp.udma_count != 1 && resp.udma_count != 2) {
165+
fprintf(stderr, "ionic: udma_count %d invalid\n",
166+
resp.udma_count);
167+
rc = EINVAL;
168+
goto err_cmd;
169+
}
170+
ctx->udma_count = resp.udma_count;
171+
172+
ctx->sq_qtype = resp.sq_qtype;
173+
ctx->rq_qtype = resp.rq_qtype;
174+
ctx->cq_qtype = resp.cq_qtype;
175+
176+
ctx->max_stride = resp.max_stride;
177+
178+
ctx->expdb_mask = resp.expdb_mask;
179+
ctx->sq_expdb = !!(resp.expdb_qtypes & IONIC_EXPDB_SQ);
180+
ctx->rq_expdb = !!(resp.expdb_qtypes & IONIC_EXPDB_RQ);
181+
182+
ctx->ovrd_sq_cmb = ionic_env_ovrd_sq_cmb();
183+
ctx->ovrd_rq_cmb = ionic_env_ovrd_rq_cmb();
184+
185+
mask = (1u << ctx->pg_shift) - 1;
186+
ctx->dbpage_page = ionic_map_device(1u << ctx->pg_shift, cmd_fd,
187+
resp.dbell_offset & ~mask);
188+
if (!ctx->dbpage_page) {
189+
rc = errno;
190+
goto err_cmd;
191+
}
192+
ctx->dbpage = ctx->dbpage_page + (resp.dbell_offset & mask);
193+
194+
pthread_mutex_init(&ctx->mut, NULL);
195+
ionic_tbl_init(&ctx->qp_tbl);
196+
197+
verbs_set_ops(&ctx->vctx, &ionic_ctx_ops);
198+
199+
if (dev->abi_ver <= 1) {
200+
ctx->spec = 0;
201+
} else {
202+
ctx->spec = resp.max_spec;
203+
if (ctx->spec < 0 || ctx->spec > 16)
204+
ctx->spec = 0;
205+
}
206+
207+
if (ionic_env_debug()) {
208+
ctx->dbg_file = IONIC_DEBUG_FILE;
209+
ionic_dbg(ctx, "Attached to ctx %p", ctx);
210+
}
211+
212+
return &ctx->vctx;
213+
214+
err_cmd:
215+
verbs_uninit_context(&ctx->vctx);
216+
err_ctx:
217+
errno = rc;
218+
return NULL;
219+
}
220+
221+
static const struct verbs_match_ent cna_table[] = {
222+
VERBS_DRIVER_ID(RDMA_DRIVER_IONIC),
223+
{}
224+
};
225+
226+
static struct verbs_device *ionic_alloc_device(struct verbs_sysfs_dev *sdev)
227+
{
228+
struct ionic_dev *dev;
229+
230+
static_assert(sizeof(struct ionic_v1_cqe) == 32, "bad size");
231+
static_assert(sizeof(struct ionic_v1_base_hdr) == 16, "bad size");
232+
static_assert(sizeof(struct ionic_v1_recv_bdy) == 48, "bad size");
233+
static_assert(sizeof(struct ionic_v1_common_bdy) == 48, "bad size");
234+
static_assert(sizeof(struct ionic_v1_atomic_bdy) == 48, "bad size");
235+
static_assert(sizeof(struct ionic_v1_bind_mw_bdy) == 48, "bad size");
236+
static_assert(sizeof(struct ionic_v1_wqe) == 64, "bad size");
237+
238+
dev = calloc(1, sizeof(*dev));
239+
if (!dev)
240+
return NULL;
241+
242+
dev->abi_ver = sdev->abi_ver;
243+
244+
return &dev->vdev;
245+
}
246+
247+
static void ionic_uninit_device(struct verbs_device *vdev)
248+
{
249+
struct ionic_dev *dev = to_ionic_dev(&vdev->device);
250+
251+
free(dev);
252+
}
253+
254+
static const struct verbs_device_ops ionic_dev_ops = {
255+
.name = "ionic",
256+
.match_min_abi_version = IONIC_ABI_VERSION,
257+
.match_max_abi_version = IONIC_ABI_VERSION,
258+
.match_table = cna_table,
259+
.alloc_device = ionic_alloc_device,
260+
.uninit_device = ionic_uninit_device,
261+
.alloc_context = ionic_alloc_context,
262+
};
263+
264+
PROVIDER_DRIVER(ionic, ionic_dev_ops);

0 commit comments

Comments
 (0)