Linux Audio

Check our new training course

Loading...
  1/*******************************************************************
  2 * This file is part of the Emulex RoCE Device Driver for          *
  3 * RoCE (RDMA over Converged Ethernet) adapters.                   *
  4 * Copyright (C) 2008-2012 Emulex. All rights reserved.            *
  5 * EMULEX and SLI are trademarks of Emulex.                        *
  6 * www.emulex.com                                                  *
  7 *                                                                 *
  8 * This program is free software; you can redistribute it and/or   *
  9 * modify it under the terms of version 2 of the GNU General       *
 10 * Public License as published by the Free Software Foundation.    *
 11 * This program is distributed in the hope that it will be useful. *
 12 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 13 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 14 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 15 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 16 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 17 * more details, a copy of which can be found in the file COPYING  *
 18 * included with this package.                                     *
 19 *
 20 * Contact Information:
 21 * linux-drivers@emulex.com
 22 *
 23 * Emulex
 24 * 3333 Susan Street
 25 * Costa Mesa, CA 92626
 26 *******************************************************************/
 27
 28#include <linux/module.h>
 29#include <linux/idr.h>
 30#include <rdma/ib_verbs.h>
 31#include <rdma/ib_user_verbs.h>
 32#include <rdma/ib_addr.h>
 33
 34#include <linux/netdevice.h>
 35#include <net/addrconf.h>
 36
 37#include "ocrdma.h"
 38#include "ocrdma_verbs.h"
 39#include "ocrdma_ah.h"
 40#include "be_roce.h"
 41#include "ocrdma_hw.h"
 42
 43MODULE_VERSION(OCRDMA_ROCE_DEV_VERSION);
 44MODULE_DESCRIPTION("Emulex RoCE HCA Driver");
 45MODULE_AUTHOR("Emulex Corporation");
 46MODULE_LICENSE("GPL");
 47
 48static LIST_HEAD(ocrdma_dev_list);
 49static DEFINE_SPINLOCK(ocrdma_devlist_lock);
 50static DEFINE_IDR(ocrdma_dev_id);
 51
 52static union ib_gid ocrdma_zero_sgid;
 53
 54static int ocrdma_get_instance(void)
 55{
 56	int instance = 0;
 57
 58	/* Assign an unused number */
 59	if (!idr_pre_get(&ocrdma_dev_id, GFP_KERNEL))
 60		return -1;
 61	if (idr_get_new(&ocrdma_dev_id, NULL, &instance))
 62		return -1;
 63	return instance;
 64}
 65
 66void ocrdma_get_guid(struct ocrdma_dev *dev, u8 *guid)
 67{
 68	u8 mac_addr[6];
 69
 70	memcpy(&mac_addr[0], &dev->nic_info.mac_addr[0], ETH_ALEN);
 71	guid[0] = mac_addr[0] ^ 2;
 72	guid[1] = mac_addr[1];
 73	guid[2] = mac_addr[2];
 74	guid[3] = 0xff;
 75	guid[4] = 0xfe;
 76	guid[5] = mac_addr[3];
 77	guid[6] = mac_addr[4];
 78	guid[7] = mac_addr[5];
 79}
 80
 81static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr,
 82				  bool is_vlan, u16 vlan_id)
 83{
 84	sgid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
 85	sgid->raw[8] = mac_addr[0] ^ 2;
 86	sgid->raw[9] = mac_addr[1];
 87	sgid->raw[10] = mac_addr[2];
 88	if (is_vlan) {
 89		sgid->raw[11] = vlan_id >> 8;
 90		sgid->raw[12] = vlan_id & 0xff;
 91	} else {
 92		sgid->raw[11] = 0xff;
 93		sgid->raw[12] = 0xfe;
 94	}
 95	sgid->raw[13] = mac_addr[3];
 96	sgid->raw[14] = mac_addr[4];
 97	sgid->raw[15] = mac_addr[5];
 98}
 99
