/*******************************************************************
* This file is part of the Emulex RoCE Device Driver for *
* RoCE (RDMA over Converged Ethernet) adapters. *
* Copyright (C) 2008-2012 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of version 2 of the GNU General *
* Public License as published by the Free Software Foundation. *
* This program is distributed in the hope that it will be useful. *
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
* DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
* TO BE LEGALLY INVALID. See the GNU General Public License for *
* more details, a copy of which can be found in the file COPYING *
* included with this package. *
*
* Contact Information:
* linux-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*******************************************************************/
#include <linux/dma-mapping.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_user_verbs.h>
#include <rdma/iw_cm.h>
#include <rdma/ib_umem.h>
#include <rdma/ib_addr.h>
#include "ocrdma.h"
#include "ocrdma_hw.h"
#include "ocrdma_verbs.h"
#include "ocrdma_abi.h"
int ocrdma_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
{
if (index > 1)
return -EINVAL;
*pkey = 0xffff;
return 0;
}
int ocrdma_query_gid(struct ib_device *ibdev, u8 port,
int index, union ib_gid *sgid)
{
struct ocrdma_dev *dev;
dev = get_ocrdma_dev(ibdev);
memset(sgid, 0, sizeof(*sgid));
if (index > OCRDMA_MAX_SGID)
return -EINVAL;
memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid));
return 0;
}
int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
{
struct ocrdma_dev *dev = get_ocrdma_dev(ibdev);
memset(attr, 0, sizeof *attr);
memcpy(&attr->fw_ver, &dev->attr.fw_ver[0],
min(sizeof(dev->attr.fw_ver), sizeof(attr->fw_ver)));
ocrdma_get_guid(dev, (u8 *)&attr->sys_image_guid);
attr->max_mr_size = dev->attr.max_mr_size;
attr->page_size_cap = 0xffff000;
attr->vendor_id = dev->nic_info.pdev->vendor;
attr->vendor_part_id = dev->nic_info.pdev->device;
attr->hw_ver = dev->asic_id;
attr->max_qp = dev->attr.max_qp;
attr->max_ah = OCRDMA_MAX_AH;
attr->max_qp_wr = dev->attr.max_wqe;
attr->device_cap_flags = IB_DEVICE_CURR_QP_STATE_MOD |
IB_DEVICE_RC_RNR_NAK_GEN |
IB_DEVICE_SHUTDOWN_PORT |
IB_DEVICE_SYS_IMAGE_GUID |
IB_DEVICE_LOCAL_DMA_LKEY |
IB_DEVICE_MEM_MGT_EXTENSIONS;
attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge);
attr->max_sge_rd = 0;
attr->max_cq = dev->attr.max_cq;
attr->max_cqe = dev->attr.max_cqe;
attr->max_mr = dev->attr.max_mr;
attr->max_mw = dev->attr.max_mw;
attr->max_pd = dev->attr.max_pd;
attr->atomic_cap = 0;
attr->max_fmr = 0;
attr->max_map_per_fmr = 0;
attr->max_qp_rd_atom =
min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp);
attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp;
attr->max_srq = dev->attr.max_srq;
attr->max_srq_sge = dev->attr.max_srq_sge;
attr->max_srq_wr = dev->attr.max_rqe;
attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay;
attr->max_fast_reg_page_list_len = dev->attr.max_pages_per_frmr;
attr->max_pkeys = 1;
return 0;
}
static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
u8 *ib_speed, u8 *ib_width)
{
int status;
u8 speed;
status = ocrdma_mbx_get_link_speed(dev, &speed);
if (status)
speed = OCRDMA_PHYS_LINK_SPEED_ZERO;
switch (speed) {
case OCRDMA_PHYS_LINK_SPEED_1GBPS:
*ib_speed = IB_SPEED_SDR;
*ib_width = IB_WIDTH_1X;
break;
case OCRDMA_PHYS_LINK_SPEED_10GBPS:
*ib_speed = IB_SPEED_QDR;
*ib_width = IB_WIDTH_1X;
break;
case OCRDMA_PHYS_LINK_SPEED_20GBPS:
*ib_speed = IB_SPEED_DDR;
*ib_width = IB_WIDTH_4X;
break;
case OCRDMA_PHYS_LINK_SPEED_40GBPS:
*ib_speed = IB_SPEED_QDR;
*ib_width = IB_WIDTH_4X;
break;
default:
/* Unsupported */
*ib_speed = IB_SPEED_SDR;
*ib_width = IB_WIDTH_1X;
}
}
int ocrdma_query_port(struct ib_device *ibdev,
u8 port, struct ib_port_attr *props)
{
enum ib_port_state port_state;
struct ocrdma_dev *dev;
struct net_device *netdev;
dev = get_ocrdma_dev(ibdev);
if (port > 1) {
pr_err("%s(%d) invalid_port=0x%x\n", __func__,
dev->id, port);
return -EINVAL;
}
netdev = dev->nic_info.netdev;
if (netif_running(netdev) && netif_oper_up(netdev)) {
port_state = IB_PORT_ACTIVE;
props->phys_state = 5;
} else {
port_state = IB_PORT_DOWN;
props->phys_state = 3;
}
props->max_mtu = IB_MTU_4096;
props->active_mtu = iboe_get_mtu(netdev->mtu);
props->lid = 0;
props->lmc = 0;
props->sm_lid = 0;
props->sm_sl = 0;
props->state = port_state;
props->port_cap_flags =
IB_PORT_CM_SUP |
IB_PORT_REINIT_SUP |
IB_PORT_DEVICE_MGMT_SUP | IB_PORT_VENDOR_CLASS_SUP | IB_PORT_IP_BASED_GIDS;
props->gid_tbl_len = OCRDMA_MAX_SGID;
props->pkey_tbl_len = 1;
props->bad_pkey_cntr = 0;
props->qkey_viol_cntr = 0;
get_link_speed_and_width(dev, &props->active_speed,
&props->active_width);
props->max_msg_sz = 0x80000000;
props->max_vl_num = 4;
return 0;
}
int ocrdma_modify_port(struct ib_device *ibdev, u8 port, int mask,
struct ib_port_modify *props)
{
struct ocrdma_dev *dev;
dev = get_ocrdma_dev(ibdev);
if (port > 1) {
pr_err("%s(%d) invalid_port=0x%x\n", __func__, dev->id, port);
return -EINVAL;
}
return 0;
}
static int ocrdma_add_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr,
unsigned long len)
{
struct ocrdma_mm *mm;
mm = kzalloc(sizeof(*mm), GFP_KERNEL);
if (mm == NULL)
return -ENOMEM;
mm->key.phy_addr = phy_addr;
mm->key.len = len;
INIT_LIST_HEAD(&mm->entry);
mutex_lock(&uctx->mm_list_lock);
list_add_tail(&mm->entry, &uctx->mm_head);
mutex_unlock(&uctx->mm_list_lock);
return 0;
}
static void ocrdma_del_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr,
unsigned long len)
{
struct ocrdma_mm *mm, *tmp;
mutex_lock(&uctx->mm_list_lock);
list_for_each_entry_safe(mm, tmp, &uctx->mm_head, entry) {
if (len != mm->key.len && phy_addr != mm->key.phy_addr)
continue;
list_del(&mm->entry);
kfree(mm);
break;
}
mutex_unlock(&uctx->mm_list_lock);
}
static bool ocrdma_search_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr,
unsigned long len)
{
bool found = false;
struct ocrdma_mm *mm;
mutex_lock(&uctx->mm_list_lock);
list_for_each_entry(mm, &uctx->mm_head, entry) {
if (len != mm->key.len && phy_addr != mm->key.phy_addr)
continue;
found = true;
break;
}
mutex_unlock(&uctx->mm_list_lock);
return found;
}
static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
struct ocrdma_ucontext *uctx,
struct ib_udata *udata)
{
struct ocrdma_pd *pd = NULL;
int status = 0;
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
if (!pd)
return ERR_PTR(-ENOMEM);
if (udata && uctx) {
pd->dpp_enabled =
ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R;
pd->num_dpp_qp =
pd->dpp_enabled ? (dev->nic_info.db_page_size /
dev->attr.wqe_size) : 0;
}
retry:
status = ocrdma_mbx_alloc_pd(dev, pd);
if (status) {
if (pd->dpp_enabled) {
pd->dpp_enabled = false;
pd->num_dpp_qp = 0;
goto retry;
} else {
kfree(pd);
return ERR_PTR(status);
}
}
return pd;
}
static inline int is_ucontext_pd(struct ocrdma_ucontext *uctx,
struct ocrdma_pd *pd)
{
return (uctx->cntxt_pd == pd ? true : false);
}
static int _ocrdma_dealloc_pd(struct ocrdma_dev *dev,
struct ocrdma_pd
weixin_42653672
- 粉丝: 105
- 资源: 1万+
最新资源
- 智能车-车载工控机外部通信协议详解
- C#VS2012通用权限管理系统源码数据库 SQL2012源码类型 WebForm
- 基于多头选择和词-词关系分类的NER统一框架+python项目源码+文档说明
- 基于UNER-W2NER 的命名实体识别+python项目源码+文档说明
- 镜像资源包php7.4.33
- 基于LLM的命名实体识别(NER)和实体关系抽取(IE)
- 基于python和llm大模型开发的数据处理和任务调度系统
- JAVASpring mvc在线问卷答题系统源码数据库 MySQL源码类型 WebForm
- 作业1-视频1111111111111
- python-基于LLM multi agents的《谁是卧底》游戏模拟+项目源码+文档说明
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