blob: 5bf3b20eba258ba2b46e0c57a25a6eaf4336ddd8 [file] [log] [blame]
Upinder Malhie3cf00d2013-09-10 03:38:16 +00001/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
Jeff Squyres3805ead2015-09-30 13:34:00 -07004 * 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 * BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
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.
Upinder Malhie3cf00d2013-09-10 03:38:16 +000022 *
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
30 * SOFTWARE.
31 *
32 * Author: Upinder Malhi <umalhi@cisco.com>
33 * Author: Anant Deepak <anadeepa@cisco.com>
34 * Author: Cesare Cantu' <cantuc@cisco.com>
35 * Author: Jeff Squyres <jsquyres@cisco.com>
36 * Author: Kiran Thirumalai <kithirum@cisco.com>
37 * Author: Xuyang Wang <xuywang@cisco.com>
38 * Author: Reese Faucette <rfaucett@cisco.com>
39 *
40 */
41
42#include <linux/module.h>
Upinder Malhic7845bc2014-01-09 14:48:17 -080043#include <linux/inetdevice.h>
Upinder Malhie3cf00d2013-09-10 03:38:16 +000044#include <linux/init.h>
45#include <linux/slab.h>
46#include <linux/errno.h>
47#include <linux/pci.h>
48#include <linux/netdevice.h>
49
50#include <rdma/ib_user_verbs.h>
51#include <rdma/ib_addr.h>
52
53#include "usnic_abi.h"
54#include "usnic_common_util.h"
55#include "usnic_ib.h"
56#include "usnic_ib_qp_grp.h"
57#include "usnic_log.h"
58#include "usnic_fwd.h"
59#include "usnic_debugfs.h"
60#include "usnic_ib_verbs.h"
61#include "usnic_transport.h"
62#include "usnic_uiom.h"
63#include "usnic_ib_sysfs.h"
64
65unsigned int usnic_log_lvl = USNIC_LOG_LVL_ERR;
66unsigned int usnic_ib_share_vf = 1;
67
68static const char usnic_version[] =
69 DRV_NAME ": Cisco VIC (USNIC) Verbs Driver v"
70 DRV_VERSION " (" DRV_RELDATE ")\n";
71
72static DEFINE_MUTEX(usnic_ib_ibdev_list_lock);
73static LIST_HEAD(usnic_ib_ibdev_list);
74
75/* Callback dump funcs */
76static int usnic_ib_dump_vf_hdr(void *obj, char *buf, int buf_sz)
77{
78 struct usnic_ib_vf *vf = obj;
79 return scnprintf(buf, buf_sz, "PF: %s ", vf->pf->ib_dev.name);
80}
81/* End callback dump funcs */
82
83static void usnic_ib_dump_vf(struct usnic_ib_vf *vf, char *buf, int buf_sz)
84{
85 usnic_vnic_dump(vf->vnic, buf, buf_sz, vf,
86 usnic_ib_dump_vf_hdr,
87 usnic_ib_qp_grp_dump_hdr, usnic_ib_qp_grp_dump_rows);
88}
89
90void usnic_ib_log_vf(struct usnic_ib_vf *vf)
91{
92 char buf[1000];
93 usnic_ib_dump_vf(vf, buf, sizeof(buf));
94 usnic_dbg("%s\n", buf);
95}
96
97/* Start of netdev section */
98static inline const char *usnic_ib_netdev_event_to_string(unsigned long event)
99{
Kirill Tkhaiede27622018-03-23 19:47:19 +0300100 return netdev_cmd_to_name(event);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000101}
102
103static void usnic_ib_qp_grp_modify_active_to_err(struct usnic_ib_dev *us_ibdev)
104{
105 struct usnic_ib_ucontext *ctx;
106 struct usnic_ib_qp_grp *qp_grp;
107 enum ib_qp_state cur_state;
108 int status;
109
110 BUG_ON(!mutex_is_locked(&us_ibdev->usdev_lock));
111
112 list_for_each_entry(ctx, &us_ibdev->ctx_list, link) {
113 list_for_each_entry(qp_grp, &ctx->qp_grp_list, link) {
114 cur_state = qp_grp->state;
115 if (cur_state == IB_QPS_INIT ||
116 cur_state == IB_QPS_RTR ||
117 cur_state == IB_QPS_RTS) {
118 status = usnic_ib_qp_grp_modify(qp_grp,
119 IB_QPS_ERR,
120 NULL);
121 if (status) {
122 usnic_err("Failed to transistion qp grp %u from %s to %s\n",
123 qp_grp->grp_id,
124 usnic_ib_qp_grp_state_to_string
125 (cur_state),
126 usnic_ib_qp_grp_state_to_string
127 (IB_QPS_ERR));
128 }
129 }
130 }
131 }
132}
133
134static void usnic_ib_handle_usdev_event(struct usnic_ib_dev *us_ibdev,
135 unsigned long event)
136{
137 struct net_device *netdev;
138 struct ib_event ib_event;
139
140 memset(&ib_event, 0, sizeof(ib_event));
141
142 mutex_lock(&us_ibdev->usdev_lock);
143 netdev = us_ibdev->netdev;
144 switch (event) {
145 case NETDEV_REBOOT:
146 usnic_info("PF Reset on %s\n", us_ibdev->ib_dev.name);
147 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
148 ib_event.event = IB_EVENT_PORT_ERR;
149 ib_event.device = &us_ibdev->ib_dev;
150 ib_event.element.port_num = 1;
151 ib_dispatch_event(&ib_event);
152 break;
153 case NETDEV_UP:
154 case NETDEV_DOWN:
155 case NETDEV_CHANGE:
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800156 if (!us_ibdev->ufdev->link_up &&
157 netif_carrier_ok(netdev)) {
158 usnic_fwd_carrier_up(us_ibdev->ufdev);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000159 usnic_info("Link UP on %s\n", us_ibdev->ib_dev.name);
160 ib_event.event = IB_EVENT_PORT_ACTIVE;
161 ib_event.device = &us_ibdev->ib_dev;
162 ib_event.element.port_num = 1;
163 ib_dispatch_event(&ib_event);
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800164 } else if (us_ibdev->ufdev->link_up &&
165 !netif_carrier_ok(netdev)) {
166 usnic_fwd_carrier_down(us_ibdev->ufdev);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000167 usnic_info("Link DOWN on %s\n", us_ibdev->ib_dev.name);
168 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
169 ib_event.event = IB_EVENT_PORT_ERR;
170 ib_event.device = &us_ibdev->ib_dev;
171 ib_event.element.port_num = 1;
172 ib_dispatch_event(&ib_event);
173 } else {
Roland Dreierc30392a2014-01-13 13:12:48 -0800174 usnic_dbg("Ignoring %s on %s\n",
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000175 usnic_ib_netdev_event_to_string(event),
176 us_ibdev->ib_dev.name);
177 }
178 break;
179 case NETDEV_CHANGEADDR:
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800180 if (!memcmp(us_ibdev->ufdev->mac, netdev->dev_addr,
181 sizeof(us_ibdev->ufdev->mac))) {
Roland Dreierc30392a2014-01-13 13:12:48 -0800182 usnic_dbg("Ignoring addr change on %s\n",
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000183 us_ibdev->ib_dev.name);
184 } else {
185 usnic_info(" %s old mac: %pM new mac: %pM\n",
186 us_ibdev->ib_dev.name,
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800187 us_ibdev->ufdev->mac,
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000188 netdev->dev_addr);
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800189 usnic_fwd_set_mac(us_ibdev->ufdev, netdev->dev_addr);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000190 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
191 ib_event.event = IB_EVENT_GID_CHANGE;
192 ib_event.device = &us_ibdev->ib_dev;
193 ib_event.element.port_num = 1;
194 ib_dispatch_event(&ib_event);
195 }
196
197 break;
198 case NETDEV_CHANGEMTU:
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800199 if (us_ibdev->ufdev->mtu != netdev->mtu) {
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000200 usnic_info("MTU Change on %s old: %u new: %u\n",
201 us_ibdev->ib_dev.name,
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800202 us_ibdev->ufdev->mtu, netdev->mtu);
203 usnic_fwd_set_mtu(us_ibdev->ufdev, netdev->mtu);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000204 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
205 } else {
206 usnic_dbg("Ignoring MTU change on %s\n",
207 us_ibdev->ib_dev.name);
208 }
209 break;
210 default:
Roland Dreierc30392a2014-01-13 13:12:48 -0800211 usnic_dbg("Ignoring event %s on %s",
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000212 usnic_ib_netdev_event_to_string(event),
213 us_ibdev->ib_dev.name);
214 }
215 mutex_unlock(&us_ibdev->usdev_lock);
216}
217
218static int usnic_ib_netdevice_event(struct notifier_block *notifier,
219 unsigned long event, void *ptr)
220{
221 struct usnic_ib_dev *us_ibdev;
222
223 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
224
225 mutex_lock(&usnic_ib_ibdev_list_lock);
226 list_for_each_entry(us_ibdev, &usnic_ib_ibdev_list, ib_dev_link) {
227 if (us_ibdev->netdev == netdev) {
228 usnic_ib_handle_usdev_event(us_ibdev, event);
229 break;
230 }
231 }
232 mutex_unlock(&usnic_ib_ibdev_list_lock);
233
234 return NOTIFY_DONE;
235}
236
237static struct notifier_block usnic_ib_netdevice_notifier = {
238 .notifier_call = usnic_ib_netdevice_event
239};
240/* End of netdev section */
241
Upinder Malhic7845bc2014-01-09 14:48:17 -0800242/* Start of inet section */
243static int usnic_ib_handle_inet_event(struct usnic_ib_dev *us_ibdev,
244 unsigned long event, void *ptr)
245{
246 struct in_ifaddr *ifa = ptr;
247 struct ib_event ib_event;
248
249 mutex_lock(&us_ibdev->usdev_lock);
250
251 switch (event) {
252 case NETDEV_DOWN:
253 usnic_info("%s via ip notifiers",
254 usnic_ib_netdev_event_to_string(event));
255 usnic_fwd_del_ipaddr(us_ibdev->ufdev);
256 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
257 ib_event.event = IB_EVENT_GID_CHANGE;
258 ib_event.device = &us_ibdev->ib_dev;
259 ib_event.element.port_num = 1;
260 ib_dispatch_event(&ib_event);
261 break;
262 case NETDEV_UP:
263 usnic_fwd_add_ipaddr(us_ibdev->ufdev, ifa->ifa_address);
264 usnic_info("%s via ip notifiers: ip %pI4",
265 usnic_ib_netdev_event_to_string(event),
266 &us_ibdev->ufdev->inaddr);
267 ib_event.event = IB_EVENT_GID_CHANGE;
268 ib_event.device = &us_ibdev->ib_dev;
269 ib_event.element.port_num = 1;
270 ib_dispatch_event(&ib_event);
271 break;
272 default:
Roland Dreierc30392a2014-01-13 13:12:48 -0800273 usnic_info("Ignoring event %s on %s",
Upinder Malhic7845bc2014-01-09 14:48:17 -0800274 usnic_ib_netdev_event_to_string(event),
275 us_ibdev->ib_dev.name);
276 }
277 mutex_unlock(&us_ibdev->usdev_lock);
278
279 return NOTIFY_DONE;
280}
281
282static int usnic_ib_inetaddr_event(struct notifier_block *notifier,
283 unsigned long event, void *ptr)
284{
285 struct usnic_ib_dev *us_ibdev;
286 struct in_ifaddr *ifa = ptr;
287 struct net_device *netdev = ifa->ifa_dev->dev;
288
289 mutex_lock(&usnic_ib_ibdev_list_lock);
290 list_for_each_entry(us_ibdev, &usnic_ib_ibdev_list, ib_dev_link) {
291 if (us_ibdev->netdev == netdev) {
292 usnic_ib_handle_inet_event(us_ibdev, event, ptr);
293 break;
294 }
295 }
296 mutex_unlock(&usnic_ib_ibdev_list_lock);
297
298 return NOTIFY_DONE;
299}
300static struct notifier_block usnic_ib_inetaddr_notifier = {
301 .notifier_call = usnic_ib_inetaddr_event
302};
303/* End of inet section*/
304
Ira Weiny77386132015-05-13 20:02:58 -0400305static int usnic_port_immutable(struct ib_device *ibdev, u8 port_num,
306 struct ib_port_immutable *immutable)
307{
308 struct ib_port_attr attr;
309 int err;
310
Or Gerlitzc4550c62017-01-24 13:02:39 +0200311 immutable->core_cap_flags = RDMA_CORE_PORT_USNIC;
312
313 err = ib_query_port(ibdev, port_num, &attr);
Ira Weiny77386132015-05-13 20:02:58 -0400314 if (err)
315 return err;
316
317 immutable->pkey_tbl_len = attr.pkey_tbl_len;
318 immutable->gid_tbl_len = attr.gid_tbl_len;
319
320 return 0;
321}
322
Leon Romanovsky9abb0d12017-06-27 16:49:53 +0300323static void usnic_get_dev_fw_str(struct ib_device *device, char *str)
Ira Weiny15453e82016-06-15 02:22:05 -0400324{
325 struct usnic_ib_dev *us_ibdev =
326 container_of(device, struct usnic_ib_dev, ib_dev);
327 struct ethtool_drvinfo info;
328
329 mutex_lock(&us_ibdev->usdev_lock);
330 us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, &info);
331 mutex_unlock(&us_ibdev->usdev_lock);
332
Leon Romanovsky9abb0d12017-06-27 16:49:53 +0300333 snprintf(str, IB_FW_VERSION_NAME_MAX, "%s", info.fw_version);
Ira Weiny15453e82016-06-15 02:22:05 -0400334}
335
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000336/* Start of PF discovery section */
337static void *usnic_ib_device_add(struct pci_dev *dev)
338{
339 struct usnic_ib_dev *us_ibdev;
340 union ib_gid gid;
Leon Romanovsky5d50f402017-08-17 15:50:41 +0300341 struct in_device *ind;
Upinder Malhic7845bc2014-01-09 14:48:17 -0800342 struct net_device *netdev;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000343
344 usnic_dbg("\n");
Upinder Malhic7845bc2014-01-09 14:48:17 -0800345 netdev = pci_get_drvdata(dev);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000346
347 us_ibdev = (struct usnic_ib_dev *)ib_alloc_device(sizeof(*us_ibdev));
Insu Yun2c79dad2015-10-15 21:15:15 +0000348 if (!us_ibdev) {
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000349 usnic_err("Device %s context alloc failed\n",
350 netdev_name(pci_get_drvdata(dev)));
Insu Yun2c79dad2015-10-15 21:15:15 +0000351 return ERR_PTR(-EFAULT);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000352 }
353
354 us_ibdev->ufdev = usnic_fwd_dev_alloc(dev);
Insu Yun2c79dad2015-10-15 21:15:15 +0000355 if (!us_ibdev->ufdev) {
356 usnic_err("Failed to alloc ufdev for %s\n", pci_name(dev));
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000357 goto err_dealloc;
358 }
359
360 mutex_init(&us_ibdev->usdev_lock);
361 INIT_LIST_HEAD(&us_ibdev->vf_dev_list);
362 INIT_LIST_HEAD(&us_ibdev->ctx_list);
363
364 us_ibdev->pdev = dev;
365 us_ibdev->netdev = pci_get_drvdata(dev);
366 us_ibdev->ib_dev.owner = THIS_MODULE;
Upinder Malhi61f78262014-01-15 17:02:37 -0800367 us_ibdev->ib_dev.node_type = RDMA_NODE_USNIC_UDP;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000368 us_ibdev->ib_dev.phys_port_cnt = USNIC_IB_PORT_CNT;
369 us_ibdev->ib_dev.num_comp_vectors = USNIC_IB_NUM_COMP_VECTORS;
Bart Van Assche6b06d522017-01-20 13:04:27 -0800370 us_ibdev->ib_dev.dev.parent = &dev->dev;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000371 us_ibdev->ib_dev.uverbs_abi_ver = USNIC_UVERBS_ABI_VERSION;
372 strlcpy(us_ibdev->ib_dev.name, "usnic_%d", IB_DEVICE_NAME_MAX);
373
374 us_ibdev->ib_dev.uverbs_cmd_mask =
375 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
376 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
377 (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
378 (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
379 (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
380 (1ull << IB_USER_VERBS_CMD_REG_MR) |
381 (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
382 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
383 (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
384 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
385 (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
386 (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
387 (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
388 (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
389 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) |
390 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) |
391 (1ull << IB_USER_VERBS_CMD_OPEN_QP);
392
393 us_ibdev->ib_dev.query_device = usnic_ib_query_device;
394 us_ibdev->ib_dev.query_port = usnic_ib_query_port;
395 us_ibdev->ib_dev.query_pkey = usnic_ib_query_pkey;
396 us_ibdev->ib_dev.query_gid = usnic_ib_query_gid;
Yuval Shaia44b0b742017-06-14 23:13:33 +0300397 us_ibdev->ib_dev.get_netdev = usnic_get_netdev;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000398 us_ibdev->ib_dev.get_link_layer = usnic_ib_port_link_layer;
399 us_ibdev->ib_dev.alloc_pd = usnic_ib_alloc_pd;
400 us_ibdev->ib_dev.dealloc_pd = usnic_ib_dealloc_pd;
401 us_ibdev->ib_dev.create_qp = usnic_ib_create_qp;
402 us_ibdev->ib_dev.modify_qp = usnic_ib_modify_qp;
403 us_ibdev->ib_dev.query_qp = usnic_ib_query_qp;
404 us_ibdev->ib_dev.destroy_qp = usnic_ib_destroy_qp;
405 us_ibdev->ib_dev.create_cq = usnic_ib_create_cq;
406 us_ibdev->ib_dev.destroy_cq = usnic_ib_destroy_cq;
407 us_ibdev->ib_dev.reg_user_mr = usnic_ib_reg_mr;
408 us_ibdev->ib_dev.dereg_mr = usnic_ib_dereg_mr;
409 us_ibdev->ib_dev.alloc_ucontext = usnic_ib_alloc_ucontext;
410 us_ibdev->ib_dev.dealloc_ucontext = usnic_ib_dealloc_ucontext;
411 us_ibdev->ib_dev.mmap = usnic_ib_mmap;
412 us_ibdev->ib_dev.create_ah = usnic_ib_create_ah;
413 us_ibdev->ib_dev.destroy_ah = usnic_ib_destroy_ah;
414 us_ibdev->ib_dev.post_send = usnic_ib_post_send;
415 us_ibdev->ib_dev.post_recv = usnic_ib_post_recv;
416 us_ibdev->ib_dev.poll_cq = usnic_ib_poll_cq;
417 us_ibdev->ib_dev.req_notify_cq = usnic_ib_req_notify_cq;
418 us_ibdev->ib_dev.get_dma_mr = usnic_ib_get_dma_mr;
Ira Weiny77386132015-05-13 20:02:58 -0400419 us_ibdev->ib_dev.get_port_immutable = usnic_port_immutable;
Ira Weiny15453e82016-06-15 02:22:05 -0400420 us_ibdev->ib_dev.get_dev_fw_str = usnic_get_dev_fw_str;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000421
422
423 if (ib_register_device(&us_ibdev->ib_dev, NULL))
424 goto err_fwd_dealloc;
425
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800426 usnic_fwd_set_mtu(us_ibdev->ufdev, us_ibdev->netdev->mtu);
427 usnic_fwd_set_mac(us_ibdev->ufdev, us_ibdev->netdev->dev_addr);
428 if (netif_carrier_ok(us_ibdev->netdev))
429 usnic_fwd_carrier_up(us_ibdev->ufdev);
430
Leon Romanovsky5d50f402017-08-17 15:50:41 +0300431 ind = in_dev_get(netdev);
432 if (ind->ifa_list)
433 usnic_fwd_add_ipaddr(us_ibdev->ufdev,
434 ind->ifa_list->ifa_address);
435 in_dev_put(ind);
Upinder Malhic7845bc2014-01-09 14:48:17 -0800436
437 usnic_mac_ip_to_gid(us_ibdev->netdev->perm_addr,
438 us_ibdev->ufdev->inaddr, &gid.raw[0]);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000439 memcpy(&us_ibdev->ib_dev.node_guid, &gid.global.interface_id,
440 sizeof(gid.global.interface_id));
441 kref_init(&us_ibdev->vf_cnt);
442
443 usnic_info("Added ibdev: %s netdev: %s with mac %pM Link: %u MTU: %u\n",
444 us_ibdev->ib_dev.name, netdev_name(us_ibdev->netdev),
Upinder Malhi8af94ac2014-01-09 14:48:08 -0800445 us_ibdev->ufdev->mac, us_ibdev->ufdev->link_up,
446 us_ibdev->ufdev->mtu);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000447 return us_ibdev;
448
449err_fwd_dealloc:
450 usnic_fwd_dev_free(us_ibdev->ufdev);
451err_dealloc:
452 usnic_err("failed -- deallocing device\n");
453 ib_dealloc_device(&us_ibdev->ib_dev);
454 return NULL;
455}
456
457static void usnic_ib_device_remove(struct usnic_ib_dev *us_ibdev)
458{
459 usnic_info("Unregistering %s\n", us_ibdev->ib_dev.name);
460 usnic_ib_sysfs_unregister_usdev(us_ibdev);
461 usnic_fwd_dev_free(us_ibdev->ufdev);
462 ib_unregister_device(&us_ibdev->ib_dev);
463 ib_dealloc_device(&us_ibdev->ib_dev);
464}
465
466static void usnic_ib_undiscover_pf(struct kref *kref)
467{
468 struct usnic_ib_dev *us_ibdev, *tmp;
469 struct pci_dev *dev;
470 bool found = false;
471
472 dev = container_of(kref, struct usnic_ib_dev, vf_cnt)->pdev;
473 mutex_lock(&usnic_ib_ibdev_list_lock);
474 list_for_each_entry_safe(us_ibdev, tmp,
475 &usnic_ib_ibdev_list, ib_dev_link) {
476 if (us_ibdev->pdev == dev) {
477 list_del(&us_ibdev->ib_dev_link);
478 usnic_ib_device_remove(us_ibdev);
479 found = true;
480 break;
481 }
482 }
483
484 WARN(!found, "Failed to remove PF %s\n", pci_name(dev));
485
486 mutex_unlock(&usnic_ib_ibdev_list_lock);
487}
488
489static struct usnic_ib_dev *usnic_ib_discover_pf(struct usnic_vnic *vnic)
490{
491 struct usnic_ib_dev *us_ibdev;
492 struct pci_dev *parent_pci, *vf_pci;
493 int err;
494
495 vf_pci = usnic_vnic_get_pdev(vnic);
496 parent_pci = pci_physfn(vf_pci);
497
498 BUG_ON(!parent_pci);
499
500 mutex_lock(&usnic_ib_ibdev_list_lock);
501 list_for_each_entry(us_ibdev, &usnic_ib_ibdev_list, ib_dev_link) {
502 if (us_ibdev->pdev == parent_pci) {
503 kref_get(&us_ibdev->vf_cnt);
504 goto out;
505 }
506 }
507
508 us_ibdev = usnic_ib_device_add(parent_pci);
509 if (IS_ERR_OR_NULL(us_ibdev)) {
Upinder Malhi6a54d9f2014-01-09 14:48:36 -0800510 us_ibdev = us_ibdev ? us_ibdev : ERR_PTR(-EFAULT);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000511 goto out;
512 }
513
514 err = usnic_ib_sysfs_register_usdev(us_ibdev);
515 if (err) {
516 usnic_ib_device_remove(us_ibdev);
517 us_ibdev = ERR_PTR(err);
518 goto out;
519 }
520
521 list_add(&us_ibdev->ib_dev_link, &usnic_ib_ibdev_list);
522out:
523 mutex_unlock(&usnic_ib_ibdev_list_lock);
524 return us_ibdev;
525}
526/* End of PF discovery section */
527
528/* Start of PCI section */
529
Benoit Taine9baa3c32014-08-08 15:56:03 +0200530static const struct pci_device_id usnic_ib_pci_ids[] = {
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000531 {PCI_DEVICE(PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_CISCO_VIC_USPACE_NIC)},
532 {0,}
533};
534
535static int usnic_ib_pci_probe(struct pci_dev *pdev,
536 const struct pci_device_id *id)
537{
538 int err;
539 struct usnic_ib_dev *pf;
540 struct usnic_ib_vf *vf;
541 enum usnic_vnic_res_type res_type;
542
543 vf = kzalloc(sizeof(*vf), GFP_KERNEL);
544 if (!vf)
545 return -ENOMEM;
546
547 err = pci_enable_device(pdev);
548 if (err) {
549 usnic_err("Failed to enable %s with err %d\n",
550 pci_name(pdev), err);
551 goto out_clean_vf;
552 }
553
554 err = pci_request_regions(pdev, DRV_NAME);
555 if (err) {
556 usnic_err("Failed to request region for %s with err %d\n",
557 pci_name(pdev), err);
558 goto out_disable_device;
559 }
560
561 pci_set_master(pdev);
562 pci_set_drvdata(pdev, vf);
563
564 vf->vnic = usnic_vnic_alloc(pdev);
565 if (IS_ERR_OR_NULL(vf->vnic)) {
Upinder Malhi6a54d9f2014-01-09 14:48:36 -0800566 err = vf->vnic ? PTR_ERR(vf->vnic) : -ENOMEM;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000567 usnic_err("Failed to alloc vnic for %s with err %d\n",
568 pci_name(pdev), err);
569 goto out_release_regions;
570 }
571
572 pf = usnic_ib_discover_pf(vf->vnic);
573 if (IS_ERR_OR_NULL(pf)) {
574 usnic_err("Failed to discover pf of vnic %s with err%ld\n",
575 pci_name(pdev), PTR_ERR(pf));
Upinder Malhi6a54d9f2014-01-09 14:48:36 -0800576 err = pf ? PTR_ERR(pf) : -EFAULT;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000577 goto out_clean_vnic;
578 }
579
580 vf->pf = pf;
581 spin_lock_init(&vf->lock);
582 mutex_lock(&pf->usdev_lock);
583 list_add_tail(&vf->link, &pf->vf_dev_list);
584 /*
585 * Save max settings (will be same for each VF, easier to re-write than
586 * to say "if (!set) { set_values(); set=1; }
587 */
588 for (res_type = USNIC_VNIC_RES_TYPE_EOL+1;
589 res_type < USNIC_VNIC_RES_TYPE_MAX;
590 res_type++) {
591 pf->vf_res_cnt[res_type] = usnic_vnic_res_cnt(vf->vnic,
592 res_type);
593 }
594
595 mutex_unlock(&pf->usdev_lock);
596
597 usnic_info("Registering usnic VF %s into PF %s\n", pci_name(pdev),
598 pf->ib_dev.name);
599 usnic_ib_log_vf(vf);
600 return 0;
601
602out_clean_vnic:
603 usnic_vnic_free(vf->vnic);
604out_release_regions:
605 pci_set_drvdata(pdev, NULL);
606 pci_clear_master(pdev);
607 pci_release_regions(pdev);
608out_disable_device:
609 pci_disable_device(pdev);
610out_clean_vf:
611 kfree(vf);
612 return err;
613}
614
615static void usnic_ib_pci_remove(struct pci_dev *pdev)
616{
617 struct usnic_ib_vf *vf = pci_get_drvdata(pdev);
618 struct usnic_ib_dev *pf = vf->pf;
619
620 mutex_lock(&pf->usdev_lock);
621 list_del(&vf->link);
622 mutex_unlock(&pf->usdev_lock);
623
624 kref_put(&pf->vf_cnt, usnic_ib_undiscover_pf);
625 usnic_vnic_free(vf->vnic);
626 pci_set_drvdata(pdev, NULL);
627 pci_clear_master(pdev);
628 pci_release_regions(pdev);
629 pci_disable_device(pdev);
630 kfree(vf);
631
632 usnic_info("Removed VF %s\n", pci_name(pdev));
633}
634
635/* PCI driver entry points */
636static struct pci_driver usnic_ib_pci_driver = {
637 .name = DRV_NAME,
638 .id_table = usnic_ib_pci_ids,
639 .probe = usnic_ib_pci_probe,
640 .remove = usnic_ib_pci_remove,
641};
642/* End of PCI section */
643
644/* Start of module section */
645static int __init usnic_ib_init(void)
646{
647 int err;
648
649 printk_once(KERN_INFO "%s", usnic_version);
650
651 err = usnic_uiom_init(DRV_NAME);
652 if (err) {
653 usnic_err("Unable to initalize umem with err %d\n", err);
654 return err;
655 }
656
Christophe Jaillet86cd7472016-08-10 17:45:01 +0200657 err = pci_register_driver(&usnic_ib_pci_driver);
658 if (err) {
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000659 usnic_err("Unable to register with PCI\n");
660 goto out_umem_fini;
661 }
662
663 err = register_netdevice_notifier(&usnic_ib_netdevice_notifier);
664 if (err) {
665 usnic_err("Failed to register netdev notifier\n");
666 goto out_pci_unreg;
667 }
668
Upinder Malhic7845bc2014-01-09 14:48:17 -0800669 err = register_inetaddr_notifier(&usnic_ib_inetaddr_notifier);
670 if (err) {
671 usnic_err("Failed to register inet addr notifier\n");
672 goto out_unreg_netdev_notifier;
673 }
674
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000675 err = usnic_transport_init();
676 if (err) {
677 usnic_err("Failed to initialize transport\n");
Upinder Malhic7845bc2014-01-09 14:48:17 -0800678 goto out_unreg_inetaddr_notifier;
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000679 }
680
681 usnic_debugfs_init();
682
683 return 0;
684
Upinder Malhic7845bc2014-01-09 14:48:17 -0800685out_unreg_inetaddr_notifier:
686 unregister_inetaddr_notifier(&usnic_ib_inetaddr_notifier);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000687out_unreg_netdev_notifier:
688 unregister_netdevice_notifier(&usnic_ib_netdevice_notifier);
689out_pci_unreg:
690 pci_unregister_driver(&usnic_ib_pci_driver);
691out_umem_fini:
692 usnic_uiom_fini();
693
694 return err;
695}
696
697static void __exit usnic_ib_destroy(void)
698{
699 usnic_dbg("\n");
700 usnic_debugfs_exit();
701 usnic_transport_fini();
Upinder Malhic7845bc2014-01-09 14:48:17 -0800702 unregister_inetaddr_notifier(&usnic_ib_inetaddr_notifier);
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000703 unregister_netdevice_notifier(&usnic_ib_netdevice_notifier);
704 pci_unregister_driver(&usnic_ib_pci_driver);
705 usnic_uiom_fini();
706}
707
708MODULE_DESCRIPTION("Cisco VIC (usNIC) Verbs Driver");
709MODULE_AUTHOR("Upinder Malhi <umalhi@cisco.com>");
710MODULE_LICENSE("Dual BSD/GPL");
Upinder Malhie3cf00d2013-09-10 03:38:16 +0000711module_param(usnic_log_lvl, uint, S_IRUGO | S_IWUSR);
712module_param(usnic_ib_share_vf, uint, S_IRUGO | S_IWUSR);
713MODULE_PARM_DESC(usnic_log_lvl, " Off=0, Err=1, Info=2, Debug=3");
714MODULE_PARM_DESC(usnic_ib_share_vf, "Off=0, On=1 VF sharing amongst QPs");
715MODULE_DEVICE_TABLE(pci, usnic_ib_pci_ids);
716
717module_init(usnic_ib_init);
718module_exit(usnic_ib_destroy);
719/* End of module section */