⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c2_provider.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	c2mr = kmalloc(sizeof(*c2mr), GFP_KERNEL);	if (!c2mr)		return ERR_PTR(-ENOMEM);	c2mr->pd = c2pd;	c2mr->umem = ib_umem_get(pd->uobject->context, start, length, acc);	if (IS_ERR(c2mr->umem)) {		err = PTR_ERR(c2mr->umem);		kfree(c2mr);		return ERR_PTR(err);	}	shift = ffs(c2mr->umem->page_size) - 1;	n = 0;	list_for_each_entry(chunk, &c2mr->umem->chunk_list, list)		n += chunk->nents;	pages = kmalloc(n * sizeof(u64), GFP_KERNEL);	if (!pages) {		err = -ENOMEM;		goto err;	}	i = 0;	list_for_each_entry(chunk, &c2mr->umem->chunk_list, list) {		for (j = 0; j < chunk->nmap; ++j) {			len = sg_dma_len(&chunk->page_list[j]) >> shift;			for (k = 0; k < len; ++k) {				pages[i++] =					sg_dma_address(&chunk->page_list[j]) +					(c2mr->umem->page_size * k);			}		}	}	kva = virt;  	err = c2_nsmr_register_phys_kern(to_c2dev(pd->device),					 pages,					 c2mr->umem->page_size,					 i,					 length,					 c2mr->umem->offset,					 &kva,					 c2_convert_access(acc),					 c2mr);	kfree(pages);	if (err)		goto err;	return &c2mr->ibmr;err:	ib_umem_release(c2mr->umem);	kfree(c2mr);	return ERR_PTR(err);}static int c2_dereg_mr(struct ib_mr *ib_mr){	struct c2_mr *mr = to_c2mr(ib_mr);	int err;	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	err = c2_stag_dealloc(to_c2dev(ib_mr->device), ib_mr->lkey);	if (err)		pr_debug("c2_stag_dealloc failed: %d\n", err);	else {		if (mr->umem)			ib_umem_release(mr->umem);		kfree(mr);	}	return err;}static ssize_t show_rev(struct class_device *cdev, char *buf){	struct c2_dev *dev = container_of(cdev, struct c2_dev, ibdev.class_dev);	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return sprintf(buf, "%x\n", dev->props.hw_ver);}static ssize_t show_fw_ver(struct class_device *cdev, char *buf){	struct c2_dev *dev = container_of(cdev, struct c2_dev, ibdev.class_dev);	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return sprintf(buf, "%x.%x.%x\n",		       (int) (dev->props.fw_ver >> 32),		       (int) (dev->props.fw_ver >> 16) & 0xffff,		       (int) (dev->props.fw_ver & 0xffff));}static ssize_t show_hca(struct class_device *cdev, char *buf){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return sprintf(buf, "AMSO1100\n");}static ssize_t show_board(struct class_device *cdev, char *buf){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return sprintf(buf, "%.*s\n", 32, "AMSO1100 Board ID");}static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);static struct class_device_attribute *c2_class_attributes[] = {	&class_device_attr_hw_rev,	&class_device_attr_fw_ver,	&class_device_attr_hca_type,	&class_device_attr_board_id};static int c2_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,			int attr_mask, struct ib_udata *udata){	int err;	err =	    c2_qp_modify(to_c2dev(ibqp->device), to_c2qp(ibqp), attr,			 attr_mask);	return err;}static int c2_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return -ENOSYS;}static int c2_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return -ENOSYS;}static int c2_process_mad(struct ib_device *ibdev,			  int mad_flags,			  u8 port_num,			  struct ib_wc *in_wc,			  struct ib_grh *in_grh,			  struct ib_mad *in_mad, struct ib_mad *out_mad){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	return -ENOSYS;}static int c2_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	/* Request a connection */	return c2_llp_connect(cm_id, iw_param);}static int c2_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	/* Accept the new connection */	return c2_llp_accept(cm_id, iw_param);}static int c2_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len){	int err;	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	err = c2_llp_reject(cm_id, pdata, pdata_len);	return err;}static int c2_service_create(struct iw_cm_id *cm_id, int backlog){	int err;	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	err = c2_llp_service_create(cm_id, backlog);	pr_debug("%s:%u err=%d\n",		__FUNCTION__, __LINE__,		err);	return err;}static int c2_service_destroy(struct iw_cm_id *cm_id){	int err;	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	err = c2_llp_service_destroy(cm_id);	return err;}static int c2_pseudo_up(struct net_device *netdev){	struct in_device *ind;	struct c2_dev *c2dev = netdev->priv;	ind = in_dev_get(netdev);	if (!ind)		return 0;	pr_debug("adding...\n");	for_ifa(ind) {#ifdef DEBUG		u8 *ip = (u8 *) & ifa->ifa_address;		pr_debug("%s: %d.%d.%d.%d\n",		       ifa->ifa_label, ip[0], ip[1], ip[2], ip[3]);#endif		c2_add_addr(c2dev, ifa->ifa_address, ifa->ifa_mask);	}	endfor_ifa(ind);	in_dev_put(ind);	return 0;}static int c2_pseudo_down(struct net_device *netdev){	struct in_device *ind;	struct c2_dev *c2dev = netdev->priv;	ind = in_dev_get(netdev);	if (!ind)		return 0;	pr_debug("deleting...\n");	for_ifa(ind) {#ifdef DEBUG		u8 *ip = (u8 *) & ifa->ifa_address;		pr_debug("%s: %d.%d.%d.%d\n",		       ifa->ifa_label, ip[0], ip[1], ip[2], ip[3]);#endif		c2_del_addr(c2dev, ifa->ifa_address, ifa->ifa_mask);	}	endfor_ifa(ind);	in_dev_put(ind);	return 0;}static int c2_pseudo_xmit_frame(struct sk_buff *skb, struct net_device *netdev){	kfree_skb(skb);	return NETDEV_TX_OK;}static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu){	int ret = 0;	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)		return -EINVAL;	netdev->mtu = new_mtu;	/* TODO: Tell rnic about new rmda interface mtu */	return ret;}static void setup(struct net_device *netdev){	netdev->open = c2_pseudo_up;	netdev->stop = c2_pseudo_down;	netdev->hard_start_xmit = c2_pseudo_xmit_frame;	netdev->get_stats = NULL;	netdev->tx_timeout = NULL;	netdev->set_mac_address = NULL;	netdev->change_mtu = c2_pseudo_change_mtu;	netdev->watchdog_timeo = 0;	netdev->type = ARPHRD_ETHER;	netdev->mtu = 1500;	netdev->hard_header_len = ETH_HLEN;	netdev->addr_len = ETH_ALEN;	netdev->tx_queue_len = 0;	netdev->flags |= IFF_NOARP;	return;}static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev){	char name[IFNAMSIZ];	struct net_device *netdev;	/* change ethxxx to iwxxx */	strcpy(name, "iw");	strcat(name, &c2dev->netdev->name[3]);	netdev = alloc_netdev(sizeof(*netdev), name, setup);	if (!netdev) {		printk(KERN_ERR PFX "%s -  etherdev alloc failed",			__FUNCTION__);		return NULL;	}	netdev->priv = c2dev;	SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);	memcpy_fromio(netdev->dev_addr, c2dev->kva + C2_REGS_RDMA_ENADDR, 6);	/* Print out the MAC address */	pr_debug("%s: MAC %02X:%02X:%02X:%02X:%02X:%02X\n",		netdev->name,		netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],		netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);#if 0	/* Disable network packets */	netif_stop_queue(netdev);#endif	return netdev;}int c2_register_device(struct c2_dev *dev){	int ret = -ENOMEM;	int i;	/* Register pseudo network device */	dev->pseudo_netdev = c2_pseudo_netdev_init(dev);	if (!dev->pseudo_netdev)		goto out3;	ret = register_netdev(dev->pseudo_netdev);	if (ret)		goto out2;	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX);	dev->ibdev.owner = THIS_MODULE;	dev->ibdev.uverbs_cmd_mask =	    (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |	    (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |	    (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |	    (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |	    (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |	    (1ull << IB_USER_VERBS_CMD_REG_MR) |	    (1ull << IB_USER_VERBS_CMD_DEREG_MR) |	    (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |	    (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |	    (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |	    (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |	    (1ull << IB_USER_VERBS_CMD_CREATE_QP) |	    (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |	    (1ull << IB_USER_VERBS_CMD_POLL_CQ) |	    (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |	    (1ull << IB_USER_VERBS_CMD_POST_SEND) |	    (1ull << IB_USER_VERBS_CMD_POST_RECV);	dev->ibdev.node_type = RDMA_NODE_RNIC;	memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));	memcpy(&dev->ibdev.node_guid, dev->pseudo_netdev->dev_addr, 6);	dev->ibdev.phys_port_cnt = 1;	dev->ibdev.num_comp_vectors = 1;	dev->ibdev.dma_device = &dev->pcidev->dev;	dev->ibdev.query_device = c2_query_device;	dev->ibdev.query_port = c2_query_port;	dev->ibdev.modify_port = c2_modify_port;	dev->ibdev.query_pkey = c2_query_pkey;	dev->ibdev.query_gid = c2_query_gid;	dev->ibdev.alloc_ucontext = c2_alloc_ucontext;	dev->ibdev.dealloc_ucontext = c2_dealloc_ucontext;	dev->ibdev.mmap = c2_mmap_uar;	dev->ibdev.alloc_pd = c2_alloc_pd;	dev->ibdev.dealloc_pd = c2_dealloc_pd;	dev->ibdev.create_ah = c2_ah_create;	dev->ibdev.destroy_ah = c2_ah_destroy;	dev->ibdev.create_qp = c2_create_qp;	dev->ibdev.modify_qp = c2_modify_qp;	dev->ibdev.destroy_qp = c2_destroy_qp;	dev->ibdev.create_cq = c2_create_cq;	dev->ibdev.destroy_cq = c2_destroy_cq;	dev->ibdev.poll_cq = c2_poll_cq;	dev->ibdev.get_dma_mr = c2_get_dma_mr;	dev->ibdev.reg_phys_mr = c2_reg_phys_mr;	dev->ibdev.reg_user_mr = c2_reg_user_mr;	dev->ibdev.dereg_mr = c2_dereg_mr;	dev->ibdev.alloc_fmr = NULL;	dev->ibdev.unmap_fmr = NULL;	dev->ibdev.dealloc_fmr = NULL;	dev->ibdev.map_phys_fmr = NULL;	dev->ibdev.attach_mcast = c2_multicast_attach;	dev->ibdev.detach_mcast = c2_multicast_detach;	dev->ibdev.process_mad = c2_process_mad;	dev->ibdev.req_notify_cq = c2_arm_cq;	dev->ibdev.post_send = c2_post_send;	dev->ibdev.post_recv = c2_post_receive;	dev->ibdev.iwcm = kmalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL);	dev->ibdev.iwcm->add_ref = c2_add_ref;	dev->ibdev.iwcm->rem_ref = c2_rem_ref;	dev->ibdev.iwcm->get_qp = c2_get_qp;	dev->ibdev.iwcm->connect = c2_connect;	dev->ibdev.iwcm->accept = c2_accept;	dev->ibdev.iwcm->reject = c2_reject;	dev->ibdev.iwcm->create_listen = c2_service_create;	dev->ibdev.iwcm->destroy_listen = c2_service_destroy;	ret = ib_register_device(&dev->ibdev);	if (ret)		goto out1;	for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) {		ret = class_device_create_file(&dev->ibdev.class_dev,					       c2_class_attributes[i]);		if (ret)			goto out0;	}	goto out3;out0:	ib_unregister_device(&dev->ibdev);out1:	unregister_netdev(dev->pseudo_netdev);out2:	free_netdev(dev->pseudo_netdev);out3:	pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret);	return ret;}void c2_unregister_device(struct c2_dev *dev){	pr_debug("%s:%u\n", __FUNCTION__, __LINE__);	unregister_netdev(dev->pseudo_netdev);	free_netdev(dev->pseudo_netdev);	ib_unregister_device(&dev->ibdev);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -