Skip to content

Commit 0c2b80c

Browse files
mustafakismailrleon
authored andcommitted
RDMA/irdma: Refactor GEN2 auxiliary driver
Refactor the irdma auxiliary driver and associated interfaces out of main.c and into a standalone GEN2-specific source file and rename as gen_2 driver. This is in preparation for adding GEN3 auxiliary drivers. Each HW generation will have its own gen-specific interface file. Additionally, move the Address Handle hash table and associated locks under rf struct. This will allow GEN3 code to migrate to use it easily. Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com> Co-developed-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com> Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com> Link: https://patch.msgid.link/20250827152545.2056-2-tatyana.e.nikolova@intel.com Tested-by: Jacob Moroni <jmoroni@google.com> Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 2bd7dd3 commit 0c2b80c

6 files changed

Lines changed: 360 additions & 354 deletions

File tree

drivers/infiniband/hw/irdma/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ irdma-objs := cm.o \
1313
hw.o \
1414
i40iw_hw.o \
1515
i40iw_if.o \
16+
icrdma_if.o \
1617
icrdma_hw.o \
1718
main.o \
1819
pble.o \

drivers/infiniband/hw/irdma/i40iw_if.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ static void i40iw_fill_device_info(struct irdma_device *iwdev, struct i40e_info
7575
struct irdma_pci_f *rf = iwdev->rf;
7676

7777
rf->rdma_ver = IRDMA_GEN_1;
78+
rf->sc_dev.hw = &rf->hw;
79+
rf->sc_dev.hw_attrs.uk_attrs.hw_rev = IRDMA_GEN_1;
7880
rf->gen_ops.request_reset = i40iw_request_reset;
7981
rf->pcidev = cdev_info->pcidev;
8082
rf->pf_id = cdev_info->fid;
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
2+
/* Copyright (c) 2015 - 2024 Intel Corporation */
3+
4+
#include "main.h"
5+
#include <linux/net/intel/iidc_rdma_ice.h>
6+
7+
static void icrdma_prep_tc_change(struct irdma_device *iwdev)
8+
{
9+
iwdev->vsi.tc_change_pending = true;
10+
irdma_sc_suspend_resume_qps(&iwdev->vsi, IRDMA_OP_SUSPEND);
11+
12+
/* Wait for all qp's to suspend */
13+
wait_event_timeout(iwdev->suspend_wq,
14+
!atomic_read(&iwdev->vsi.qp_suspend_reqs),
15+
msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS));
16+
irdma_ws_reset(&iwdev->vsi);
17+
}
18+
19+
static void icrdma_fill_qos_info(struct irdma_l2params *l2params,
20+
struct iidc_rdma_qos_params *qos_info)
21+
{
22+
int i;
23+
24+
l2params->num_tc = qos_info->num_tc;
25+
l2params->vsi_prio_type = qos_info->vport_priority_type;
26+
l2params->vsi_rel_bw = qos_info->vport_relative_bw;
27+
for (i = 0; i < l2params->num_tc; i++) {
28+
l2params->tc_info[i].egress_virt_up =
29+
qos_info->tc_info[i].egress_virt_up;
30+
l2params->tc_info[i].ingress_virt_up =
31+
qos_info->tc_info[i].ingress_virt_up;
32+
l2params->tc_info[i].prio_type = qos_info->tc_info[i].prio_type;
33+
l2params->tc_info[i].rel_bw = qos_info->tc_info[i].rel_bw;
34+
l2params->tc_info[i].tc_ctx = qos_info->tc_info[i].tc_ctx;
35+
}
36+
for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
37+
l2params->up2tc[i] = qos_info->up2tc[i];
38+
if (qos_info->pfc_mode == IIDC_DSCP_PFC_MODE) {
39+
l2params->dscp_mode = true;
40+
memcpy(l2params->dscp_map, qos_info->dscp_map, sizeof(l2params->dscp_map));
41+
}
42+
}
43+
44+
static void icrdma_iidc_event_handler(struct iidc_rdma_core_dev_info *cdev_info,
45+
struct iidc_rdma_event *event)
46+
{
47+
struct irdma_device *iwdev = dev_get_drvdata(&cdev_info->adev->dev);
48+
struct irdma_l2params l2params = {};
49+
50+
if (*event->type & BIT(IIDC_RDMA_EVENT_AFTER_MTU_CHANGE)) {
51+
ibdev_dbg(&iwdev->ibdev, "CLNT: new MTU = %d\n", iwdev->netdev->mtu);
52+
if (iwdev->vsi.mtu != iwdev->netdev->mtu) {
53+
l2params.mtu = iwdev->netdev->mtu;
54+
l2params.mtu_changed = true;
55+
irdma_log_invalid_mtu(l2params.mtu, &iwdev->rf->sc_dev);
56+
irdma_change_l2params(&iwdev->vsi, &l2params);
57+
}
58+
} else if (*event->type & BIT(IIDC_RDMA_EVENT_BEFORE_TC_CHANGE)) {
59+
if (iwdev->vsi.tc_change_pending)
60+
return;
61+
62+
icrdma_prep_tc_change(iwdev);
63+
} else if (*event->type & BIT(IIDC_RDMA_EVENT_AFTER_TC_CHANGE)) {
64+
struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv;
65+
66+
if (!iwdev->vsi.tc_change_pending)
67+
return;
68+
69+
l2params.tc_changed = true;
70+
ibdev_dbg(&iwdev->ibdev, "CLNT: TC Change\n");
71+
72+
icrdma_fill_qos_info(&l2params, &idc_priv->qos_info);
73+
if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
74+
iwdev->dcb_vlan_mode =
75+
l2params.num_tc > 1 && !l2params.dscp_mode;
76+
irdma_change_l2params(&iwdev->vsi, &l2params);
77+
} else if (*event->type & BIT(IIDC_RDMA_EVENT_CRIT_ERR)) {
78+
ibdev_warn(&iwdev->ibdev, "ICE OICR event notification: oicr = 0x%08x\n",
79+
event->reg);
80+
if (event->reg & IRDMAPFINT_OICR_PE_CRITERR_M) {
81+
u32 pe_criterr;
82+
83+
pe_criterr = readl(iwdev->rf->sc_dev.hw_regs[IRDMA_GLPE_CRITERR]);
84+
#define IRDMA_Q1_RESOURCE_ERR 0x0001024d
85+
if (pe_criterr != IRDMA_Q1_RESOURCE_ERR) {
86+
ibdev_err(&iwdev->ibdev, "critical PE Error, GLPE_CRITERR=0x%08x\n",
87+
pe_criterr);
88+
iwdev->rf->reset = true;
89+
} else {
90+
ibdev_warn(&iwdev->ibdev, "Q1 Resource Check\n");
91+
}
92+
}
93+
if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) {
94+
ibdev_err(&iwdev->ibdev, "HMC Error\n");
95+
iwdev->rf->reset = true;
96+
}
97+
if (event->reg & IRDMAPFINT_OICR_PE_PUSH_M) {
98+
ibdev_err(&iwdev->ibdev, "PE Push Error\n");
99+
iwdev->rf->reset = true;
100+
}
101+
if (iwdev->rf->reset)
102+
iwdev->rf->gen_ops.request_reset(iwdev->rf);
103+
}
104+
}
105+
106+
/**
107+
* icrdma_lan_register_qset - Register qset with LAN driver
108+
* @vsi: vsi structure
109+
* @tc_node: Traffic class node
110+
*/
111+
static int icrdma_lan_register_qset(struct irdma_sc_vsi *vsi,
112+
struct irdma_ws_node *tc_node)
113+
{
114+
struct irdma_device *iwdev = vsi->back_vsi;
115+
struct iidc_rdma_core_dev_info *cdev_info = iwdev->rf->cdev;
116+
struct iidc_rdma_qset_params qset = {};
117+
int ret;
118+
119+
qset.qs_handle = tc_node->qs_handle;
120+
qset.tc = tc_node->traffic_class;
121+
qset.vport_id = vsi->vsi_idx;
122+
ret = ice_add_rdma_qset(cdev_info, &qset);
123+
if (ret) {
124+
ibdev_dbg(&iwdev->ibdev, "WS: LAN alloc_res for rdma qset failed.\n");
125+
return ret;
126+
}
127+
128+
tc_node->l2_sched_node_id = qset.teid;
129+
vsi->qos[tc_node->user_pri].l2_sched_node_id = qset.teid;
130+
131+
return 0;
132+
}
133+
134+
/**
135+
* icrdma_lan_unregister_qset - Unregister qset with LAN driver
136+
* @vsi: vsi structure
137+
* @tc_node: Traffic class node
138+
*/
139+
static void icrdma_lan_unregister_qset(struct irdma_sc_vsi *vsi,
140+
struct irdma_ws_node *tc_node)
141+
{
142+
struct irdma_device *iwdev = vsi->back_vsi;
143+
struct iidc_rdma_core_dev_info *cdev_info = iwdev->rf->cdev;
144+
struct iidc_rdma_qset_params qset = {};
145+
146+
qset.qs_handle = tc_node->qs_handle;
147+
qset.tc = tc_node->traffic_class;
148+
qset.vport_id = vsi->vsi_idx;
149+
qset.teid = tc_node->l2_sched_node_id;
150+
151+
if (ice_del_rdma_qset(cdev_info, &qset))
152+
ibdev_dbg(&iwdev->ibdev, "WS: LAN free_res for rdma qset failed.\n");
153+
}
154+
155+
/**
156+
* icrdma_request_reset - Request a reset
157+
* @rf: RDMA PCI function
158+
*/
159+
static void icrdma_request_reset(struct irdma_pci_f *rf)
160+
{
161+
ibdev_warn(&rf->iwdev->ibdev, "Requesting a reset\n");
162+
ice_rdma_request_reset(rf->cdev, IIDC_FUNC_RESET);
163+
}
164+
165+
static int icrdma_init_interrupts(struct irdma_pci_f *rf, struct iidc_rdma_core_dev_info *cdev)
166+
{
167+
int i;
168+
169+
rf->msix_count = num_online_cpus() + IRDMA_NUM_AEQ_MSIX;
170+
rf->msix_entries = kcalloc(rf->msix_count, sizeof(*rf->msix_entries),
171+
GFP_KERNEL);
172+
if (!rf->msix_entries)
173+
return -ENOMEM;
174+
175+
for (i = 0; i < rf->msix_count; i++)
176+
if (ice_alloc_rdma_qvector(cdev, &rf->msix_entries[i]))
177+
break;
178+
179+
if (i < IRDMA_MIN_MSIX) {
180+
while (--i >= 0)
181+
ice_free_rdma_qvector(cdev, &rf->msix_entries[i]);
182+
183+
kfree(rf->msix_entries);
184+
return -ENOMEM;
185+
}
186+
187+
rf->msix_count = i;
188+
189+
return 0;
190+
}
191+
192+
static void icrdma_deinit_interrupts(struct irdma_pci_f *rf, struct iidc_rdma_core_dev_info *cdev)
193+
{
194+
int i;
195+
196+
for (i = 0; i < rf->msix_count; i++)
197+
ice_free_rdma_qvector(cdev, &rf->msix_entries[i]);
198+
199+
kfree(rf->msix_entries);
200+
}
201+
202+
static void icrdma_fill_device_info(struct irdma_device *iwdev,
203+
struct iidc_rdma_core_dev_info *cdev_info)
204+
{
205+
struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv;
206+
struct irdma_pci_f *rf = iwdev->rf;
207+
208+
rf->sc_dev.hw = &rf->hw;
209+
rf->iwdev = iwdev;
210+
rf->cdev = cdev_info;
211+
rf->hw.hw_addr = idc_priv->hw_addr;
212+
rf->pcidev = cdev_info->pdev;
213+
rf->hw.device = &rf->pcidev->dev;
214+
rf->pf_id = idc_priv->pf_id;
215+
rf->rdma_ver = IRDMA_GEN_2;
216+
rf->sc_dev.hw_attrs.uk_attrs.hw_rev = IRDMA_GEN_2;
217+
218+
rf->gen_ops.register_qset = icrdma_lan_register_qset;
219+
rf->gen_ops.unregister_qset = icrdma_lan_unregister_qset;
220+
221+
rf->default_vsi.vsi_idx = idc_priv->vport_id;
222+
rf->protocol_used =
223+
cdev_info->rdma_protocol == IIDC_RDMA_PROTOCOL_ROCEV2 ?
224+
IRDMA_ROCE_PROTOCOL_ONLY : IRDMA_IWARP_PROTOCOL_ONLY;
225+
rf->rsrc_profile = IRDMA_HMC_PROFILE_DEFAULT;
226+
rf->rst_to = IRDMA_RST_TIMEOUT_HZ;
227+
rf->gen_ops.request_reset = icrdma_request_reset;
228+
rf->limits_sel = 7;
229+
mutex_init(&rf->ah_tbl_lock);
230+
231+
iwdev->netdev = idc_priv->netdev;
232+
iwdev->vsi_num = idc_priv->vport_id;
233+
iwdev->init_state = INITIAL_STATE;
234+
iwdev->roce_cwnd = IRDMA_ROCE_CWND_DEFAULT;
235+
iwdev->roce_ackcreds = IRDMA_ROCE_ACKCREDS_DEFAULT;
236+
iwdev->rcv_wnd = IRDMA_CM_DEFAULT_RCV_WND_SCALED;
237+
iwdev->rcv_wscale = IRDMA_CM_DEFAULT_RCV_WND_SCALE;
238+
if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
239+
iwdev->roce_mode = true;
240+
}
241+
242+
static int icrdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary_device_id *id)
243+
{
244+
struct iidc_rdma_core_auxiliary_dev *iidc_adev;
245+
struct iidc_rdma_core_dev_info *cdev_info;
246+
struct iidc_rdma_priv_dev_info *idc_priv;
247+
struct irdma_l2params l2params = {};
248+
struct irdma_device *iwdev;
249+
struct irdma_pci_f *rf;
250+
int err;
251+
252+
iidc_adev = container_of(aux_dev, struct iidc_rdma_core_auxiliary_dev, adev);
253+
cdev_info = iidc_adev->cdev_info;
254+
idc_priv = cdev_info->iidc_priv;
255+
256+
iwdev = ib_alloc_device(irdma_device, ibdev);
257+
if (!iwdev)
258+
return -ENOMEM;
259+
iwdev->rf = kzalloc(sizeof(*rf), GFP_KERNEL);
260+
if (!iwdev->rf) {
261+
ib_dealloc_device(&iwdev->ibdev);
262+
return -ENOMEM;
263+
}
264+
265+
icrdma_fill_device_info(iwdev, cdev_info);
266+
rf = iwdev->rf;
267+
268+
err = icrdma_init_interrupts(rf, cdev_info);
269+
if (err)
270+
goto err_init_interrupts;
271+
272+
err = irdma_ctrl_init_hw(rf);
273+
if (err)
274+
goto err_ctrl_init;
275+
276+
l2params.mtu = iwdev->netdev->mtu;
277+
icrdma_fill_qos_info(&l2params, &idc_priv->qos_info);
278+
if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
279+
iwdev->dcb_vlan_mode = l2params.num_tc > 1 && !l2params.dscp_mode;
280+
281+
err = irdma_rt_init_hw(iwdev, &l2params);
282+
if (err)
283+
goto err_rt_init;
284+
285+
err = irdma_ib_register_device(iwdev);
286+
if (err)
287+
goto err_ibreg;
288+
289+
ice_rdma_update_vsi_filter(cdev_info, iwdev->vsi_num, true);
290+
291+
ibdev_dbg(&iwdev->ibdev, "INIT: Gen2 PF[%d] device probe success\n", PCI_FUNC(rf->pcidev->devfn));
292+
auxiliary_set_drvdata(aux_dev, iwdev);
293+
294+
return 0;
295+
296+
err_ibreg:
297+
irdma_rt_deinit_hw(iwdev);
298+
err_rt_init:
299+
irdma_ctrl_deinit_hw(rf);
300+
err_ctrl_init:
301+
icrdma_deinit_interrupts(rf, cdev_info);
302+
err_init_interrupts:
303+
kfree(iwdev->rf);
304+
ib_dealloc_device(&iwdev->ibdev);
305+
306+
return err;
307+
}
308+
309+
static void icrdma_remove(struct auxiliary_device *aux_dev)
310+
{
311+
struct iidc_rdma_core_auxiliary_dev *idc_adev =
312+
container_of(aux_dev, struct iidc_rdma_core_auxiliary_dev, adev);
313+
struct iidc_rdma_core_dev_info *cdev_info = idc_adev->cdev_info;
314+
struct irdma_device *iwdev = auxiliary_get_drvdata(aux_dev);
315+
u8 rdma_ver = iwdev->rf->rdma_ver;
316+
317+
ice_rdma_update_vsi_filter(cdev_info, iwdev->vsi_num, false);
318+
irdma_ib_unregister_device(iwdev);
319+
icrdma_deinit_interrupts(iwdev->rf, cdev_info);
320+
321+
pr_debug("INIT: Gen[%d] func[%d] device remove success\n",
322+
rdma_ver, PCI_FUNC(cdev_info->pdev->devfn));
323+
}
324+
325+
static const struct auxiliary_device_id icrdma_auxiliary_id_table[] = {
326+
{.name = "ice.iwarp", },
327+
{.name = "ice.roce", },
328+
{},
329+
};
330+
331+
MODULE_DEVICE_TABLE(auxiliary, icrdma_auxiliary_id_table);
332+
333+
struct iidc_rdma_core_auxiliary_drv icrdma_core_auxiliary_drv = {
334+
.adrv = {
335+
.name = "gen_2",
336+
.id_table = icrdma_auxiliary_id_table,
337+
.probe = icrdma_probe,
338+
.remove = icrdma_remove,
339+
},
340+
.event_handler = icrdma_iidc_event_handler,
341+
};

0 commit comments

Comments
 (0)