100static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
101			    bool is_vlan, u16 vlan_id)
102{
103	int i;
104	union ib_gid new_sgid;
105	unsigned long flags;
106
107	memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid));
108
109	ocrdma_build_sgid_mac(&new_sgid, mac_addr, is_vlan, vlan_id);
110
111	spin_lock_irqsave(&dev->sgid_lock, flags);
112	for (i = 0; i < OCRDMA_MAX_SGID; i++) {
113		if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid,
114			    sizeof(union ib_gid))) {
115			/* found free entry */
116			memcpy(&dev->sgid_tbl[i], &new_sgid,
117			       sizeof(union ib_gid));
118			spin_unlock_irqrestore(&dev->sgid_lock, flags);
119			return true;
120		} else if (!memcmp(&dev->sgid_tbl[i], &new_sgid,
121				   sizeof(union ib_gid))) {
122			/* entry already present, no addition is required. */
123			spin_unlock_irqrestore(&dev->sgid_lock, flags);
124			return false;
125		}
126	}
127	spin_unlock_irqrestore(&dev->sgid_lock, flags);
128	return false;
129}
130
131static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
132			    bool is_vlan, u16 vlan_id)
133{
134	int found = false;
135	int i;
136	union ib_gid sgid;
137	unsigned long flags;
138
139	ocrdma_build_sgid_mac(&sgid, mac_addr, is_vlan, vlan_id);
140
141	spin_lock_irqsave(&dev->sgid_lock, flags);
142	/* first is default sgid, which cannot be deleted. */
143	for (i = 1; i < OCRDMA_MAX_SGID; i++) {
144		if (!memcmp(&dev->sgid_tbl[i], &sgid, sizeof(union ib_gid))) {
145			/* found matching entry */
146			memset(&dev->sgid_tbl[i], 0, sizeof(union ib_gid));
147			found = true;
148			break;
149		}
150	}
151	spin_unlock_irqrestore(&dev->sgid_lock, flags);
152	return found;
153}
154
155static void ocrdma_add_default_sgid(struct ocrdma_dev *dev)
156{
157	/* GID Index 0 - Invariant manufacturer-assigned EUI-64 */
158	union ib_gid *sgid = &dev->sgid_tbl[0];
159
160	sgid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
161	ocrdma_get_guid(dev, &sgid->raw[8]);
162}
163
164#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
165static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
166{
167	struct net_device *netdev, *tmp;
168	u16 vlan_id;
169	bool is_vlan;
170
171	netdev = dev->nic_info.netdev;
172
173	rcu_read_lock();
174	for_each_netdev_rcu(&init_net, tmp) {
175		if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) {
176			if (!netif_running(tmp) || !netif_oper_up(tmp))
177				continue;
178			if (netdev != tmp) {
179				vlan_id = vlan_dev_vlan_id(tmp);
180				is_vlan = true;
181			} else {
182				is_vlan = false;
183				vlan_id = 0;
184				tmp = netdev;
185			}
186			ocrdma_add_sgid(dev, tmp->dev_addr, is_vlan, vlan_id);
187		}
188	}
189	rcu_read_unlock();
190}
191#else
192static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
193{
194
195}
196#endif /* VLAN */
197
198static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
199{
200	ocrdma_add_default_sgid(dev);
201	ocrdma_add_vlan_sgids(dev);
202	return 0;
203}
204
205#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \
206defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
207
208static int ocrdma_inet6addr_event(struct notifier_block *notifier,
209				  unsigned long event, void *ptr)
210{
211	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
212	struct net_device *event_netdev = ifa->idev->dev;
213	struct net_device *netdev = NULL;
214	struct ib_event gid_event;
215	struct ocrdma_dev *dev;
216	bool found = false;
217	bool updated = false;
218	bool is_vlan = false;
219	u16 vid = 0;
220
221	netdev = vlan_dev_real_dev(event_netdev);
222	if (netdev != event_netdev) {
223		is_vlan = true;
224		vid = vlan_dev_vlan_id(event_netdev);
225	}
226	rcu_read_lock();
227	list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) {
228		if (dev->nic_info.netdev == netdev) {
229			found = true;
230			break;
231		}
232	}
233	rcu_read_unlock();
234
235	if (!found)
236		return NOTIFY_DONE;
237	if (!rdma_link_local_addr((struct in6_addr *)&ifa->addr))
238		return NOTIFY_DONE;
239
240	mutex_lock(&dev->dev_lock);
241	switch (event) {
242	case NETDEV_UP:
243		updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid);
244		break;
245	case NETDEV_DOWN:
246		updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid);
247		break;
248	default:
249		break;
250	}
251	if (updated) {
252		/* GID table updated, notify the consumers about it */
253		gid_event.device = &dev->ibdev;
254		gid_event.element.port_num = 1;
255		gid_event.event = IB_EVENT_GID_CHANGE;
256		ib_dispatch_event(&gid_event);
257	}
258	mutex_unlock(&dev->dev_lock);
259	return NOTIFY_OK;
260}
261
262static struct notifier_block ocrdma_inet6addr_notifier = {
263	.notifier_call = ocrdma_inet6addr_event
264};
265
266#endif /* IPV6 and VLAN */
267
268static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
269					      u8 port_num)
270{
271	return IB_LINK_LAYER_ETHERNET;
272}
273
274static int ocrdma_register_device(struct ocrdma_dev *dev)
275{
276	strlcpy(dev->ibdev.name, "ocrdma%d", IB_DEVICE_NAME_MAX);
277	ocrdma_get_guid(dev, (u8 *)&dev->ibdev.node_guid);
278	memcpy(dev->ibdev.node_desc, OCRDMA_NODE_DESC,
279	       sizeof(OCRDMA_NODE_DESC));
280	dev->ibdev.owner = THIS_MODULE;
281	dev->ibdev.uverbs_cmd_mask =
282	    OCRDMA_UVERBS(GET_CONTEXT) |
283	    OCRDMA_UVERBS(QUERY_DEVICE) |
284	    OCRDMA_UVERBS(QUERY_PORT) |
285	    OCRDMA_UVERBS(ALLOC_PD) |
286	    OCRDMA_UVERBS(DEALLOC_PD) |
287	    OCRDMA_UVERBS(REG_MR) |
288	    OCRDMA_UVERBS(DEREG_MR) |
289	    OCRDMA_UVERBS(CREATE_COMP_CHANNEL) |
290	    OCRDMA_UVERBS(CREATE_CQ) |
291	    OCRDMA_UVERBS(RESIZE_CQ) |
292	    OCRDMA_UVERBS(DESTROY_CQ) |
293	    OCRDMA_UVERBS(REQ_NOTIFY_CQ) |
294	    OCRDMA_UVERBS(CREATE_QP) |
295	    OCRDMA_UVERBS(MODIFY_QP) |
296	    OCRDMA_UVERBS(QUERY_QP) |
297	    OCRDMA_UVERBS(DESTROY_QP) |
298	    OCRDMA_UVERBS(POLL_CQ) |
299	    OCRDMA_UVERBS(POST_SEND) |
300	    OCRDMA_UVERBS(POST_RECV);
301
302	dev->ibdev.uverbs_cmd_mask |=
303	    OCRDMA_UVERBS(CREATE_AH) |
304	     OCRDMA_UVERBS(MODIFY_AH) |
305	     OCRDMA_UVERBS(QUERY_AH) |
306	     OCRDMA_UVERBS(DESTROY_AH);
307
308	dev->ibdev.node_type = RDMA_NODE_IB_CA;
309	dev->ibdev.phys_port_cnt = 1;
310	dev->ibdev.num_comp_vectors = 1;
311
312	/* mandatory verbs. */
313	dev->ibdev.query_device = ocrdma_query_device;
314	dev->ibdev.query_port = ocrdma_query_port;
315	dev->ibdev.modify_port = ocrdma_modify_port;
316	dev->ibdev.query_gid = ocrdma_query_gid;
317	dev->ibdev.get_link_layer = ocrdma_link_layer;
318	dev->ibdev.alloc_pd = ocrdma_alloc_pd;
319	dev->ibdev.dealloc_pd = ocrdma_dealloc_pd;
320
321	dev->ibdev.create_cq = ocrdma_create_cq;
322	dev->ibdev.destroy_cq = ocrdma_destroy_cq;
323	dev->ibdev.resize_cq = ocrdma_resize_cq;
324
325	dev->ibdev.create_qp = ocrdma_create_qp;
326	dev->ibdev.modify_qp = ocrdma_modify_qp;
327	dev->ibdev.query_qp = ocrdma_query_qp;
328	dev->ibdev.destroy_qp = ocrdma_destroy_qp;
329
330	dev->ibdev.query_pkey = ocrdma_query_pkey;
331	dev->ibdev.create_ah = ocrdma_create_ah;
332	dev->ibdev.destroy_ah = ocrdma_destroy_ah;
333	dev->ibdev.query_ah = ocrdma_query_ah;
334	dev->ibdev.modify_ah = ocrdma_modify_ah;
335
336	dev->ibdev.poll_cq = ocrdma_poll_cq;
337	dev->ibdev.post_send = ocrdma_post_send;
338	dev->ibdev.post_recv = ocrdma_post_recv;
339	dev->ibdev.req_notify_cq = ocrdma_arm_cq;
340
341	dev->ibdev.get_dma_mr = ocrdma_get_dma_mr;
342	dev->ibdev.dereg_mr = ocrdma_dereg_mr;
343	dev->ibdev.reg_user_mr = ocrdma_reg_user_mr;
344
345	/* mandatory to support user space verbs consumer. */
346	dev->ibdev.alloc_ucontext = ocrdma_alloc_ucontext;
347	dev->ibdev.dealloc_ucontext = ocrdma_dealloc_ucontext;
348	dev->ibdev.mmap = ocrdma_mmap;
349	dev->ibdev.dma_device = &dev->nic_info.pdev->dev;
350
351	dev->ibdev.process_mad = ocrdma_process_mad;
352
353	if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
354		dev->ibdev.uverbs_cmd_mask |=
355		     OCRDMA_UVERBS(CREATE_SRQ) |
356		     OCRDMA_UVERBS(MODIFY_SRQ) |
357		     OCRDMA_UVERBS(QUERY_SRQ) |
358		     OCRDMA_UVERBS(DESTROY_SRQ) |
359		     OCRDMA_UVERBS(POST_SRQ_RECV);
360
361		dev->ibdev.create_srq = ocrdma_create_srq;
362		dev->ibdev.modify_srq = ocrdma_modify_srq;
363		dev->ibdev.query_srq = ocrdma_query_srq;
364		dev->ibdev.destroy_srq = ocrdma_destroy_srq;
365		dev->ibdev.post_srq_recv = ocrdma_post_srq_recv;
366	}
367	return ib_register_device(&dev->ibdev, NULL);
368}
369
370static int ocrdma_alloc_resources(struct ocrdma_dev *dev)
371{
372	mutex_init(&dev->dev_lock);
373	dev->sgid_tbl = kzalloc(sizeof(union ib_gid) *
374				OCRDMA_MAX_SGID, GFP_KERNEL);
375	if (!dev->sgid_tbl)
376		goto alloc_err;
377	spin_lock_init(&dev->sgid_lock);
378
379	dev->cq_tbl = kzalloc(sizeof(struct ocrdma_cq *) *
380			      OCRDMA_MAX_CQ, GFP_KERNEL);
381	if (!dev->cq_tbl)
382		goto alloc_err;
383
384	if (dev->attr.max_qp) {
385		dev->qp_tbl = kzalloc(sizeof(struct ocrdma_qp *) *
386				      OCRDMA_MAX_QP, GFP_KERNEL);
387		if (!dev->qp_tbl)
388			goto alloc_err;
389	}
390	spin_lock_init(&dev->av_tbl.lock);
391	spin_lock_init(&dev->flush_q_lock);
392	return 0;
393alloc_err:
394	ocrdma_err("%s(%d) error.\n", __func__, dev->id);
395	return -ENOMEM;
396}
397
398static void ocrdma_free_resources(struct ocrdma_dev *dev)
399{
400	kfree(dev->qp_tbl);
401	kfree(dev->cq_tbl);
402	kfree(dev->sgid_tbl);
403}
404
405static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
406{
407	int status = 0;
408	struct ocrdma_dev *dev;
409
410	dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
411	if (!dev) {
412		ocrdma_err("Unable to allocate ib device\n");
413		return NULL;
414	}
415	dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL);
416	if (!dev->mbx_cmd)
417		goto idr_err;
418
419	memcpy(&dev->nic_info, dev_info, sizeof(*dev_info));
420	dev->id = ocrdma_get_instance();
421	if (dev->id < 0)
422		goto idr_err;
423
424	status = ocrdma_init_hw(dev);
425	if (status)
426		goto init_err;
427
428	status = ocrdma_alloc_resources(dev);
429	if (status)
430		goto alloc_err;
431
432	status = ocrdma_build_sgid_tbl(dev);
433	if (status)
434		goto alloc_err;
435
436	status = ocrdma_register_device(dev);
437	if (status)
438		goto alloc_err;
439
440	spin_lock(&ocrdma_devlist_lock);
441	list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
442	spin_unlock(&ocrdma_devlist_lock);
443	return dev;
444
445alloc_err:
446	ocrdma_free_resources(dev);
447	ocrdma_cleanup_hw(dev);
448init_err:
449	idr_remove(&ocrdma_dev_id, dev->id);
450idr_err:
451	kfree(dev->mbx_cmd);
452	ib_dealloc_device(&dev->ibdev);
453	ocrdma_err("%s() leaving. ret=%d\n", __func__, status);
454	return NULL;
455}
456
457static void ocrdma_remove_free(struct rcu_head *rcu)
458{
459	struct ocrdma_dev *dev = container_of(rcu, struct ocrdma_dev, rcu);
460
461	ocrdma_free_resources(dev);
462	ocrdma_cleanup_hw(dev);
463
464	idr_remove(&ocrdma_dev_id, dev->id);
465	kfree(dev->mbx_cmd);
466	ib_dealloc_device(&dev->ibdev);
467}
468
469static void ocrdma_remove(struct ocrdma_dev *dev)
470{
471	/* first unregister with stack to stop all the active traffic
472	 * of the registered clients.
473	 */
474	ib_unregister_device(&dev->ibdev);
475
476	spin_lock(&ocrdma_devlist_lock);
477	list_del_rcu(&dev->entry);
478	spin_unlock(&ocrdma_devlist_lock);
479	call_rcu(&dev->rcu, ocrdma_remove_free);
480}
481
482static int ocrdma_open(struct ocrdma_dev *dev)
483{
484	struct ib_event port_event;
485
486	port_event.event = IB_EVENT_PORT_ACTIVE;
487	port_event.element.port_num = 1;
488	port_event.device = &dev->ibdev;
489	ib_dispatch_event(&port_event);
490	return 0;
491}
492
493static int ocrdma_close(struct ocrdma_dev *dev)
494{
495	int i;
496	struct ocrdma_qp *qp, **cur_qp;
497	struct ib_event err_event;
498	struct ib_qp_attr attrs;
499	int attr_mask = IB_QP_STATE;
500
501	attrs.qp_state = IB_QPS_ERR;
502	mutex_lock(&dev->dev_lock);
503	if (dev->qp_tbl) {
504		cur_qp = dev->qp_tbl;
505		for (i = 0; i < OCRDMA_MAX_QP; i++) {
506			qp = cur_qp[i];
507			if (qp) {
508				/* change the QP state to ERROR */
509				_ocrdma_modify_qp(&qp->ibqp, &attrs, attr_mask);
510
511				err_event.event = IB_EVENT_QP_FATAL;
512				err_event.element.qp = &qp->ibqp;
513				err_event.device = &dev->ibdev;
514				ib_dispatch_event(&err_event);
515			}
516		}
517	}
518	mutex_unlock(&dev->dev_lock);
519
520	err_event.event = IB_EVENT_PORT_ERR;
521	err_event.element.port_num = 1;
522	err_event.device = &dev->ibdev;
523	ib_dispatch_event(&err_event);
524	return 0;
525}
526
527/* event handling via NIC driver ensures that all the NIC specific
528 * initialization done before RoCE driver notifies
529 * event to stack.
530 */
531static void ocrdma_event_handler(struct ocrdma_dev *dev, u32 event)
532{
533	switch (event) {
534	case BE_DEV_UP:
535		ocrdma_open(dev);
536		break;
537	case BE_DEV_DOWN:
538		ocrdma_close(dev);
539		break;
540	};
541}
542
543static struct ocrdma_driver ocrdma_drv = {
544	.name			= "ocrdma_driver",
545	.add			= ocrdma_add,
546	.remove			= ocrdma_remove,
547	.state_change_handler	= ocrdma_event_handler,
548};
549
550static void ocrdma_unregister_inet6addr_notifier(void)
551{
552#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
553	unregister_inet6addr_notifier(&ocrdma_inet6addr_notifier);
554#endif
555}
556
557static int __init ocrdma_init_module(void)
558{
559	int status;
560
561#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
562	status = register_inet6addr_notifier(&ocrdma_inet6addr_notifier);
563	if (status)
564		return status;
565#endif
566
567	status = be_roce_register_driver(&ocrdma_drv);
568	if (status)
569		ocrdma_unregister_inet6addr_notifier();
570
571	return status;
572}
573
574static void __exit ocrdma_exit_module(void)
575{
576	be_roce_unregister_driver(&ocrdma_drv);
577	ocrdma_unregister_inet6addr_notifier();
578}
579
580module_init(ocrdma_init_module);
581module_exit(ocrdma_exit_module);