1 /* QLogic qedr NIC Driver
2 * Copyright (c) 2015-2017 QLogic Corporation
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and /or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 #include <linux/pci.h>
33 #include <linux/netdevice.h>
34 #include <linux/list.h>
35 #include <linux/mutex.h>
36 #include <linux/qed/qede_rdma.h>
39 static struct qedr_driver
*qedr_drv
;
40 static LIST_HEAD(qedr_dev_list
);
41 static DEFINE_MUTEX(qedr_dev_list_lock
);
43 bool qede_rdma_supported(struct qede_dev
*dev
)
45 return dev
->dev_info
.common
.rdma_supported
;
48 static void _qede_rdma_dev_add(struct qede_dev
*edev
)
53 edev
->rdma_info
.qedr_dev
= qedr_drv
->add(edev
->cdev
, edev
->pdev
,
57 static int qede_rdma_create_wq(struct qede_dev
*edev
)
59 INIT_LIST_HEAD(&edev
->rdma_info
.rdma_event_list
);
60 edev
->rdma_info
.rdma_wq
= create_singlethread_workqueue("rdma_wq");
61 if (!edev
->rdma_info
.rdma_wq
) {
62 DP_NOTICE(edev
, "qedr: Could not create workqueue\n");
69 static void qede_rdma_cleanup_event(struct qede_dev
*edev
)
71 struct list_head
*head
= &edev
->rdma_info
.rdma_event_list
;
72 struct qede_rdma_event_work
*event_node
;
74 flush_workqueue(edev
->rdma_info
.rdma_wq
);
75 while (!list_empty(head
)) {
76 event_node
= list_entry(head
->next
, struct qede_rdma_event_work
,
78 cancel_work_sync(&event_node
->work
);
79 list_del(&event_node
->list
);
84 static void qede_rdma_destroy_wq(struct qede_dev
*edev
)
86 qede_rdma_cleanup_event(edev
);
87 destroy_workqueue(edev
->rdma_info
.rdma_wq
);
90 int qede_rdma_dev_add(struct qede_dev
*edev
)
94 if (qede_rdma_supported(edev
)) {
95 rc
= qede_rdma_create_wq(edev
);
99 INIT_LIST_HEAD(&edev
->rdma_info
.entry
);
100 mutex_lock(&qedr_dev_list_lock
);
101 list_add_tail(&edev
->rdma_info
.entry
, &qedr_dev_list
);
102 _qede_rdma_dev_add(edev
);
103 mutex_unlock(&qedr_dev_list_lock
);
109 static void _qede_rdma_dev_remove(struct qede_dev
*edev
)
111 if (qedr_drv
&& qedr_drv
->remove
&& edev
->rdma_info
.qedr_dev
)
112 qedr_drv
->remove(edev
->rdma_info
.qedr_dev
);
113 edev
->rdma_info
.qedr_dev
= NULL
;
116 void qede_rdma_dev_remove(struct qede_dev
*edev
)
118 if (!qede_rdma_supported(edev
))
121 qede_rdma_destroy_wq(edev
);
122 mutex_lock(&qedr_dev_list_lock
);
123 _qede_rdma_dev_remove(edev
);
124 list_del(&edev
->rdma_info
.entry
);
125 mutex_unlock(&qedr_dev_list_lock
);
128 static void _qede_rdma_dev_open(struct qede_dev
*edev
)
130 if (qedr_drv
&& edev
->rdma_info
.qedr_dev
&& qedr_drv
->notify
)
131 qedr_drv
->notify(edev
->rdma_info
.qedr_dev
, QEDE_UP
);
134 static void qede_rdma_dev_open(struct qede_dev
*edev
)
136 if (!qede_rdma_supported(edev
))
139 mutex_lock(&qedr_dev_list_lock
);
140 _qede_rdma_dev_open(edev
);
141 mutex_unlock(&qedr_dev_list_lock
);
144 static void _qede_rdma_dev_close(struct qede_dev
*edev
)
146 if (qedr_drv
&& edev
->rdma_info
.qedr_dev
&& qedr_drv
->notify
)
147 qedr_drv
->notify(edev
->rdma_info
.qedr_dev
, QEDE_DOWN
);
150 static void qede_rdma_dev_close(struct qede_dev
*edev
)
152 if (!qede_rdma_supported(edev
))
155 mutex_lock(&qedr_dev_list_lock
);
156 _qede_rdma_dev_close(edev
);
157 mutex_unlock(&qedr_dev_list_lock
);
160 static void qede_rdma_dev_shutdown(struct qede_dev
*edev
)
162 if (!qede_rdma_supported(edev
))
165 mutex_lock(&qedr_dev_list_lock
);
166 if (qedr_drv
&& edev
->rdma_info
.qedr_dev
&& qedr_drv
->notify
)
167 qedr_drv
->notify(edev
->rdma_info
.qedr_dev
, QEDE_CLOSE
);
168 mutex_unlock(&qedr_dev_list_lock
);
171 int qede_rdma_register_driver(struct qedr_driver
*drv
)
173 struct qede_dev
*edev
;
176 mutex_lock(&qedr_dev_list_lock
);
178 mutex_unlock(&qedr_dev_list_lock
);
183 list_for_each_entry(edev
, &qedr_dev_list
, rdma_info
.entry
) {
184 struct net_device
*ndev
;
187 _qede_rdma_dev_add(edev
);
189 if (netif_running(ndev
) && netif_oper_up(ndev
))
190 _qede_rdma_dev_open(edev
);
192 mutex_unlock(&qedr_dev_list_lock
);
194 pr_notice("qedr: discovered and registered %d RDMA funcs\n",
199 EXPORT_SYMBOL(qede_rdma_register_driver
);
201 void qede_rdma_unregister_driver(struct qedr_driver
*drv
)
203 struct qede_dev
*edev
;
205 mutex_lock(&qedr_dev_list_lock
);
206 list_for_each_entry(edev
, &qedr_dev_list
, rdma_info
.entry
) {
207 if (edev
->rdma_info
.qedr_dev
)
208 _qede_rdma_dev_remove(edev
);
211 mutex_unlock(&qedr_dev_list_lock
);
213 EXPORT_SYMBOL(qede_rdma_unregister_driver
);
215 static void qede_rdma_changeaddr(struct qede_dev
*edev
)
217 if (!qede_rdma_supported(edev
))
220 if (qedr_drv
&& edev
->rdma_info
.qedr_dev
&& qedr_drv
->notify
)
221 qedr_drv
->notify(edev
->rdma_info
.qedr_dev
, QEDE_CHANGE_ADDR
);
224 static struct qede_rdma_event_work
*
225 qede_rdma_get_free_event_node(struct qede_dev
*edev
)
227 struct qede_rdma_event_work
*event_node
= NULL
;
228 struct list_head
*list_node
= NULL
;
231 list_for_each(list_node
, &edev
->rdma_info
.rdma_event_list
) {
232 event_node
= list_entry(list_node
, struct qede_rdma_event_work
,
234 if (!work_pending(&event_node
->work
)) {
241 event_node
= kzalloc(sizeof(*event_node
), GFP_KERNEL
);
244 "qedr: Could not allocate memory for rdma work\n");
247 list_add_tail(&event_node
->list
,
248 &edev
->rdma_info
.rdma_event_list
);
254 static void qede_rdma_handle_event(struct work_struct
*work
)
256 struct qede_rdma_event_work
*event_node
;
257 enum qede_rdma_event event
;
258 struct qede_dev
*edev
;
260 event_node
= container_of(work
, struct qede_rdma_event_work
, work
);
261 event
= event_node
->event
;
262 edev
= event_node
->ptr
;
266 qede_rdma_dev_open(edev
);
269 qede_rdma_dev_close(edev
);
272 qede_rdma_dev_shutdown(edev
);
274 case QEDE_CHANGE_ADDR
:
275 qede_rdma_changeaddr(edev
);
278 DP_NOTICE(edev
, "Invalid rdma event %d", event
);
282 static void qede_rdma_add_event(struct qede_dev
*edev
,
283 enum qede_rdma_event event
)
285 struct qede_rdma_event_work
*event_node
;
287 if (!edev
->rdma_info
.qedr_dev
)
290 event_node
= qede_rdma_get_free_event_node(edev
);
294 event_node
->event
= event
;
295 event_node
->ptr
= edev
;
297 INIT_WORK(&event_node
->work
, qede_rdma_handle_event
);
298 queue_work(edev
->rdma_info
.rdma_wq
, &event_node
->work
);
301 void qede_rdma_dev_event_open(struct qede_dev
*edev
)
303 qede_rdma_add_event(edev
, QEDE_UP
);
306 void qede_rdma_dev_event_close(struct qede_dev
*edev
)
308 qede_rdma_add_event(edev
, QEDE_DOWN
);
311 void qede_rdma_event_changeaddr(struct qede_dev
*edev
)
313 qede_rdma_add_event(edev
, QEDE_CHANGE_ADDR
);