📄 c2_provider.c
字号:
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 + -