Skip to content

Commit 8498a30

Browse files
mustafakismailjgunthorpe
authored andcommitted
RDMA/irdma: Register auxiliary driver and implement private channel OPs
Register auxiliary drivers which can attach to auxiliary RDMA devices from Intel PCI netdev drivers i40e and ice. Implement the private channel ops, and register net notifiers. Link: https://lore.kernel.org/r/[email protected] [flexible array transformation] Signed-off-by: Gustavo A. R. Silva <[email protected]> Signed-off-by: Mustafa Ismail <[email protected]> Signed-off-by: Shiraz Saleem <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent f4370a8 commit 8498a30

File tree

3 files changed

+1129
-0
lines changed

3 files changed

+1129
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
2+
/* Copyright (c) 2015 - 2021 Intel Corporation */
3+
#include "main.h"
4+
#include "i40iw_hw.h"
5+
#include <linux/net/intel/i40e_client.h>
6+
7+
static struct i40e_client i40iw_client;
8+
9+
/**
10+
* i40iw_l2param_change - handle mss change
11+
* @cdev_info: parent lan device information structure with data/ops
12+
* @client: client for parameter change
13+
* @params: new parameters from L2
14+
*/
15+
static void i40iw_l2param_change(struct i40e_info *cdev_info,
16+
struct i40e_client *client,
17+
struct i40e_params *params)
18+
{
19+
struct irdma_l2params l2params = {};
20+
struct irdma_device *iwdev;
21+
struct ib_device *ibdev;
22+
23+
ibdev = ib_device_get_by_netdev(cdev_info->netdev, RDMA_DRIVER_IRDMA);
24+
if (!ibdev)
25+
return;
26+
27+
iwdev = to_iwdev(ibdev);
28+
29+
if (iwdev->vsi.mtu != params->mtu) {
30+
l2params.mtu_changed = true;
31+
l2params.mtu = params->mtu;
32+
}
33+
irdma_change_l2params(&iwdev->vsi, &l2params);
34+
ib_device_put(ibdev);
35+
}
36+
37+
/**
38+
* i40iw_close - client interface operation close for iwarp/uda device
39+
* @cdev_info: parent lan device information structure with data/ops
40+
* @client: client to close
41+
* @reset: flag to indicate close on reset
42+
*
43+
* Called by the lan driver during the processing of client unregister
44+
* Destroy and clean up the driver resources
45+
*/
46+
static void i40iw_close(struct i40e_info *cdev_info, struct i40e_client *client,
47+
bool reset)
48+
{
49+
struct irdma_device *iwdev;
50+
struct ib_device *ibdev;
51+
52+
ibdev = ib_device_get_by_netdev(cdev_info->netdev, RDMA_DRIVER_IRDMA);
53+
if (WARN_ON(!ibdev))
54+
return;
55+
56+
iwdev = to_iwdev(ibdev);
57+
if (reset)
58+
iwdev->reset = true;
59+
60+
iwdev->iw_status = 0;
61+
irdma_port_ibevent(iwdev);
62+
ib_unregister_device_and_put(ibdev);
63+
pr_debug("INIT: Gen1 PF[%d] close complete\n", PCI_FUNC(cdev_info->pcidev->devfn));
64+
}
65+
66+
static void i40iw_request_reset(struct irdma_pci_f *rf)
67+
{
68+
struct i40e_info *cdev_info = rf->cdev;
69+
70+
cdev_info->ops->request_reset(cdev_info, &i40iw_client, 1);
71+
}
72+
73+
static void i40iw_fill_device_info(struct irdma_device *iwdev, struct i40e_info *cdev_info)
74+
{
75+
struct irdma_pci_f *rf = iwdev->rf;
76+
77+
rf->rdma_ver = IRDMA_GEN_1;
78+
rf->gen_ops.request_reset = i40iw_request_reset;
79+
rf->pcidev = cdev_info->pcidev;
80+
rf->hw.hw_addr = cdev_info->hw_addr;
81+
rf->cdev = cdev_info;
82+
rf->msix_count = cdev_info->msix_count;
83+
rf->msix_entries = cdev_info->msix_entries;
84+
rf->limits_sel = 5;
85+
rf->protocol_used = IRDMA_IWARP_PROTOCOL_ONLY;
86+
rf->iwdev = iwdev;
87+
88+
iwdev->init_state = INITIAL_STATE;
89+
iwdev->rcv_wnd = IRDMA_CM_DEFAULT_RCV_WND_SCALED;
90+
iwdev->rcv_wscale = IRDMA_CM_DEFAULT_RCV_WND_SCALE;
91+
iwdev->netdev = cdev_info->netdev;
92+
iwdev->vsi_num = 0;
93+
}
94+
95+
/**
96+
* i40iw_open - client interface operation open for iwarp/uda device
97+
* @cdev_info: parent lan device information structure with data/ops
98+
* @client: iwarp client information, provided during registration
99+
*
100+
* Called by the lan driver during the processing of client register
101+
* Create device resources, set up queues, pble and hmc objects and
102+
* register the device with the ib verbs interface
103+
* Return 0 if successful, otherwise return error
104+
*/
105+
static int i40iw_open(struct i40e_info *cdev_info, struct i40e_client *client)
106+
{
107+
struct irdma_l2params l2params = {};
108+
struct irdma_device *iwdev;
109+
struct irdma_pci_f *rf;
110+
int err = -EIO;
111+
int i;
112+
u16 qset;
113+
u16 last_qset = IRDMA_NO_QSET;
114+
115+
iwdev = ib_alloc_device(irdma_device, ibdev);
116+
if (!iwdev)
117+
return -ENOMEM;
118+
119+
iwdev->rf = kzalloc(sizeof(*rf), GFP_KERNEL);
120+
if (!iwdev->rf) {
121+
ib_dealloc_device(&iwdev->ibdev);
122+
return -ENOMEM;
123+
}
124+
125+
i40iw_fill_device_info(iwdev, cdev_info);
126+
rf = iwdev->rf;
127+
128+
if (irdma_ctrl_init_hw(rf)) {
129+
err = -EIO;
130+
goto err_ctrl_init;
131+
}
132+
133+
l2params.mtu = (cdev_info->params.mtu) ? cdev_info->params.mtu : IRDMA_DEFAULT_MTU;
134+
for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++) {
135+
qset = cdev_info->params.qos.prio_qos[i].qs_handle;
136+
l2params.up2tc[i] = cdev_info->params.qos.prio_qos[i].tc;
137+
l2params.qs_handle_list[i] = qset;
138+
if (last_qset == IRDMA_NO_QSET)
139+
last_qset = qset;
140+
else if ((qset != last_qset) && (qset != IRDMA_NO_QSET))
141+
iwdev->dcb = true;
142+
}
143+
144+
if (irdma_rt_init_hw(iwdev, &l2params)) {
145+
err = -EIO;
146+
goto err_rt_init;
147+
}
148+
149+
err = irdma_ib_register_device(iwdev);
150+
if (err)
151+
goto err_ibreg;
152+
153+
ibdev_dbg(&iwdev->ibdev, "INIT: Gen1 PF[%d] open success\n",
154+
PCI_FUNC(rf->pcidev->devfn));
155+
156+
return 0;
157+
158+
err_ibreg:
159+
irdma_rt_deinit_hw(iwdev);
160+
err_rt_init:
161+
irdma_ctrl_deinit_hw(rf);
162+
err_ctrl_init:
163+
kfree(iwdev->rf);
164+
ib_dealloc_device(&iwdev->ibdev);
165+
166+
return err;
167+
}
168+
169+
/* client interface functions */
170+
static const struct i40e_client_ops i40e_ops = {
171+
.open = i40iw_open,
172+
.close = i40iw_close,
173+
.l2_param_change = i40iw_l2param_change
174+
};
175+
176+
static struct i40e_client i40iw_client = {
177+
.ops = &i40e_ops,
178+
.type = I40E_CLIENT_IWARP,
179+
};
180+
181+
static int i40iw_probe(struct auxiliary_device *aux_dev, const struct auxiliary_device_id *id)
182+
{
183+
struct i40e_auxiliary_device *i40e_adev = container_of(aux_dev,
184+
struct i40e_auxiliary_device,
185+
aux_dev);
186+
struct i40e_info *cdev_info = i40e_adev->ldev;
187+
188+
strncpy(i40iw_client.name, "irdma", I40E_CLIENT_STR_LENGTH);
189+
i40e_client_device_register(cdev_info, &i40iw_client);
190+
191+
return 0;
192+
}
193+
194+
static void i40iw_remove(struct auxiliary_device *aux_dev)
195+
{
196+
struct i40e_auxiliary_device *i40e_adev = container_of(aux_dev,
197+
struct i40e_auxiliary_device,
198+
aux_dev);
199+
struct i40e_info *cdev_info = i40e_adev->ldev;
200+
201+
return i40e_client_device_unregister(cdev_info);
202+
}
203+
204+
static const struct auxiliary_device_id i40iw_auxiliary_id_table[] = {
205+
{.name = "i40e.iwarp", },
206+
{},
207+
};
208+
209+
MODULE_DEVICE_TABLE(auxiliary, i40iw_auxiliary_id_table);
210+
211+
struct auxiliary_driver i40iw_auxiliary_drv = {
212+
.name = "gen_1",
213+
.id_table = i40iw_auxiliary_id_table,
214+
.probe = i40iw_probe,
215+
.remove = i40iw_remove,
216+
};

0 commit comments

Comments
 (0)