Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
fb1b5034
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
fb1b5034
编写于
1月 22, 2014
作者:
R
Roland Dreier
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'ip-roce' into for-next
Conflicts: drivers/infiniband/hw/mlx4/main.c
上级
8f399921
27cdef63
变更
36
隐藏空白更改
内联
并排
Showing
36 changed file
with
939 addition
and
389 deletion
+939
-389
drivers/infiniband/Kconfig
drivers/infiniband/Kconfig
+3
-2
drivers/infiniband/core/Makefile
drivers/infiniband/core/Makefile
+3
-2
drivers/infiniband/core/addr.c
drivers/infiniband/core/addr.c
+94
-3
drivers/infiniband/core/cm.c
drivers/infiniband/core/cm.c
+52
-0
drivers/infiniband/core/cma.c
drivers/infiniband/core/cma.c
+61
-13
drivers/infiniband/core/core_priv.h
drivers/infiniband/core/core_priv.h
+2
-0
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/sa_query.c
+11
-1
drivers/infiniband/core/ucma.c
drivers/infiniband/core/ucma.c
+4
-14
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_cmd.c
+4
-0
drivers/infiniband/core/verbs.c
drivers/infiniband/core/verbs.c
+96
-2
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/ehca_qp.c
+1
-1
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_qp.c
+1
-1
drivers/infiniband/hw/mlx4/Kconfig
drivers/infiniband/hw/mlx4/Kconfig
+1
-1
drivers/infiniband/hw/mlx4/ah.c
drivers/infiniband/hw/mlx4/ah.c
+9
-31
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/cq.c
+9
-0
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/main.c
+332
-143
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/mlx4_ib.h
+3
-3
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/qp.c
+83
-21
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/mlx5/qp.c
+2
-1
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_qp.c
+2
-1
drivers/infiniband/hw/ocrdma/Kconfig
drivers/infiniband/hw/ocrdma/Kconfig
+1
-1
drivers/infiniband/hw/ocrdma/ocrdma.h
drivers/infiniband/hw/ocrdma/ocrdma.h
+12
-0
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+3
-2
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+2
-19
drivers/infiniband/hw/ocrdma/ocrdma_hw.h
drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+0
-1
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/ocrdma/ocrdma_main.c
+40
-98
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+2
-1
drivers/infiniband/hw/qib/qib_qp.c
drivers/infiniband/hw/qib/qib_qp.c
+1
-1
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/port.c
+20
-0
include/linux/mlx4/cq.h
include/linux/mlx4/cq.h
+11
-4
include/linux/mlx4/device.h
include/linux/mlx4/device.h
+1
-0
include/rdma/ib_addr.h
include/rdma/ib_addr.h
+49
-20
include/rdma/ib_cm.h
include/rdma/ib_cm.h
+1
-0
include/rdma/ib_pack.h
include/rdma/ib_pack.h
+1
-0
include/rdma/ib_sa.h
include/rdma/ib_sa.h
+3
-0
include/rdma/ib_verbs.h
include/rdma/ib_verbs.h
+19
-2
未找到文件。
drivers/infiniband/Kconfig
浏览文件 @
fb1b5034
...
...
@@ -3,6 +3,8 @@ menuconfig INFINIBAND
depends on PCI || BROKEN
depends on HAS_IOMEM
depends on NET
depends on INET
depends on m || IPV6 != m
---help---
Core support for InfiniBand (IB). Make sure to also select
any protocols you wish to use as well as drivers for your
...
...
@@ -38,8 +40,7 @@ config INFINIBAND_USER_MEM
config INFINIBAND_ADDR_TRANS
bool
depends on INET
depends on !(INFINIBAND = y && IPV6 = m)
depends on INFINIBAND
default y
source "drivers/infiniband/hw/mthca/Kconfig"
...
...
drivers/infiniband/core/Makefile
浏览文件 @
fb1b5034
infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS)
:=
ib_addr.o
rdma_cm.o
infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS)
:=
rdma_cm.o
user_access-$(CONFIG_INFINIBAND_ADDR_TRANS)
:=
rdma_ucm.o
obj-$(CONFIG_INFINIBAND)
+=
ib_core.o ib_mad.o ib_sa.o
\
ib_cm.o iw_cm.o
$
(
infiniband-y
)
ib_cm.o iw_cm.o ib_addr.o
\
$
(
infiniband-y
)
obj-$(CONFIG_INFINIBAND_USER_MAD)
+=
ib_umad.o
obj-$(CONFIG_INFINIBAND_USER_ACCESS)
+=
ib_uverbs.o ib_ucm.o
\
$
(
user_access-y
)
...
...
drivers/infiniband/core/addr.c
浏览文件 @
fb1b5034
...
...
@@ -86,6 +86,8 @@ int rdma_addr_size(struct sockaddr *addr)
}
EXPORT_SYMBOL
(
rdma_addr_size
);
static
struct
rdma_addr_client
self
;
void
rdma_addr_register_client
(
struct
rdma_addr_client
*
client
)
{
atomic_set
(
&
client
->
refcount
,
1
);
...
...
@@ -119,7 +121,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
}
EXPORT_SYMBOL
(
rdma_copy_addr
);
int
rdma_translate_ip
(
struct
sockaddr
*
addr
,
struct
rdma_dev_addr
*
dev_addr
)
int
rdma_translate_ip
(
struct
sockaddr
*
addr
,
struct
rdma_dev_addr
*
dev_addr
,
u16
*
vlan_id
)
{
struct
net_device
*
dev
;
int
ret
=
-
EADDRNOTAVAIL
;
...
...
@@ -142,6 +145,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
return
ret
;
ret
=
rdma_copy_addr
(
dev_addr
,
dev
,
NULL
);
if
(
vlan_id
)
*
vlan_id
=
rdma_vlan_dev_vlan_id
(
dev
);
dev_put
(
dev
);
break
;
...
...
@@ -153,6 +158,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
&
((
struct
sockaddr_in6
*
)
addr
)
->
sin6_addr
,
dev
,
1
))
{
ret
=
rdma_copy_addr
(
dev_addr
,
dev
,
NULL
);
if
(
vlan_id
)
*
vlan_id
=
rdma_vlan_dev_vlan_id
(
dev
);
break
;
}
}
...
...
@@ -238,7 +245,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
src_in
->
sin_addr
.
s_addr
=
fl4
.
saddr
;
if
(
rt
->
dst
.
dev
->
flags
&
IFF_LOOPBACK
)
{
ret
=
rdma_translate_ip
((
struct
sockaddr
*
)
dst_in
,
addr
);
ret
=
rdma_translate_ip
((
struct
sockaddr
*
)
dst_in
,
addr
,
NULL
);
if
(
!
ret
)
memcpy
(
addr
->
dst_dev_addr
,
addr
->
src_dev_addr
,
MAX_ADDR_LEN
);
goto
put
;
...
...
@@ -286,7 +293,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
}
if
(
dst
->
dev
->
flags
&
IFF_LOOPBACK
)
{
ret
=
rdma_translate_ip
((
struct
sockaddr
*
)
dst_in
,
addr
);
ret
=
rdma_translate_ip
((
struct
sockaddr
*
)
dst_in
,
addr
,
NULL
);
if
(
!
ret
)
memcpy
(
addr
->
dst_dev_addr
,
addr
->
src_dev_addr
,
MAX_ADDR_LEN
);
goto
put
;
...
...
@@ -437,6 +444,88 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr)
}
EXPORT_SYMBOL
(
rdma_addr_cancel
);
struct
resolve_cb_context
{
struct
rdma_dev_addr
*
addr
;
struct
completion
comp
;
};
static
void
resolve_cb
(
int
status
,
struct
sockaddr
*
src_addr
,
struct
rdma_dev_addr
*
addr
,
void
*
context
)
{
memcpy
(((
struct
resolve_cb_context
*
)
context
)
->
addr
,
addr
,
sizeof
(
struct
rdma_dev_addr
));
complete
(
&
((
struct
resolve_cb_context
*
)
context
)
->
comp
);
}
int
rdma_addr_find_dmac_by_grh
(
union
ib_gid
*
sgid
,
union
ib_gid
*
dgid
,
u8
*
dmac
,
u16
*
vlan_id
)
{
int
ret
=
0
;
struct
rdma_dev_addr
dev_addr
;
struct
resolve_cb_context
ctx
;
struct
net_device
*
dev
;
union
{
struct
sockaddr
_sockaddr
;
struct
sockaddr_in
_sockaddr_in
;
struct
sockaddr_in6
_sockaddr_in6
;
}
sgid_addr
,
dgid_addr
;
ret
=
rdma_gid2ip
(
&
sgid_addr
.
_sockaddr
,
sgid
);
if
(
ret
)
return
ret
;
ret
=
rdma_gid2ip
(
&
dgid_addr
.
_sockaddr
,
dgid
);
if
(
ret
)
return
ret
;
memset
(
&
dev_addr
,
0
,
sizeof
(
dev_addr
));
ctx
.
addr
=
&
dev_addr
;
init_completion
(
&
ctx
.
comp
);
ret
=
rdma_resolve_ip
(
&
self
,
&
sgid_addr
.
_sockaddr
,
&
dgid_addr
.
_sockaddr
,
&
dev_addr
,
1000
,
resolve_cb
,
&
ctx
);
if
(
ret
)
return
ret
;
wait_for_completion
(
&
ctx
.
comp
);
memcpy
(
dmac
,
dev_addr
.
dst_dev_addr
,
ETH_ALEN
);
dev
=
dev_get_by_index
(
&
init_net
,
dev_addr
.
bound_dev_if
);
if
(
!
dev
)
return
-
ENODEV
;
if
(
vlan_id
)
*
vlan_id
=
rdma_vlan_dev_vlan_id
(
dev
);
dev_put
(
dev
);
return
ret
;
}
EXPORT_SYMBOL
(
rdma_addr_find_dmac_by_grh
);
int
rdma_addr_find_smac_by_sgid
(
union
ib_gid
*
sgid
,
u8
*
smac
,
u16
*
vlan_id
)
{
int
ret
=
0
;
struct
rdma_dev_addr
dev_addr
;
union
{
struct
sockaddr
_sockaddr
;
struct
sockaddr_in
_sockaddr_in
;
struct
sockaddr_in6
_sockaddr_in6
;
}
gid_addr
;
ret
=
rdma_gid2ip
(
&
gid_addr
.
_sockaddr
,
sgid
);
if
(
ret
)
return
ret
;
memset
(
&
dev_addr
,
0
,
sizeof
(
dev_addr
));
ret
=
rdma_translate_ip
(
&
gid_addr
.
_sockaddr
,
&
dev_addr
,
vlan_id
);
if
(
ret
)
return
ret
;
memcpy
(
smac
,
dev_addr
.
src_dev_addr
,
ETH_ALEN
);
return
ret
;
}
EXPORT_SYMBOL
(
rdma_addr_find_smac_by_sgid
);
static
int
netevent_callback
(
struct
notifier_block
*
self
,
unsigned
long
event
,
void
*
ctx
)
{
...
...
@@ -461,11 +550,13 @@ static int __init addr_init(void)
return
-
ENOMEM
;
register_netevent_notifier
(
&
nb
);
rdma_addr_register_client
(
&
self
);
return
0
;
}
static
void
__exit
addr_cleanup
(
void
)
{
rdma_addr_unregister_client
(
&
self
);
unregister_netevent_notifier
(
&
nb
);
destroy_workqueue
(
addr_wq
);
}
...
...
drivers/infiniband/core/cm.c
浏览文件 @
fb1b5034
...
...
@@ -47,6 +47,7 @@
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
#include <linux/etherdevice.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_cm.h>
...
...
@@ -177,6 +178,8 @@ struct cm_av {
struct
ib_ah_attr
ah_attr
;
u16
pkey_index
;
u8
timeout
;
u8
valid
;
u8
smac
[
ETH_ALEN
];
};
struct
cm_work
{
...
...
@@ -346,6 +349,23 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
grh
,
&
av
->
ah_attr
);
}
int
ib_update_cm_av
(
struct
ib_cm_id
*
id
,
const
u8
*
smac
,
const
u8
*
alt_smac
)
{
struct
cm_id_private
*
cm_id_priv
;
cm_id_priv
=
container_of
(
id
,
struct
cm_id_private
,
id
);
if
(
smac
!=
NULL
)
memcpy
(
cm_id_priv
->
av
.
smac
,
smac
,
sizeof
(
cm_id_priv
->
av
.
smac
));
if
(
alt_smac
!=
NULL
)
memcpy
(
cm_id_priv
->
alt_av
.
smac
,
alt_smac
,
sizeof
(
cm_id_priv
->
alt_av
.
smac
));
return
0
;
}
EXPORT_SYMBOL
(
ib_update_cm_av
);
static
int
cm_init_av_by_path
(
struct
ib_sa_path_rec
*
path
,
struct
cm_av
*
av
)
{
struct
cm_device
*
cm_dev
;
...
...
@@ -376,6 +396,9 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
ib_init_ah_from_path
(
cm_dev
->
ib_device
,
port
->
port_num
,
path
,
&
av
->
ah_attr
);
av
->
timeout
=
path
->
packet_life_time
+
1
;
memcpy
(
av
->
smac
,
path
->
smac
,
sizeof
(
av
->
smac
));
av
->
valid
=
1
;
return
0
;
}
...
...
@@ -1554,6 +1577,9 @@ static int cm_req_handler(struct cm_work *work)
cm_process_routed_req
(
req_msg
,
work
->
mad_recv_wc
->
wc
);
cm_format_paths_from_req
(
req_msg
,
&
work
->
path
[
0
],
&
work
->
path
[
1
]);
memcpy
(
work
->
path
[
0
].
dmac
,
cm_id_priv
->
av
.
ah_attr
.
dmac
,
ETH_ALEN
);
work
->
path
[
0
].
vlan_id
=
cm_id_priv
->
av
.
ah_attr
.
vlan_id
;
ret
=
cm_init_av_by_path
(
&
work
->
path
[
0
],
&
cm_id_priv
->
av
);
if
(
ret
)
{
ib_get_cached_gid
(
work
->
port
->
cm_dev
->
ib_device
,
...
...
@@ -3500,6 +3526,32 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
*
qp_attr_mask
=
IB_QP_STATE
|
IB_QP_AV
|
IB_QP_PATH_MTU
|
IB_QP_DEST_QPN
|
IB_QP_RQ_PSN
;
qp_attr
->
ah_attr
=
cm_id_priv
->
av
.
ah_attr
;
if
(
!
cm_id_priv
->
av
.
valid
)
{
spin_unlock_irqrestore
(
&
cm_id_priv
->
lock
,
flags
);
return
-
EINVAL
;
}
if
(
cm_id_priv
->
av
.
ah_attr
.
vlan_id
!=
0xffff
)
{
qp_attr
->
vlan_id
=
cm_id_priv
->
av
.
ah_attr
.
vlan_id
;
*
qp_attr_mask
|=
IB_QP_VID
;
}
if
(
!
is_zero_ether_addr
(
cm_id_priv
->
av
.
smac
))
{
memcpy
(
qp_attr
->
smac
,
cm_id_priv
->
av
.
smac
,
sizeof
(
qp_attr
->
smac
));
*
qp_attr_mask
|=
IB_QP_SMAC
;
}
if
(
cm_id_priv
->
alt_av
.
valid
)
{
if
(
cm_id_priv
->
alt_av
.
ah_attr
.
vlan_id
!=
0xffff
)
{
qp_attr
->
alt_vlan_id
=
cm_id_priv
->
alt_av
.
ah_attr
.
vlan_id
;
*
qp_attr_mask
|=
IB_QP_ALT_VID
;
}
if
(
!
is_zero_ether_addr
(
cm_id_priv
->
alt_av
.
smac
))
{
memcpy
(
qp_attr
->
alt_smac
,
cm_id_priv
->
alt_av
.
smac
,
sizeof
(
qp_attr
->
alt_smac
));
*
qp_attr_mask
|=
IB_QP_ALT_SMAC
;
}
}
qp_attr
->
path_mtu
=
cm_id_priv
->
path_mtu
;
qp_attr
->
dest_qp_num
=
be32_to_cpu
(
cm_id_priv
->
remote_qpn
);
qp_attr
->
rq_psn
=
be32_to_cpu
(
cm_id_priv
->
rq_psn
);
...
...
drivers/infiniband/core/cma.c
浏览文件 @
fb1b5034
...
...
@@ -340,7 +340,7 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a
int
ret
;
if
(
addr
->
sa_family
!=
AF_IB
)
{
ret
=
rdma_translate_ip
(
addr
,
dev_addr
);
ret
=
rdma_translate_ip
(
addr
,
dev_addr
,
NULL
);
}
else
{
cma_translate_ib
((
struct
sockaddr_ib
*
)
addr
,
dev_addr
);
ret
=
0
;
...
...
@@ -365,7 +365,9 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
return
-
EINVAL
;
mutex_lock
(
&
lock
);
iboe_addr_get_sgid
(
dev_addr
,
&
iboe_gid
);
rdma_ip2gid
((
struct
sockaddr
*
)
&
id_priv
->
id
.
route
.
addr
.
src_addr
,
&
iboe_gid
);
memcpy
(
&
gid
,
dev_addr
->
src_dev_addr
+
rdma_addr_gid_offset
(
dev_addr
),
sizeof
gid
);
if
(
listen_id_priv
&&
...
...
@@ -603,6 +605,7 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv,
{
struct
ib_qp_attr
qp_attr
;
int
qp_attr_mask
,
ret
;
union
ib_gid
sgid
;
mutex_lock
(
&
id_priv
->
qp_mutex
);
if
(
!
id_priv
->
id
.
qp
)
{
...
...
@@ -625,6 +628,20 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv,
if
(
ret
)
goto
out
;
ret
=
ib_query_gid
(
id_priv
->
id
.
device
,
id_priv
->
id
.
port_num
,
qp_attr
.
ah_attr
.
grh
.
sgid_index
,
&
sgid
);
if
(
ret
)
goto
out
;
if
(
rdma_node_get_transport
(
id_priv
->
cma_dev
->
device
->
node_type
)
==
RDMA_TRANSPORT_IB
&&
rdma_port_get_link_layer
(
id_priv
->
id
.
device
,
id_priv
->
id
.
port_num
)
==
IB_LINK_LAYER_ETHERNET
)
{
ret
=
rdma_addr_find_smac_by_sgid
(
&
sgid
,
qp_attr
.
smac
,
NULL
);
if
(
ret
)
goto
out
;
}
if
(
conn_param
)
qp_attr
.
max_dest_rd_atomic
=
conn_param
->
responder_resources
;
ret
=
ib_modify_qp
(
id_priv
->
id
.
qp
,
&
qp_attr
,
qp_attr_mask
);
...
...
@@ -725,6 +742,7 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
else
ret
=
ib_cm_init_qp_attr
(
id_priv
->
cm_id
.
ib
,
qp_attr
,
qp_attr_mask
);
if
(
qp_attr
->
qp_state
==
IB_QPS_RTR
)
qp_attr
->
rq_psn
=
id_priv
->
seq_num
;
break
;
...
...
@@ -1266,6 +1284,15 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
struct
rdma_id_private
*
listen_id
,
*
conn_id
;
struct
rdma_cm_event
event
;
int
offset
,
ret
;
u8
smac
[
ETH_ALEN
];
u8
alt_smac
[
ETH_ALEN
];
u8
*
psmac
=
smac
;
u8
*
palt_smac
=
alt_smac
;
int
is_iboe
=
((
rdma_node_get_transport
(
cm_id
->
device
->
node_type
)
==
RDMA_TRANSPORT_IB
)
&&
(
rdma_port_get_link_layer
(
cm_id
->
device
,
ib_event
->
param
.
req_rcvd
.
port
)
==
IB_LINK_LAYER_ETHERNET
));
listen_id
=
cm_id
->
context
;
if
(
!
cma_check_req_qp_type
(
&
listen_id
->
id
,
ib_event
))
...
...
@@ -1310,12 +1337,29 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
if
(
ret
)
goto
err3
;
if
(
is_iboe
)
{
if
(
ib_event
->
param
.
req_rcvd
.
primary_path
!=
NULL
)
rdma_addr_find_smac_by_sgid
(
&
ib_event
->
param
.
req_rcvd
.
primary_path
->
sgid
,
psmac
,
NULL
);
else
psmac
=
NULL
;
if
(
ib_event
->
param
.
req_rcvd
.
alternate_path
!=
NULL
)
rdma_addr_find_smac_by_sgid
(
&
ib_event
->
param
.
req_rcvd
.
alternate_path
->
sgid
,
palt_smac
,
NULL
);
else
palt_smac
=
NULL
;
}
/*
* Acquire mutex to prevent user executing rdma_destroy_id()
* while we're accessing the cm_id.
*/
mutex_lock
(
&
lock
);
if
(
cma_comp
(
conn_id
,
RDMA_CM_CONNECT
)
&&
(
conn_id
->
id
.
qp_type
!=
IB_QPT_UD
))
if
(
is_iboe
)
ib_update_cm_av
(
cm_id
,
psmac
,
palt_smac
);
if
(
cma_comp
(
conn_id
,
RDMA_CM_CONNECT
)
&&
(
conn_id
->
id
.
qp_type
!=
IB_QPT_UD
))
ib_send_cm_mra
(
cm_id
,
CMA_CM_MRA_SETTING
,
NULL
,
0
);
mutex_unlock
(
&
lock
);
mutex_unlock
(
&
conn_id
->
handler_mutex
);
...
...
@@ -1474,7 +1518,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
mutex_lock_nested
(
&
conn_id
->
handler_mutex
,
SINGLE_DEPTH_NESTING
);
conn_id
->
state
=
RDMA_CM_CONNECT
;
ret
=
rdma_translate_ip
(
laddr
,
&
conn_id
->
id
.
route
.
addr
.
dev_addr
);
ret
=
rdma_translate_ip
(
laddr
,
&
conn_id
->
id
.
route
.
addr
.
dev_addr
,
NULL
);
if
(
ret
)
{
mutex_unlock
(
&
conn_id
->
handler_mutex
);
rdma_destroy_id
(
new_cm_id
);
...
...
@@ -1873,7 +1917,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
struct
cma_work
*
work
;
int
ret
;
struct
net_device
*
ndev
=
NULL
;
u16
vid
;
work
=
kzalloc
(
sizeof
*
work
,
GFP_KERNEL
);
if
(
!
work
)
...
...
@@ -1897,10 +1941,14 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
goto
err2
;
}
vid
=
rdma_vlan_dev_vlan_id
(
ndev
);
route
->
path_rec
->
vlan_id
=
rdma_vlan_dev_vlan_id
(
ndev
);
memcpy
(
route
->
path_rec
->
dmac
,
addr
->
dev_addr
.
dst_dev_addr
,
ETH_ALEN
);
memcpy
(
route
->
path_rec
->
smac
,
ndev
->
dev_addr
,
ndev
->
addr_len
);
iboe_mac_vlan_to_ll
(
&
route
->
path_rec
->
sgid
,
addr
->
dev_addr
.
src_dev_addr
,
vid
);
iboe_mac_vlan_to_ll
(
&
route
->
path_rec
->
dgid
,
addr
->
dev_addr
.
dst_dev_addr
,
vid
);
rdma_ip2gid
((
struct
sockaddr
*
)
&
id_priv
->
id
.
route
.
addr
.
src_addr
,
&
route
->
path_rec
->
sgid
);
rdma_ip2gid
((
struct
sockaddr
*
)
&
id_priv
->
id
.
route
.
addr
.
dst_addr
,
&
route
->
path_rec
->
dgid
);
route
->
path_rec
->
hop_limit
=
1
;
route
->
path_rec
->
reversible
=
1
;
...
...
@@ -2063,6 +2111,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
RDMA_CM_ADDR_RESOLVED
))
goto
out
;
memcpy
(
cma_src_addr
(
id_priv
),
src_addr
,
rdma_addr_size
(
src_addr
));
if
(
!
status
&&
!
id_priv
->
cma_dev
)
status
=
cma_acquire_dev
(
id_priv
,
NULL
);
...
...
@@ -2072,10 +2121,8 @@ static void addr_handler(int status, struct sockaddr *src_addr,
goto
out
;
event
.
event
=
RDMA_CM_EVENT_ADDR_ERROR
;
event
.
status
=
status
;
}
else
{
memcpy
(
cma_src_addr
(
id_priv
),
src_addr
,
rdma_addr_size
(
src_addr
));
}
else
event
.
event
=
RDMA_CM_EVENT_ADDR_RESOLVED
;
}
if
(
id_priv
->
id
.
event_handler
(
&
id_priv
->
id
,
&
event
))
{
cma_exch
(
id_priv
,
RDMA_CM_DESTROYING
);
...
...
@@ -2559,6 +2606,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
if
(
ret
)
goto
err1
;
memcpy
(
cma_src_addr
(
id_priv
),
addr
,
rdma_addr_size
(
addr
));
if
(
!
cma_any_addr
(
addr
))
{
ret
=
cma_translate_addr
(
addr
,
&
id
->
route
.
addr
.
dev_addr
);
if
(
ret
)
...
...
@@ -2569,7 +2617,6 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
goto
err1
;
}
memcpy
(
cma_src_addr
(
id_priv
),
addr
,
rdma_addr_size
(
addr
));
if
(
!
(
id_priv
->
options
&
(
1
<<
CMA_OPTION_AFONLY
)))
{
if
(
addr
->
sa_family
==
AF_INET
)
id_priv
->
afonly
=
1
;
...
...
@@ -3298,7 +3345,8 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
err
=
-
EINVAL
;
goto
out2
;
}
iboe_addr_get_sgid
(
dev_addr
,
&
mc
->
multicast
.
ib
->
rec
.
port_gid
);
rdma_ip2gid
((
struct
sockaddr
*
)
&
id_priv
->
id
.
route
.
addr
.
src_addr
,
&
mc
->
multicast
.
ib
->
rec
.
port_gid
);
work
->
id
=
id_priv
;
work
->
mc
=
mc
;
INIT_WORK
(
&
work
->
work
,
iboe_mcast_work_handler
);
...
...
drivers/infiniband/core/core_priv.h
浏览文件 @
fb1b5034
...
...
@@ -49,4 +49,6 @@ void ib_sysfs_cleanup(void);
int
ib_cache_setup
(
void
);
void
ib_cache_cleanup
(
void
);
int
ib_resolve_eth_l2_attrs
(
struct
ib_qp
*
qp
,
struct
ib_qp_attr
*
qp_attr
,
int
*
qp_attr_mask
);
#endif
/* _CORE_PRIV_H */
drivers/infiniband/core/sa_query.c
浏览文件 @
fb1b5034
...
...
@@ -42,7 +42,7 @@
#include <linux/kref.h>
#include <linux/idr.h>
#include <linux/workqueue.h>
#include <uapi/linux/if_ether.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_cache.h>
#include "sa.h"
...
...
@@ -556,6 +556,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
ah_attr
->
grh
.
hop_limit
=
rec
->
hop_limit
;
ah_attr
->
grh
.
traffic_class
=
rec
->
traffic_class
;
}
if
(
force_grh
)
{
memcpy
(
ah_attr
->
dmac
,
rec
->
dmac
,
ETH_ALEN
);
ah_attr
->
vlan_id
=
rec
->
vlan_id
;
}
else
{
ah_attr
->
vlan_id
=
0xffff
;
}
return
0
;
}
EXPORT_SYMBOL
(
ib_init_ah_from_path
);
...
...
@@ -670,6 +677,9 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
ib_unpack
(
path_rec_table
,
ARRAY_SIZE
(
path_rec_table
),
mad
->
data
,
&
rec
);
rec
.
vlan_id
=
0xffff
;
memset
(
rec
.
dmac
,
0
,
ETH_ALEN
);
memset
(
rec
.
smac
,
0
,
ETH_ALEN
);
query
->
callback
(
status
,
&
rec
,
query
->
context
);
}
else
query
->
callback
(
status
,
NULL
,
query
->
context
);
...
...
drivers/infiniband/core/ucma.c
浏览文件 @
fb1b5034
...
...
@@ -655,24 +655,14 @@ static void ucma_copy_ib_route(struct rdma_ucm_query_route_resp *resp,
static
void
ucma_copy_iboe_route
(
struct
rdma_ucm_query_route_resp
*
resp
,
struct
rdma_route
*
route
)
{
struct
rdma_dev_addr
*
dev_addr
;
struct
net_device
*
dev
;
u16
vid
=
0
;
resp
->
num_paths
=
route
->
num_paths
;
switch
(
route
->
num_paths
)
{
case
0
:
dev_addr
=
&
route
->
addr
.
dev_addr
;
dev
=
dev_get_by_index
(
&
init_net
,
dev_addr
->
bound_dev_if
);
if
(
dev
)
{
vid
=
rdma_vlan_dev_vlan_id
(
dev
);
dev_put
(
dev
);
}
iboe_mac_vlan_to_ll
((
union
ib_gid
*
)
&
resp
->
ib_route
[
0
].
dgid
,
dev_addr
->
dst_dev_addr
,
vid
);
iboe_addr_get_sgid
(
dev_addr
,
(
union
ib_gid
*
)
&
resp
->
ib_route
[
0
].
sgid
);
rdma_ip2gid
((
struct
sockaddr
*
)
&
route
->
addr
.
dst_addr
,
(
union
ib_gid
*
)
&
resp
->
ib_route
[
0
].
dgid
);
rdma_ip2gid
((
struct
sockaddr
*
)
&
route
->
addr
.
src_addr
,
(
union
ib_gid
*
)
&
resp
->
ib_route
[
0
].
sgid
);
resp
->
ib_route
[
0
].
pkey
=
cpu_to_be16
(
0xffff
);
break
;
case
2
:
...
...
drivers/infiniband/core/uverbs_cmd.c
浏览文件 @
fb1b5034
...
...
@@ -40,6 +40,7 @@
#include <asm/uaccess.h>
#include "uverbs.h"
#include "core_priv.h"
struct
uverbs_lock_class
{
struct
lock_class_key
key
;
...
...
@@ -1961,6 +1962,9 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
attr
->
alt_ah_attr
.
port_num
=
cmd
.
alt_dest
.
port_num
;
if
(
qp
->
real_qp
==
qp
)
{
ret
=
ib_resolve_eth_l2_attrs
(
qp
,
attr
,
&
cmd
.
attr_mask
);
if
(
ret
)
goto
out
;
ret
=
qp
->
device
->
modify_qp
(
qp
,
attr
,
modify_qp_mask
(
qp
->
qp_type
,
cmd
.
attr_mask
),
&
udata
);
}
else
{
...
...
drivers/infiniband/core/verbs.c
浏览文件 @
fb1b5034
...
...
@@ -44,6 +44,9 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_addr.h>
#include "core_priv.h"
int
ib_rate_to_mult
(
enum
ib_rate
rate
)
{
...
...
@@ -195,8 +198,28 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
u32
flow_class
;
u16
gid_index
;
int
ret
;
int
is_eth
=
(
rdma_port_get_link_layer
(
device
,
port_num
)
==
IB_LINK_LAYER_ETHERNET
);
memset
(
ah_attr
,
0
,
sizeof
*
ah_attr
);
if
(
is_eth
)
{
if
(
!
(
wc
->
wc_flags
&
IB_WC_GRH
))
return
-
EPROTOTYPE
;
if
(
wc
->
wc_flags
&
IB_WC_WITH_SMAC
&&
wc
->
wc_flags
&
IB_WC_WITH_VLAN
)
{
memcpy
(
ah_attr
->
dmac
,
wc
->
smac
,
ETH_ALEN
);
ah_attr
->
vlan_id
=
wc
->
vlan_id
;
}
else
{
ret
=
rdma_addr_find_dmac_by_grh
(
&
grh
->
dgid
,
&
grh
->
sgid
,
ah_attr
->
dmac
,
&
ah_attr
->
vlan_id
);
if
(
ret
)
return
ret
;
}
}
else
{
ah_attr
->
vlan_id
=
0xffff
;
}
ah_attr
->
dlid
=
wc
->
slid
;
ah_attr
->
sl
=
wc
->
sl
;
ah_attr
->
src_path_bits
=
wc
->
dlid_path_bits
;
...
...
@@ -479,7 +502,9 @@ EXPORT_SYMBOL(ib_create_qp);
static
const
struct
{
int
valid
;
enum
ib_qp_attr_mask
req_param
[
IB_QPT_MAX
];
enum
ib_qp_attr_mask
req_param_add_eth
[
IB_QPT_MAX
];
enum
ib_qp_attr_mask
opt_param
[
IB_QPT_MAX
];
enum
ib_qp_attr_mask
opt_param_add_eth
[
IB_QPT_MAX
];
}
qp_state_table
[
IB_QPS_ERR
+
1
][
IB_QPS_ERR
+
1
]
=
{
[
IB_QPS_RESET
]
=
{
[
IB_QPS_RESET
]
=
{
.
valid
=
1
},
...
...
@@ -560,6 +585,12 @@ static const struct {
IB_QP_MAX_DEST_RD_ATOMIC
|
IB_QP_MIN_RNR_TIMER
),
},
.
req_param_add_eth
=
{
[
IB_QPT_RC
]
=
(
IB_QP_SMAC
),
[
IB_QPT_UC
]
=
(
IB_QP_SMAC
),
[
IB_QPT_XRC_INI
]
=
(
IB_QP_SMAC
),
[
IB_QPT_XRC_TGT
]
=
(
IB_QP_SMAC
)
},
.
opt_param
=
{
[
IB_QPT_UD
]
=
(
IB_QP_PKEY_INDEX
|
IB_QP_QKEY
),
...
...
@@ -579,7 +610,21 @@ static const struct {
IB_QP_QKEY
),
[
IB_QPT_GSI
]
=
(
IB_QP_PKEY_INDEX
|
IB_QP_QKEY
),
}
},
.
opt_param_add_eth
=
{
[
IB_QPT_RC
]
=
(
IB_QP_ALT_SMAC
|
IB_QP_VID
|
IB_QP_ALT_VID
),
[
IB_QPT_UC
]
=
(
IB_QP_ALT_SMAC
|
IB_QP_VID
|
IB_QP_ALT_VID
),
[
IB_QPT_XRC_INI
]
=
(
IB_QP_ALT_SMAC
|
IB_QP_VID
|
IB_QP_ALT_VID
),
[
IB_QPT_XRC_TGT
]
=
(
IB_QP_ALT_SMAC
|
IB_QP_VID
|
IB_QP_ALT_VID
)
}
}
},
[
IB_QPS_RTR
]
=
{
...
...
@@ -782,7 +827,8 @@ static const struct {
};
int
ib_modify_qp_is_ok
(
enum
ib_qp_state
cur_state
,
enum
ib_qp_state
next_state
,
enum
ib_qp_type
type
,
enum
ib_qp_attr_mask
mask
)
enum
ib_qp_type
type
,
enum
ib_qp_attr_mask
mask
,
enum
rdma_link_layer
ll
)
{
enum
ib_qp_attr_mask
req_param
,
opt_param
;
...
...
@@ -801,6 +847,13 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
req_param
=
qp_state_table
[
cur_state
][
next_state
].
req_param
[
type
];
opt_param
=
qp_state_table
[
cur_state
][
next_state
].
opt_param
[
type
];
if
(
ll
==
IB_LINK_LAYER_ETHERNET
)
{
req_param
|=
qp_state_table
[
cur_state
][
next_state
].
req_param_add_eth
[
type
];
opt_param
|=
qp_state_table
[
cur_state
][
next_state
].
opt_param_add_eth
[
type
];
}
if
((
mask
&
req_param
)
!=
req_param
)
return
0
;
...
...
@@ -811,10 +864,51 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
}
EXPORT_SYMBOL
(
ib_modify_qp_is_ok
);
int
ib_resolve_eth_l2_attrs
(
struct
ib_qp
*
qp
,
struct
ib_qp_attr
*
qp_attr
,
int
*
qp_attr_mask
)
{
int
ret
=
0
;
union
ib_gid
sgid
;
if
((
*
qp_attr_mask
&
IB_QP_AV
)
&&
(
rdma_port_get_link_layer
(
qp
->
device
,
qp_attr
->
ah_attr
.
port_num
)
==
IB_LINK_LAYER_ETHERNET
))
{
ret
=
ib_query_gid
(
qp
->
device
,
qp_attr
->
ah_attr
.
port_num
,
qp_attr
->
ah_attr
.
grh
.
sgid_index
,
&
sgid
);
if
(
ret
)
goto
out
;
if
(
rdma_link_local_addr
((
struct
in6_addr
*
)
qp_attr
->
ah_attr
.
grh
.
dgid
.
raw
))
{
rdma_get_ll_mac
((
struct
in6_addr
*
)
qp_attr
->
ah_attr
.
grh
.
dgid
.
raw
,
qp_attr
->
ah_attr
.
dmac
);
rdma_get_ll_mac
((
struct
in6_addr
*
)
sgid
.
raw
,
qp_attr
->
smac
);
qp_attr
->
vlan_id
=
rdma_get_vlan_id
(
&
sgid
);
}
else
{
ret
=
rdma_addr_find_dmac_by_grh
(
&
sgid
,
&
qp_attr
->
ah_attr
.
grh
.
dgid
,
qp_attr
->
ah_attr
.
dmac
,
&
qp_attr
->
vlan_id
);
if
(
ret
)
goto
out
;
ret
=
rdma_addr_find_smac_by_sgid
(
&
sgid
,
qp_attr
->
smac
,
NULL
);
if
(
ret
)
goto
out
;
}
*
qp_attr_mask
|=
IB_QP_SMAC
;
if
(
qp_attr
->
vlan_id
<
0xFFFF
)
*
qp_attr_mask
|=
IB_QP_VID
;
}
out:
return
ret
;
}
EXPORT_SYMBOL
(
ib_resolve_eth_l2_attrs
);
int
ib_modify_qp
(
struct
ib_qp
*
qp
,
struct
ib_qp_attr
*
qp_attr
,
int
qp_attr_mask
)
{
int
ret
;
ret
=
ib_resolve_eth_l2_attrs
(
qp
,
qp_attr
,
&
qp_attr_mask
);
if
(
ret
)
return
ret
;
return
qp
->
device
->
modify_qp
(
qp
->
real_qp
,
qp_attr
,
qp_attr_mask
,
NULL
);
}
EXPORT_SYMBOL
(
ib_modify_qp
);
...
...
drivers/infiniband/hw/ehca/ehca_qp.c
浏览文件 @
fb1b5034
...
...
@@ -1329,7 +1329,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
qp_new_state
=
attr_mask
&
IB_QP_STATE
?
attr
->
qp_state
:
qp_cur_state
;
if
(
!
smi_reset2init
&&
!
ib_modify_qp_is_ok
(
qp_cur_state
,
qp_new_state
,
ibqp
->
qp_type
,
attr_mask
))
{
attr_mask
,
IB_LINK_LAYER_UNSPECIFIED
))
{
ret
=
-
EINVAL
;
ehca_err
(
ibqp
->
device
,
"Invalid qp transition new_state=%x cur_state=%x "
...
...
drivers/infiniband/hw/ipath/ipath_qp.c
浏览文件 @
fb1b5034
...
...
@@ -463,7 +463,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
new_state
=
attr_mask
&
IB_QP_STATE
?
attr
->
qp_state
:
cur_state
;
if
(
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
))
attr_mask
,
IB_LINK_LAYER_UNSPECIFIED
))
goto
inval
;
if
(
attr_mask
&
IB_QP_AV
)
{
...
...
drivers/infiniband/hw/mlx4/Kconfig
浏览文件 @
fb1b5034
config MLX4_INFINIBAND
tristate "Mellanox ConnectX HCA support"
depends on NETDEVICES && ETHERNET && PCI
depends on NETDEVICES && ETHERNET && PCI
&& INET
select NET_VENDOR_MELLANOX
select MLX4_CORE
---help---
...
...
drivers/infiniband/hw/mlx4/ah.c
浏览文件 @
fb1b5034
...
...
@@ -39,25 +39,6 @@
#include "mlx4_ib.h"
int
mlx4_ib_resolve_grh
(
struct
mlx4_ib_dev
*
dev
,
const
struct
ib_ah_attr
*
ah_attr
,
u8
*
mac
,
int
*
is_mcast
,
u8
port
)
{
struct
in6_addr
in6
;
*
is_mcast
=
0
;
memcpy
(
&
in6
,
ah_attr
->
grh
.
dgid
.
raw
,
sizeof
in6
);
if
(
rdma_link_local_addr
(
&
in6
))
rdma_get_ll_mac
(
&
in6
,
mac
);
else
if
(
rdma_is_multicast_addr
(
&
in6
))
{
rdma_get_mcast_mac
(
&
in6
,
mac
);
*
is_mcast
=
1
;
}
else
return
-
EINVAL
;
return
0
;
}
static
struct
ib_ah
*
create_ib_ah
(
struct
ib_pd
*
pd
,
struct
ib_ah_attr
*
ah_attr
,
struct
mlx4_ib_ah
*
ah
)
{
...
...
@@ -92,21 +73,18 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
{
struct
mlx4_ib_dev
*
ibdev
=
to_mdev
(
pd
->
device
);
struct
mlx4_dev
*
dev
=
ibdev
->
dev
;
union
ib_gid
sgid
;
u8
mac
[
6
];
int
err
;
int
is_mcast
;
struct
in6_addr
in6
;
u16
vlan_tag
;
err
=
mlx4_ib_resolve_grh
(
ibdev
,
ah_attr
,
mac
,
&
is_mcast
,
ah_attr
->
port_num
);
if
(
err
)
return
ERR_PTR
(
err
);
memcpy
(
ah
->
av
.
eth
.
mac
,
mac
,
6
);
err
=
ib_get_cached_gid
(
pd
->
device
,
ah_attr
->
port_num
,
ah_attr
->
grh
.
sgid_index
,
&
sgid
);
if
(
err
)
return
ERR_PTR
(
err
);
vlan_tag
=
rdma_get_vlan_id
(
&
sgid
);
memcpy
(
&
in6
,
ah_attr
->
grh
.
dgid
.
raw
,
sizeof
(
in6
));
if
(
rdma_is_multicast_addr
(
&
in6
))
{
is_mcast
=
1
;
rdma_get_mcast_mac
(
&
in6
,
ah
->
av
.
eth
.
mac
);
}
else
{
memcpy
(
ah
->
av
.
eth
.
mac
,
ah_attr
->
dmac
,
ETH_ALEN
);
}
vlan_tag
=
ah_attr
->
vlan_id
;
if
(
vlan_tag
<
0x1000
)
vlan_tag
|=
(
ah_attr
->
sl
&
7
)
<<
13
;
ah
->
av
.
eth
.
port_pd
=
cpu_to_be32
(
to_mpd
(
pd
)
->
pdn
|
(
ah_attr
->
port_num
<<
24
));
...
...
drivers/infiniband/hw/mlx4/cq.c
浏览文件 @
fb1b5034
...
...
@@ -798,6 +798,15 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
wc
->
sl
=
be16_to_cpu
(
cqe
->
sl_vid
)
>>
13
;
else
wc
->
sl
=
be16_to_cpu
(
cqe
->
sl_vid
)
>>
12
;
if
(
be32_to_cpu
(
cqe
->
vlan_my_qpn
)
&
MLX4_CQE_VLAN_PRESENT_MASK
)
{
wc
->
vlan_id
=
be16_to_cpu
(
cqe
->
sl_vid
)
&
MLX4_CQE_VID_MASK
;
}
else
{
wc
->
vlan_id
=
0xffff
;
}
wc
->
wc_flags
|=
IB_WC_WITH_VLAN
;
memcpy
(
wc
->
smac
,
cqe
->
smac
,
ETH_ALEN
);
wc
->
wc_flags
|=
IB_WC_WITH_SMAC
;
}
return
0
;
...
...
drivers/infiniband/hw/mlx4/main.c
浏览文件 @
fb1b5034
...
...
@@ -39,6 +39,8 @@
#include <linux/inetdevice.h>
#include <linux/rtnetlink.h>
#include <linux/if_vlan.h>
#include <net/ipv6.h>
#include <net/addrconf.h>
#include <rdma/ib_smi.h>
#include <rdma/ib_user_verbs.h>
...
...
@@ -794,7 +796,6 @@ static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)
int
mlx4_ib_add_mc
(
struct
mlx4_ib_dev
*
mdev
,
struct
mlx4_ib_qp
*
mqp
,
union
ib_gid
*
gid
)
{
u8
mac
[
6
];
struct
net_device
*
ndev
;
int
ret
=
0
;
...
...
@@ -808,11 +809,7 @@ int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
spin_unlock
(
&
mdev
->
iboe
.
lock
);
if
(
ndev
)
{
rdma_get_mcast_mac
((
struct
in6_addr
*
)
gid
,
mac
);
rtnl_lock
();
dev_mc_add
(
mdev
->
iboe
.
netdevs
[
mqp
->
port
-
1
],
mac
);
ret
=
1
;
rtnl_unlock
();
dev_put
(
ndev
);
}
...
...
@@ -1164,6 +1161,8 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
struct
mlx4_ib_qp
*
mqp
=
to_mqp
(
ibqp
);
u64
reg_id
;
struct
mlx4_ib_steering
*
ib_steering
=
NULL
;
enum
mlx4_protocol
prot
=
(
gid
->
raw
[
1
]
==
0x0e
)
?
MLX4_PROT_IB_IPV4
:
MLX4_PROT_IB_IPV6
;
if
(
mdev
->
dev
->
caps
.
steering_mode
==
MLX4_STEERING_MODE_DEVICE_MANAGED
)
{
...
...
@@ -1175,7 +1174,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
err
=
mlx4_multicast_attach
(
mdev
->
dev
,
&
mqp
->
mqp
,
gid
->
raw
,
mqp
->
port
,
!!
(
mqp
->
flags
&
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK
),
MLX4_PROT_IB_IPV6
,
&
reg_id
);
prot
,
&
reg_id
);
if
(
err
)
goto
err_malloc
;
...
...
@@ -1194,7 +1193,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
err_add:
mlx4_multicast_detach
(
mdev
->
dev
,
&
mqp
->
mqp
,
gid
->
raw
,
MLX4_PROT_IB_IPV6
,
reg_id
);
prot
,
reg_id
);
err_malloc:
kfree
(
ib_steering
);
...
...
@@ -1222,10 +1221,11 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
int
err
;
struct
mlx4_ib_dev
*
mdev
=
to_mdev
(
ibqp
->
device
);
struct
mlx4_ib_qp
*
mqp
=
to_mqp
(
ibqp
);
u8
mac
[
6
];
struct
net_device
*
ndev
;
struct
mlx4_ib_gid_entry
*
ge
;
u64
reg_id
=
0
;
enum
mlx4_protocol
prot
=
(
gid
->
raw
[
1
]
==
0x0e
)
?
MLX4_PROT_IB_IPV4
:
MLX4_PROT_IB_IPV6
;
if
(
mdev
->
dev
->
caps
.
steering_mode
==
MLX4_STEERING_MODE_DEVICE_MANAGED
)
{
...
...
@@ -1248,7 +1248,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
}
err
=
mlx4_multicast_detach
(
mdev
->
dev
,
&
mqp
->
mqp
,
gid
->
raw
,
MLX4_PROT_IB_IPV6
,
reg_id
);
prot
,
reg_id
);
if
(
err
)
return
err
;
...
...
@@ -1260,13 +1260,8 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
if
(
ndev
)
dev_hold
(
ndev
);
spin_unlock
(
&
mdev
->
iboe
.
lock
);
rdma_get_mcast_mac
((
struct
in6_addr
*
)
gid
,
mac
);
if
(
ndev
)
{
rtnl_lock
();
dev_mc_del
(
mdev
->
iboe
.
netdevs
[
ge
->
port
-
1
],
mac
);
rtnl_unlock
();
if
(
ndev
)
dev_put
(
ndev
);
}
list_del
(
&
ge
->
list
);
kfree
(
ge
);
}
else
...
...
@@ -1362,20 +1357,6 @@ static struct device_attribute *mlx4_class_attributes[] = {
&
dev_attr_board_id
};
static
void
mlx4_addrconf_ifid_eui48
(
u8
*
eui
,
u16
vlan_id
,
struct
net_device
*
dev
)
{
memcpy
(
eui
,
dev
->
dev_addr
,
3
);
memcpy
(
eui
+
5
,
dev
->
dev_addr
+
3
,
3
);
if
(
vlan_id
<
0x1000
)
{
eui
[
3
]
=
vlan_id
>>
8
;
eui
[
4
]
=
vlan_id
&
0xff
;
}
else
{
eui
[
3
]
=
0xff
;
eui
[
4
]
=
0xfe
;
}
eui
[
0
]
^=
2
;
}
static
void
update_gids_task
(
struct
work_struct
*
work
)
{
struct
update_gid_work
*
gw
=
container_of
(
work
,
struct
update_gid_work
,
work
);
...
...
@@ -1398,161 +1379,318 @@ static void update_gids_task(struct work_struct *work)
MLX4_CMD_WRAPPED
);
if
(
err
)
pr_warn
(
"set port command failed
\n
"
);
else
{
memcpy
(
gw
->
dev
->
iboe
.
gid_table
[
gw
->
port
-
1
],
gw
->
gids
,
sizeof
gw
->
gids
);
else
mlx4_ib_dispatch_event
(
gw
->
dev
,
gw
->
port
,
IB_EVENT_GID_CHANGE
);
}
mlx4_free_cmd_mailbox
(
dev
,
mailbox
);
kfree
(
gw
);
}
static
int
update_ipv6_gids
(
struct
mlx4_ib_dev
*
dev
,
int
port
,
int
clear
)
static
void
reset_gids_task
(
struct
work_struct
*
work
)
{
struct
net_device
*
ndev
=
dev
->
iboe
.
netdevs
[
port
-
1
];
struct
update_gid_work
*
work
;
struct
net_device
*
tmp
;
struct
update_gid_work
*
gw
=
container_of
(
work
,
struct
update_gid_work
,
work
);
struct
mlx4_cmd_mailbox
*
mailbox
;
union
ib_gid
*
gids
;
int
err
;
int
i
;
u8
*
hits
;
int
ret
;
union
ib_gid
gid
;
int
free
;
int
found
;
int
need_update
=
0
;
u16
vid
;
struct
mlx4_dev
*
dev
=
gw
->
dev
->
dev
;
work
=
kzalloc
(
sizeof
*
work
,
GFP_ATOMIC
);
if
(
!
work
)
return
-
ENOMEM
;
mailbox
=
mlx4_alloc_cmd_mailbox
(
dev
);
if
(
IS_ERR
(
mailbox
))
{
pr_warn
(
"reset gid table failed
\n
"
);
goto
free
;
}
hits
=
kzalloc
(
128
,
GFP_ATOMIC
);
if
(
!
hits
)
{
ret
=
-
ENOMEM
;
goto
out
;
gids
=
mailbox
->
buf
;
memcpy
(
gids
,
gw
->
gids
,
sizeof
(
gw
->
gids
));
for
(
i
=
1
;
i
<
gw
->
dev
->
num_ports
+
1
;
i
++
)
{
if
(
mlx4_ib_port_link_layer
(
&
gw
->
dev
->
ib_dev
,
i
)
==
IB_LINK_LAYER_ETHERNET
)
{
err
=
mlx4_cmd
(
dev
,
mailbox
->
dma
,
MLX4_SET_PORT_GID_TABLE
<<
8
|
i
,
1
,
MLX4_CMD_SET_PORT
,
MLX4_CMD_TIME_CLASS_B
,
MLX4_CMD_WRAPPED
);
if
(
err
)
pr_warn
(
KERN_WARNING
"set port %d command failed
\n
"
,
i
);
}
}
rcu_read_lock
();
for_each_netdev_rcu
(
&
init_net
,
tmp
)
{
if
(
ndev
&&
(
tmp
==
ndev
||
rdma_vlan_dev_real_dev
(
tmp
)
==
ndev
))
{
gid
.
global
.
subnet_prefix
=
cpu_to_be64
(
0xfe80000000000000LL
);
vid
=
rdma_vlan_dev_vlan_id
(
tmp
);
mlx4_addrconf_ifid_eui48
(
&
gid
.
raw
[
8
],
vid
,
ndev
);
found
=
0
;
free
=
-
1
;
for
(
i
=
0
;
i
<
128
;
++
i
)
{
if
(
free
<
0
&&
!
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
i
],
&
zgid
,
sizeof
zgid
))
free
=
i
;
if
(
!
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
i
],
&
gid
,
sizeof
gid
))
{
hits
[
i
]
=
1
;
found
=
1
;
break
;
}
}
mlx4_free_cmd_mailbox
(
dev
,
mailbox
);
free:
kfree
(
gw
);
}
if
(
!
found
)
{
if
(
tmp
==
ndev
&&
(
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
0
],
&
gid
,
sizeof
gid
)
||
!
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
0
],
&
zgid
,
sizeof
gid
)))
{
dev
->
iboe
.
gid_table
[
port
-
1
][
0
]
=
gid
;
++
need_update
;
hits
[
0
]
=
1
;
}
else
if
(
free
>=
0
)
{
dev
->
iboe
.
gid_table
[
port
-
1
][
free
]
=
gid
;
hits
[
free
]
=
1
;
++
need_update
;
}
static
int
update_gid_table
(
struct
mlx4_ib_dev
*
dev
,
int
port
,
union
ib_gid
*
gid
,
int
clear
)
{
struct
update_gid_work
*
work
;
int
i
;
int
need_update
=
0
;
int
free
=
-
1
;
int
found
=
-
1
;
int
max_gids
;
max_gids
=
dev
->
dev
->
caps
.
gid_table_len
[
port
];
for
(
i
=
0
;
i
<
max_gids
;
++
i
)
{
if
(
!
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
i
],
gid
,
sizeof
(
*
gid
)))
found
=
i
;
if
(
clear
)
{
if
(
found
>=
0
)
{
need_update
=
1
;
dev
->
iboe
.
gid_table
[
port
-
1
][
found
]
=
zgid
;
break
;
}
}
else
{
if
(
found
>=
0
)
break
;
if
(
free
<
0
&&
!
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
i
],
&
zgid
,
sizeof
(
*
gid
)))
free
=
i
;
}
}
rcu_read_unlock
();
for
(
i
=
0
;
i
<
128
;
++
i
)
if
(
!
hits
[
i
])
{
if
(
memcmp
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
i
],
&
zgid
,
sizeof
zgid
))
++
need_update
;
dev
->
iboe
.
gid_table
[
port
-
1
][
i
]
=
zgid
;
}
if
(
found
==
-
1
&&
!
clear
&&
free
>=
0
)
{
dev
->
iboe
.
gid_table
[
port
-
1
][
free
]
=
*
gid
;
need_update
=
1
;
}
if
(
need_update
)
{
memcpy
(
work
->
gids
,
dev
->
iboe
.
gid_table
[
port
-
1
],
sizeof
work
->
gids
);
INIT_WORK
(
&
work
->
work
,
update_gids_task
);
work
->
port
=
port
;
work
->
dev
=
dev
;
queue_work
(
wq
,
&
work
->
work
);
}
else
kfree
(
work
);
if
(
!
need_update
)
return
0
;
work
=
kzalloc
(
sizeof
(
*
work
),
GFP_ATOMIC
);
if
(
!
work
)
return
-
ENOMEM
;
memcpy
(
work
->
gids
,
dev
->
iboe
.
gid_table
[
port
-
1
],
sizeof
(
work
->
gids
));
INIT_WORK
(
&
work
->
work
,
update_gids_task
);
work
->
port
=
port
;
work
->
dev
=
dev
;
queue_work
(
wq
,
&
work
->
work
);
kfree
(
hits
);
return
0
;
}
out:
kfree
(
work
);
return
ret
;
static
int
reset_gid_table
(
struct
mlx4_ib_dev
*
dev
)
{
struct
update_gid_work
*
work
;
work
=
kzalloc
(
sizeof
(
*
work
),
GFP_ATOMIC
);
if
(
!
work
)
return
-
ENOMEM
;
memset
(
dev
->
iboe
.
gid_table
,
0
,
sizeof
(
dev
->
iboe
.
gid_table
));
memset
(
work
->
gids
,
0
,
sizeof
(
work
->
gids
));
INIT_WORK
(
&
work
->
work
,
reset_gids_task
);
work
->
dev
=
dev
;
queue_work
(
wq
,
&
work
->
work
);
return
0
;
}
static
void
handle_en_event
(
struct
mlx4_ib_dev
*
dev
,
int
port
,
unsigned
long
event
)
static
int
mlx4_ib_addr_event
(
int
event
,
struct
net_device
*
event_netdev
,
struct
mlx4_ib_dev
*
ibdev
,
union
ib_gid
*
gid
)
{
switch
(
event
)
{
case
NETDEV_UP
:
case
NETDEV_CHANGEADDR
:
update_ipv6_gids
(
dev
,
port
,
0
);
break
;
struct
mlx4_ib_iboe
*
iboe
;
int
port
=
0
;
struct
net_device
*
real_dev
=
rdma_vlan_dev_real_dev
(
event_netdev
)
?
rdma_vlan_dev_real_dev
(
event_netdev
)
:
event_netdev
;
if
(
event
!=
NETDEV_DOWN
&&
event
!=
NETDEV_UP
)
return
0
;
if
((
real_dev
!=
event_netdev
)
&&
(
event
==
NETDEV_DOWN
)
&&
rdma_link_local_addr
((
struct
in6_addr
*
)
gid
))
return
0
;
iboe
=
&
ibdev
->
iboe
;
spin_lock
(
&
iboe
->
lock
);
for
(
port
=
1
;
port
<=
MLX4_MAX_PORTS
;
++
port
)
if
((
netif_is_bond_master
(
real_dev
)
&&
(
real_dev
==
iboe
->
masters
[
port
-
1
]))
||
(
!
netif_is_bond_master
(
real_dev
)
&&
(
real_dev
==
iboe
->
netdevs
[
port
-
1
])))
update_gid_table
(
ibdev
,
port
,
gid
,
event
==
NETDEV_DOWN
);
spin_unlock
(
&
iboe
->
lock
);
return
0
;
case
NETDEV_DOWN
:
update_ipv6_gids
(
dev
,
port
,
1
);
dev
->
iboe
.
netdevs
[
port
-
1
]
=
NULL
;
}
}
static
void
netdev_added
(
struct
mlx4_ib_dev
*
dev
,
int
port
)
static
u8
mlx4_ib_get_dev_port
(
struct
net_device
*
dev
,
struct
mlx4_ib_dev
*
ibdev
)
{
update_ipv6_gids
(
dev
,
port
,
0
);
u8
port
=
0
;
struct
mlx4_ib_iboe
*
iboe
;
struct
net_device
*
real_dev
=
rdma_vlan_dev_real_dev
(
dev
)
?
rdma_vlan_dev_real_dev
(
dev
)
:
dev
;
iboe
=
&
ibdev
->
iboe
;
spin_lock
(
&
iboe
->
lock
);
for
(
port
=
1
;
port
<=
MLX4_MAX_PORTS
;
++
port
)
if
((
netif_is_bond_master
(
real_dev
)
&&
(
real_dev
==
iboe
->
masters
[
port
-
1
]))
||
(
!
netif_is_bond_master
(
real_dev
)
&&
(
real_dev
==
iboe
->
netdevs
[
port
-
1
])))
break
;
spin_unlock
(
&
iboe
->
lock
);
if
((
port
==
0
)
||
(
port
>
MLX4_MAX_PORTS
))
return
0
;
else
return
port
;
}
static
void
netdev_removed
(
struct
mlx4_ib_dev
*
dev
,
int
port
)
static
int
mlx4_ib_inet_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
update_ipv6_gids
(
dev
,
port
,
1
);
struct
mlx4_ib_dev
*
ibdev
;
struct
in_ifaddr
*
ifa
=
ptr
;
union
ib_gid
gid
;
struct
net_device
*
event_netdev
=
ifa
->
ifa_dev
->
dev
;
ipv6_addr_set_v4mapped
(
ifa
->
ifa_address
,
(
struct
in6_addr
*
)
&
gid
);
ibdev
=
container_of
(
this
,
struct
mlx4_ib_dev
,
iboe
.
nb_inet
);
mlx4_ib_addr_event
(
event
,
event_netdev
,
ibdev
,
&
gid
);
return
NOTIFY_DONE
;
}
static
int
mlx4_ib_netdev_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
#if IS_ENABLED(CONFIG_IPV6)
static
int
mlx4_ib_inet6_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
struct
net_device
*
dev
=
netdev_notifier_info_to_dev
(
ptr
);
struct
mlx4_ib_dev
*
ibdev
;
struct
net_device
*
oldnd
;
struct
inet6_ifaddr
*
ifa
=
ptr
;
union
ib_gid
*
gid
=
(
union
ib_gid
*
)
&
ifa
->
addr
;
struct
net_device
*
event_netdev
=
ifa
->
idev
->
dev
;
ibdev
=
container_of
(
this
,
struct
mlx4_ib_dev
,
iboe
.
nb_inet6
);
mlx4_ib_addr_event
(
event
,
event_netdev
,
ibdev
,
gid
);
return
NOTIFY_DONE
;
}
#endif
static
void
mlx4_ib_get_dev_addr
(
struct
net_device
*
dev
,
struct
mlx4_ib_dev
*
ibdev
,
u8
port
)
{
struct
in_device
*
in_dev
;
#if IS_ENABLED(CONFIG_IPV6)
struct
inet6_dev
*
in6_dev
;
union
ib_gid
*
pgid
;
struct
inet6_ifaddr
*
ifp
;
#endif
union
ib_gid
gid
;
if
((
port
==
0
)
||
(
port
>
MLX4_MAX_PORTS
))
return
;
/* IPv4 gids */
in_dev
=
in_dev_get
(
dev
);
if
(
in_dev
)
{
for_ifa
(
in_dev
)
{
/*ifa->ifa_address;*/
ipv6_addr_set_v4mapped
(
ifa
->
ifa_address
,
(
struct
in6_addr
*
)
&
gid
);
update_gid_table
(
ibdev
,
port
,
&
gid
,
0
);
}
endfor_ifa
(
in_dev
);
in_dev_put
(
in_dev
);
}
#if IS_ENABLED(CONFIG_IPV6)
/* IPv6 gids */
in6_dev
=
in6_dev_get
(
dev
);
if
(
in6_dev
)
{
read_lock_bh
(
&
in6_dev
->
lock
);
list_for_each_entry
(
ifp
,
&
in6_dev
->
addr_list
,
if_list
)
{
pgid
=
(
union
ib_gid
*
)
&
ifp
->
addr
;
update_gid_table
(
ibdev
,
port
,
pgid
,
0
);
}
read_unlock_bh
(
&
in6_dev
->
lock
);
in6_dev_put
(
in6_dev
);
}
#endif
}
static
int
mlx4_ib_init_gid_table
(
struct
mlx4_ib_dev
*
ibdev
)
{
struct
net_device
*
dev
;
if
(
reset_gid_table
(
ibdev
))
return
-
1
;
read_lock
(
&
dev_base_lock
);
for_each_netdev
(
&
init_net
,
dev
)
{
u8
port
=
mlx4_ib_get_dev_port
(
dev
,
ibdev
);
if
(
port
)
mlx4_ib_get_dev_addr
(
dev
,
ibdev
,
port
);
}
read_unlock
(
&
dev_base_lock
);
return
0
;
}
static
void
mlx4_ib_scan_netdevs
(
struct
mlx4_ib_dev
*
ibdev
)
{
struct
mlx4_ib_iboe
*
iboe
;
int
port
;
if
(
!
net_eq
(
dev_net
(
dev
),
&
init_net
))
return
NOTIFY_DONE
;
ibdev
=
container_of
(
this
,
struct
mlx4_ib_dev
,
iboe
.
nb
);
iboe
=
&
ibdev
->
iboe
;
spin_lock
(
&
iboe
->
lock
);
mlx4_foreach_ib_transport_port
(
port
,
ibdev
->
dev
)
{
oldnd
=
iboe
->
netdevs
[
port
-
1
];
struct
net_device
*
old_master
=
iboe
->
masters
[
port
-
1
];
struct
net_device
*
curr_master
;
iboe
->
netdevs
[
port
-
1
]
=
mlx4_get_protocol_dev
(
ibdev
->
dev
,
MLX4_PROT_ETH
,
port
);
if
(
oldnd
!=
iboe
->
netdevs
[
port
-
1
])
{
if
(
iboe
->
netdevs
[
port
-
1
])
netdev_added
(
ibdev
,
port
);
else
netdev_removed
(
ibdev
,
port
);
if
(
iboe
->
netdevs
[
port
-
1
]
&&
netif_is_bond_slave
(
iboe
->
netdevs
[
port
-
1
]))
{
rtnl_lock
();
iboe
->
masters
[
port
-
1
]
=
netdev_master_upper_dev_get
(
iboe
->
netdevs
[
port
-
1
]);
rtnl_unlock
();
}
}
curr_master
=
iboe
->
masters
[
port
-
1
];
if
(
dev
==
iboe
->
netdevs
[
0
]
||
(
iboe
->
netdevs
[
0
]
&&
rdma_vlan_dev_real_dev
(
dev
)
==
iboe
->
netdevs
[
0
]))
handle_en_event
(
ibdev
,
1
,
event
);
else
if
(
dev
==
iboe
->
netdevs
[
1
]
||
(
iboe
->
netdevs
[
1
]
&&
rdma_vlan_dev_real_dev
(
dev
)
==
iboe
->
netdevs
[
1
]))
handle_en_event
(
ibdev
,
2
,
event
);
/* if bonding is used it is possible that we add it to masters
only after IP address is assigned to the net bonding
interface */
if
(
curr_master
&&
(
old_master
!=
curr_master
))
mlx4_ib_get_dev_addr
(
curr_master
,
ibdev
,
port
);
}
spin_unlock
(
&
iboe
->
lock
);
}
static
int
mlx4_ib_netdev_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
struct
net_device
*
dev
=
netdev_notifier_info_to_dev
(
ptr
);
struct
mlx4_ib_dev
*
ibdev
;
if
(
!
net_eq
(
dev_net
(
dev
),
&
init_net
))
return
NOTIFY_DONE
;
ibdev
=
container_of
(
this
,
struct
mlx4_ib_dev
,
iboe
.
nb
);
mlx4_ib_scan_netdevs
(
ibdev
);
return
NOTIFY_DONE
;
}
...
...
@@ -1886,11 +2024,35 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
if
(
mlx4_ib_init_sriov
(
ibdev
))
goto
err_mad
;
if
(
dev
->
caps
.
flags
&
MLX4_DEV_CAP_FLAG_IBOE
&&
!
iboe
->
nb
.
notifier_call
)
{
iboe
->
nb
.
notifier_call
=
mlx4_ib_netdev_event
;
err
=
register_netdevice_notifier
(
&
iboe
->
nb
);
if
(
err
)
goto
err_sriov
;
if
(
dev
->
caps
.
flags
&
MLX4_DEV_CAP_FLAG_IBOE
)
{
if
(
!
iboe
->
nb
.
notifier_call
)
{
iboe
->
nb
.
notifier_call
=
mlx4_ib_netdev_event
;
err
=
register_netdevice_notifier
(
&
iboe
->
nb
);
if
(
err
)
{
iboe
->
nb
.
notifier_call
=
NULL
;
goto
err_notif
;
}
}
if
(
!
iboe
->
nb_inet
.
notifier_call
)
{
iboe
->
nb_inet
.
notifier_call
=
mlx4_ib_inet_event
;
err
=
register_inetaddr_notifier
(
&
iboe
->
nb_inet
);
if
(
err
)
{
iboe
->
nb_inet
.
notifier_call
=
NULL
;
goto
err_notif
;
}
}
#if IS_ENABLED(CONFIG_IPV6)
if
(
!
iboe
->
nb_inet6
.
notifier_call
)
{
iboe
->
nb_inet6
.
notifier_call
=
mlx4_ib_inet6_event
;
err
=
register_inet6addr_notifier
(
&
iboe
->
nb_inet6
);
if
(
err
)
{
iboe
->
nb_inet6
.
notifier_call
=
NULL
;
goto
err_notif
;
}
}
#endif
mlx4_ib_scan_netdevs
(
ibdev
);
mlx4_ib_init_gid_table
(
ibdev
);
}
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
mlx4_class_attributes
);
++
j
)
{
...
...
@@ -1916,11 +2078,25 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
return
ibdev
;
err_notif:
if
(
unregister_netdevice_notifier
(
&
ibdev
->
iboe
.
nb
))
pr_warn
(
"failure unregistering notifier
\n
"
);
if
(
ibdev
->
iboe
.
nb
.
notifier_call
)
{
if
(
unregister_netdevice_notifier
(
&
ibdev
->
iboe
.
nb
))
pr_warn
(
"failure unregistering notifier
\n
"
);
ibdev
->
iboe
.
nb
.
notifier_call
=
NULL
;
}
if
(
ibdev
->
iboe
.
nb_inet
.
notifier_call
)
{
if
(
unregister_inetaddr_notifier
(
&
ibdev
->
iboe
.
nb_inet
))
pr_warn
(
"failure unregistering notifier
\n
"
);
ibdev
->
iboe
.
nb_inet
.
notifier_call
=
NULL
;
}
#if IS_ENABLED(CONFIG_IPV6)
if
(
ibdev
->
iboe
.
nb_inet6
.
notifier_call
)
{
if
(
unregister_inet6addr_notifier
(
&
ibdev
->
iboe
.
nb_inet6
))
pr_warn
(
"failure unregistering notifier
\n
"
);
ibdev
->
iboe
.
nb_inet6
.
notifier_call
=
NULL
;
}
#endif
flush_workqueue
(
wq
);
err_sriov:
mlx4_ib_close_sriov
(
ibdev
);
err_mad:
...
...
@@ -2039,6 +2215,19 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
kfree
(
ibdev
->
ib_uc_qpns_bitmap
);
}
if
(
ibdev
->
iboe
.
nb_inet
.
notifier_call
)
{
if
(
unregister_inetaddr_notifier
(
&
ibdev
->
iboe
.
nb_inet
))
pr_warn
(
"failure unregistering notifier
\n
"
);
ibdev
->
iboe
.
nb_inet
.
notifier_call
=
NULL
;
}
#if IS_ENABLED(CONFIG_IPV6)
if
(
ibdev
->
iboe
.
nb_inet6
.
notifier_call
)
{
if
(
unregister_inet6addr_notifier
(
&
ibdev
->
iboe
.
nb_inet6
))
pr_warn
(
"failure unregistering notifier
\n
"
);
ibdev
->
iboe
.
nb_inet6
.
notifier_call
=
NULL
;
}
#endif
iounmap
(
ibdev
->
uar_map
);
for
(
p
=
0
;
p
<
ibdev
->
num_ports
;
++
p
)
if
(
ibdev
->
counters
[
p
]
!=
-
1
)
...
...
drivers/infiniband/hw/mlx4/mlx4_ib.h
浏览文件 @
fb1b5034
...
...
@@ -432,7 +432,10 @@ struct mlx4_ib_sriov {
struct
mlx4_ib_iboe
{
spinlock_t
lock
;
struct
net_device
*
netdevs
[
MLX4_MAX_PORTS
];
struct
net_device
*
masters
[
MLX4_MAX_PORTS
];
struct
notifier_block
nb
;
struct
notifier_block
nb_inet
;
struct
notifier_block
nb_inet6
;
union
ib_gid
gid_table
[
MLX4_MAX_PORTS
][
128
];
};
...
...
@@ -683,9 +686,6 @@ int __mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
int
__mlx4_ib_query_gid
(
struct
ib_device
*
ibdev
,
u8
port
,
int
index
,
union
ib_gid
*
gid
,
int
netw_view
);
int
mlx4_ib_resolve_grh
(
struct
mlx4_ib_dev
*
dev
,
const
struct
ib_ah_attr
*
ah_attr
,
u8
*
mac
,
int
*
is_mcast
,
u8
port
);
static
inline
bool
mlx4_ib_ah_grh_present
(
struct
mlx4_ib_ah
*
ah
)
{
u8
port
=
be32_to_cpu
(
ah
->
av
.
ib
.
port_pd
)
>>
24
&
3
;
...
...
drivers/infiniband/hw/mlx4/qp.c
浏览文件 @
fb1b5034
...
...
@@ -90,6 +90,21 @@ enum {
MLX4_RAW_QP_MSGMAX
=
31
,
};
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
static
inline
u64
mlx4_mac_to_u64
(
u8
*
addr
)
{
u64
mac
=
0
;
int
i
;
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
{
mac
<<=
8
;
mac
|=
addr
[
i
];
}
return
mac
;
}
static
const
__be32
mlx4_ib_opcode
[]
=
{
[
IB_WR_SEND
]
=
cpu_to_be32
(
MLX4_OPCODE_SEND
),
[
IB_WR_LSO
]
=
cpu_to_be32
(
MLX4_OPCODE_LSO
),
...
...
@@ -1171,16 +1186,15 @@ static void mlx4_set_sched(struct mlx4_qp_path *path, u8 port)
path
->
sched_queue
=
(
path
->
sched_queue
&
0xbf
)
|
((
port
-
1
)
<<
6
);
}
static
int
mlx4_set_path
(
struct
mlx4_ib_dev
*
dev
,
const
struct
ib_ah_attr
*
ah
,
struct
mlx4_qp_path
*
path
,
u8
port
)
static
int
_mlx4_set_path
(
struct
mlx4_ib_dev
*
dev
,
const
struct
ib_ah_attr
*
ah
,
u64
smac
,
u16
vlan_tag
,
struct
mlx4_qp_path
*
path
,
u8
port
)
{
int
err
;
int
is_eth
=
rdma_port_get_link_layer
(
&
dev
->
ib_dev
,
port
)
==
IB_LINK_LAYER_ETHERNET
;
u8
mac
[
6
];
int
is_mcast
;
u16
vlan_tag
;
int
vidx
;
int
smac_index
;
path
->
grh_mylmc
=
ah
->
src_path_bits
&
0x7f
;
path
->
rlid
=
cpu_to_be16
(
ah
->
dlid
);
...
...
@@ -1215,22 +1229,27 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
if
(
!
(
ah
->
ah_flags
&
IB_AH_GRH
))
return
-
1
;
err
=
mlx4_ib_resolve_grh
(
dev
,
ah
,
mac
,
&
is_mcast
,
port
);
if
(
err
)
return
err
;
memcpy
(
path
->
dmac
,
mac
,
6
);
memcpy
(
path
->
dmac
,
ah
->
dmac
,
ETH_ALEN
);
path
->
ackto
=
MLX4_IB_LINK_TYPE_ETH
;
/* use index 0 into MAC table for IBoE */
path
->
grh_mylmc
&=
0x80
;
/* find the index into MAC table for IBoE */
if
(
!
is_zero_ether_addr
((
const
u8
*
)
&
smac
))
{
if
(
mlx4_find_cached_mac
(
dev
->
dev
,
port
,
smac
,
&
smac_index
))
return
-
ENOENT
;
}
else
{
smac_index
=
0
;
}
vlan_tag
=
rdma_get_vlan_id
(
&
dev
->
iboe
.
gid_table
[
port
-
1
][
ah
->
grh
.
sgid_index
]);
path
->
grh_mylmc
&=
0x80
|
smac_index
;
path
->
feup
|=
MLX4_FEUP_FORCE_ETH_UP
;
if
(
vlan_tag
<
0x1000
)
{
if
(
mlx4_find_cached_vlan
(
dev
->
dev
,
port
,
vlan_tag
,
&
vidx
))
return
-
ENOENT
;
path
->
vlan_index
=
vidx
;
path
->
fl
=
1
<<
6
;
path
->
feup
|=
MLX4_FVL_FORCE_ETH_VLAN
;
}
}
else
path
->
sched_queue
=
MLX4_IB_DEFAULT_SCHED_QUEUE
|
...
...
@@ -1239,6 +1258,28 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
return
0
;
}
static
int
mlx4_set_path
(
struct
mlx4_ib_dev
*
dev
,
const
struct
ib_qp_attr
*
qp
,
enum
ib_qp_attr_mask
qp_attr_mask
,
struct
mlx4_qp_path
*
path
,
u8
port
)
{
return
_mlx4_set_path
(
dev
,
&
qp
->
ah_attr
,
mlx4_mac_to_u64
((
u8
*
)
qp
->
smac
),
(
qp_attr_mask
&
IB_QP_VID
)
?
qp
->
vlan_id
:
0xffff
,
path
,
port
);
}
static
int
mlx4_set_alt_path
(
struct
mlx4_ib_dev
*
dev
,
const
struct
ib_qp_attr
*
qp
,
enum
ib_qp_attr_mask
qp_attr_mask
,
struct
mlx4_qp_path
*
path
,
u8
port
)
{
return
_mlx4_set_path
(
dev
,
&
qp
->
alt_ah_attr
,
mlx4_mac_to_u64
((
u8
*
)
qp
->
alt_smac
),
(
qp_attr_mask
&
IB_QP_ALT_VID
)
?
qp
->
alt_vlan_id
:
0xffff
,
path
,
port
);
}
static
void
update_mcg_macs
(
struct
mlx4_ib_dev
*
dev
,
struct
mlx4_ib_qp
*
qp
)
{
struct
mlx4_ib_gid_entry
*
ge
,
*
tmp
;
...
...
@@ -1362,7 +1403,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
}
if
(
attr_mask
&
IB_QP_AV
)
{
if
(
mlx4_set_path
(
dev
,
&
attr
->
ah_attr
,
&
context
->
pri_path
,
if
(
mlx4_set_path
(
dev
,
attr
,
attr_mask
,
&
context
->
pri_path
,
attr_mask
&
IB_QP_PORT
?
attr
->
port_num
:
qp
->
port
))
goto
out
;
...
...
@@ -1385,8 +1426,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
dev
->
dev
->
caps
.
pkey_table_len
[
attr
->
alt_port_num
])
goto
out
;
if
(
mlx4_set_
path
(
dev
,
&
attr
->
alt_ah_attr
,
&
context
->
alt_path
,
attr
->
alt_port_num
))
if
(
mlx4_set_
alt_path
(
dev
,
attr
,
attr_mask
,
&
context
->
alt_path
,
attr
->
alt_port_num
))
goto
out
;
context
->
alt_path
.
pkey_index
=
attr
->
alt_pkey_index
;
...
...
@@ -1497,6 +1538,17 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
context
->
pri_path
.
ackto
=
(
context
->
pri_path
.
ackto
&
0xf8
)
|
MLX4_IB_LINK_TYPE_ETH
;
if
(
ibqp
->
qp_type
==
IB_QPT_UD
&&
(
new_state
==
IB_QPS_RTR
))
{
int
is_eth
=
rdma_port_get_link_layer
(
&
dev
->
ib_dev
,
qp
->
port
)
==
IB_LINK_LAYER_ETHERNET
;
if
(
is_eth
)
{
context
->
pri_path
.
ackto
=
MLX4_IB_LINK_TYPE_ETH
;
optpar
|=
MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH
;
}
}
if
(
cur_state
==
IB_QPS_RTS
&&
new_state
==
IB_QPS_SQD
&&
attr_mask
&
IB_QP_EN_SQD_ASYNC_NOTIFY
&&
attr
->
en_sqd_async_notify
)
sqd_event
=
1
;
...
...
@@ -1599,13 +1651,21 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
struct
mlx4_ib_qp
*
qp
=
to_mqp
(
ibqp
);
enum
ib_qp_state
cur_state
,
new_state
;
int
err
=
-
EINVAL
;
int
ll
;
mutex_lock
(
&
qp
->
mutex
);
cur_state
=
attr_mask
&
IB_QP_CUR_STATE
?
attr
->
cur_qp_state
:
qp
->
state
;
new_state
=
attr_mask
&
IB_QP_STATE
?
attr
->
qp_state
:
cur_state
;
if
(
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
))
{
if
(
cur_state
==
new_state
&&
cur_state
==
IB_QPS_RESET
)
{
ll
=
IB_LINK_LAYER_UNSPECIFIED
;
}
else
{
int
port
=
attr_mask
&
IB_QP_PORT
?
attr
->
port_num
:
qp
->
port
;
ll
=
rdma_port_get_link_layer
(
&
dev
->
ib_dev
,
port
);
}
if
(
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
,
ll
))
{
pr_debug
(
"qpn 0x%x: invalid attribute mask specified "
"for transition %d to %d. qp_type %d,"
" attr_mask 0x%x
\n
"
,
...
...
@@ -1822,8 +1882,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
return
err
;
}
vlan
=
rdma_get_vlan_id
(
&
sgid
);
is_vlan
=
vlan
<
0x1000
;
if
(
ah
->
av
.
eth
.
vlan
!=
0xffff
)
{
vlan
=
be16_to_cpu
(
ah
->
av
.
eth
.
vlan
)
&
0x0fff
;
is_vlan
=
1
;
}
}
ib_ud_header_init
(
send_size
,
!
is_eth
,
is_eth
,
is_vlan
,
is_grh
,
0
,
&
sqp
->
ud_header
);
...
...
drivers/infiniband/hw/mlx5/qp.c
浏览文件 @
fb1b5034
...
...
@@ -1664,7 +1664,8 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
new_state
=
attr_mask
&
IB_QP_STATE
?
attr
->
qp_state
:
cur_state
;
if
(
ibqp
->
qp_type
!=
MLX5_IB_QPT_REG_UMR
&&
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
))
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
,
IB_LINK_LAYER_UNSPECIFIED
))
goto
out
;
if
((
attr_mask
&
IB_QP_PORT
)
&&
...
...
drivers/infiniband/hw/mthca/mthca_qp.c
浏览文件 @
fb1b5034
...
...
@@ -860,7 +860,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
new_state
=
attr_mask
&
IB_QP_STATE
?
attr
->
qp_state
:
cur_state
;
if
(
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
))
{
if
(
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
,
IB_LINK_LAYER_UNSPECIFIED
))
{
mthca_dbg
(
dev
,
"Bad QP transition (transport %d) "
"%d->%d with attr 0x%08x
\n
"
,
qp
->
transport
,
cur_state
,
new_state
,
...
...
drivers/infiniband/hw/ocrdma/Kconfig
浏览文件 @
fb1b5034
config INFINIBAND_OCRDMA
tristate "Emulex One Connect HCA support"
depends on ETHERNET && NETDEVICES && PCI && (IPV6 || IPV6=n)
depends on ETHERNET && NETDEVICES && PCI &&
INET &&
(IPV6 || IPV6=n)
select NET_VENDOR_EMULEX
select BE2NET
---help---
...
...
drivers/infiniband/hw/ocrdma/ocrdma.h
浏览文件 @
fb1b5034
...
...
@@ -423,5 +423,17 @@ static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
OCRDMA_CQE_WRITE_IMM
)
?
1
:
0
;
}
static
inline
int
ocrdma_resolve_dmac
(
struct
ocrdma_dev
*
dev
,
struct
ib_ah_attr
*
ah_attr
,
u8
*
mac_addr
)
{
struct
in6_addr
in6
;
memcpy
(
&
in6
,
ah_attr
->
grh
.
dgid
.
raw
,
sizeof
(
in6
));
if
(
rdma_is_multicast_addr
(
&
in6
))
rdma_get_mcast_mac
(
&
in6
,
mac_addr
);
else
memcpy
(
mac_addr
,
ah_attr
->
dmac
,
ETH_ALEN
);
return
0
;
}
#endif
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
浏览文件 @
fb1b5034
...
...
@@ -49,7 +49,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
ah
->
sgid_index
=
attr
->
grh
.
sgid_index
;
vlan_tag
=
rdma_get_vlan_id
(
&
attr
->
grh
.
dgid
)
;
vlan_tag
=
attr
->
vlan_id
;
if
(
!
vlan_tag
||
(
vlan_tag
>
0xFFF
))
vlan_tag
=
dev
->
pvid
;
if
(
vlan_tag
&&
(
vlan_tag
<
0x1000
))
{
...
...
@@ -64,7 +64,8 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
eth_sz
=
sizeof
(
struct
ocrdma_eth_basic
);
}
memcpy
(
&
eth
.
smac
[
0
],
&
dev
->
nic_info
.
mac_addr
[
0
],
ETH_ALEN
);
status
=
ocrdma_resolve_dgid
(
dev
,
&
attr
->
grh
.
dgid
,
&
eth
.
dmac
[
0
]);
memcpy
(
&
eth
.
dmac
[
0
],
attr
->
dmac
,
ETH_ALEN
);
status
=
ocrdma_resolve_dmac
(
dev
,
attr
,
&
eth
.
dmac
[
0
]);
if
(
status
)
return
status
;
status
=
ocrdma_query_gid
(
&
dev
->
ibdev
,
1
,
attr
->
grh
.
sgid_index
,
...
...
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
浏览文件 @
fb1b5034
...
...
@@ -2076,23 +2076,6 @@ int ocrdma_mbx_query_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp,
return
status
;
}
int
ocrdma_resolve_dgid
(
struct
ocrdma_dev
*
dev
,
union
ib_gid
*
dgid
,
u8
*
mac_addr
)
{
struct
in6_addr
in6
;
memcpy
(
&
in6
,
dgid
,
sizeof
in6
);
if
(
rdma_is_multicast_addr
(
&
in6
))
{
rdma_get_mcast_mac
(
&
in6
,
mac_addr
);
}
else
if
(
rdma_link_local_addr
(
&
in6
))
{
rdma_get_ll_mac
(
&
in6
,
mac_addr
);
}
else
{
pr_err
(
"%s() fail to resolve mac_addr.
\n
"
,
__func__
);
return
-
EINVAL
;
}
return
0
;
}
static
int
ocrdma_set_av_params
(
struct
ocrdma_qp
*
qp
,
struct
ocrdma_modify_qp
*
cmd
,
struct
ib_qp_attr
*
attrs
)
...
...
@@ -2126,14 +2109,14 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
qp
->
sgid_idx
=
ah_attr
->
grh
.
sgid_index
;
memcpy
(
&
cmd
->
params
.
sgid
[
0
],
&
sgid
.
raw
[
0
],
sizeof
(
cmd
->
params
.
sgid
));
ocrdma_resolve_d
gid
(
qp
->
dev
,
&
ah_attr
->
grh
.
dgid
,
&
mac_addr
[
0
]);
ocrdma_resolve_d
mac
(
qp
->
dev
,
ah_attr
,
&
mac_addr
[
0
]);
cmd
->
params
.
dmac_b0_to_b3
=
mac_addr
[
0
]
|
(
mac_addr
[
1
]
<<
8
)
|
(
mac_addr
[
2
]
<<
16
)
|
(
mac_addr
[
3
]
<<
24
);
/* convert them to LE format. */
ocrdma_cpu_to_le32
(
&
cmd
->
params
.
dgid
[
0
],
sizeof
(
cmd
->
params
.
dgid
));
ocrdma_cpu_to_le32
(
&
cmd
->
params
.
sgid
[
0
],
sizeof
(
cmd
->
params
.
sgid
));
cmd
->
params
.
vlan_dmac_b4_to_b5
=
mac_addr
[
4
]
|
(
mac_addr
[
5
]
<<
8
);
vlan_id
=
rdma_get_vlan_id
(
&
sgid
)
;
vlan_id
=
ah_attr
->
vlan_id
;
if
(
vlan_id
&&
(
vlan_id
<
0x1000
))
{
cmd
->
params
.
vlan_dmac_b4_to_b5
|=
vlan_id
<<
OCRDMA_QP_PARAMS_VLAN_SHIFT
;
...
...
drivers/infiniband/hw/ocrdma/ocrdma_hw.h
浏览文件 @
fb1b5034
...
...
@@ -94,7 +94,6 @@ void ocrdma_ring_cq_db(struct ocrdma_dev *, u16 cq_id, bool armed,
int
ocrdma_mbx_get_link_speed
(
struct
ocrdma_dev
*
dev
,
u8
*
lnk_speed
);
int
ocrdma_query_config
(
struct
ocrdma_dev
*
,
struct
ocrdma_mbx_query_config
*
config
);
int
ocrdma_resolve_dgid
(
struct
ocrdma_dev
*
,
union
ib_gid
*
dgid
,
u8
*
mac_addr
);
int
ocrdma_mbx_alloc_pd
(
struct
ocrdma_dev
*
,
struct
ocrdma_pd
*
);
int
ocrdma_mbx_dealloc_pd
(
struct
ocrdma_dev
*
,
struct
ocrdma_pd
*
);
...
...
drivers/infiniband/hw/ocrdma/ocrdma_main.c
浏览文件 @
fb1b5034
...
...
@@ -67,46 +67,24 @@ void ocrdma_get_guid(struct ocrdma_dev *dev, u8 *guid)
guid
[
7
]
=
mac_addr
[
5
];
}
static
void
ocrdma_build_sgid_mac
(
union
ib_gid
*
sgid
,
unsigned
char
*
mac_addr
,
bool
is_vlan
,
u16
vlan_id
)
{
sgid
->
global
.
subnet_prefix
=
cpu_to_be64
(
0xfe80000000000000LL
);
sgid
->
raw
[
8
]
=
mac_addr
[
0
]
^
2
;
sgid
->
raw
[
9
]
=
mac_addr
[
1
];
sgid
->
raw
[
10
]
=
mac_addr
[
2
];
if
(
is_vlan
)
{
sgid
->
raw
[
11
]
=
vlan_id
>>
8
;
sgid
->
raw
[
12
]
=
vlan_id
&
0xff
;
}
else
{
sgid
->
raw
[
11
]
=
0xff
;
sgid
->
raw
[
12
]
=
0xfe
;
}
sgid
->
raw
[
13
]
=
mac_addr
[
3
];
sgid
->
raw
[
14
]
=
mac_addr
[
4
];
sgid
->
raw
[
15
]
=
mac_addr
[
5
];
}
static
bool
ocrdma_add_sgid
(
struct
ocrdma_dev
*
dev
,
unsigned
char
*
mac_addr
,
bool
is_vlan
,
u16
vlan_id
)
static
bool
ocrdma_add_sgid
(
struct
ocrdma_dev
*
dev
,
union
ib_gid
*
new_sgid
)
{
int
i
;
union
ib_gid
new_sgid
;
unsigned
long
flags
;
memset
(
&
ocrdma_zero_sgid
,
0
,
sizeof
(
union
ib_gid
));
ocrdma_build_sgid_mac
(
&
new_sgid
,
mac_addr
,
is_vlan
,
vlan_id
);
spin_lock_irqsave
(
&
dev
->
sgid_lock
,
flags
);
for
(
i
=
0
;
i
<
OCRDMA_MAX_SGID
;
i
++
)
{
if
(
!
memcmp
(
&
dev
->
sgid_tbl
[
i
],
&
ocrdma_zero_sgid
,
sizeof
(
union
ib_gid
)))
{
/* found free entry */
memcpy
(
&
dev
->
sgid_tbl
[
i
],
&
new_sgid
,
memcpy
(
&
dev
->
sgid_tbl
[
i
],
new_sgid
,
sizeof
(
union
ib_gid
));
spin_unlock_irqrestore
(
&
dev
->
sgid_lock
,
flags
);
return
true
;
}
else
if
(
!
memcmp
(
&
dev
->
sgid_tbl
[
i
],
&
new_sgid
,
}
else
if
(
!
memcmp
(
&
dev
->
sgid_tbl
[
i
],
new_sgid
,
sizeof
(
union
ib_gid
)))
{
/* entry already present, no addition is required. */
spin_unlock_irqrestore
(
&
dev
->
sgid_lock
,
flags
);
...
...
@@ -117,20 +95,17 @@ static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
return
false
;
}
static
bool
ocrdma_del_sgid
(
struct
ocrdma_dev
*
dev
,
unsigned
char
*
mac_addr
,
bool
is_vlan
,
u16
vlan_id
)
static
bool
ocrdma_del_sgid
(
struct
ocrdma_dev
*
dev
,
union
ib_gid
*
sgid
)
{
int
found
=
false
;
int
i
;
union
ib_gid
sgid
;
unsigned
long
flags
;
ocrdma_build_sgid_mac
(
&
sgid
,
mac_addr
,
is_vlan
,
vlan_id
);
spin_lock_irqsave
(
&
dev
->
sgid_lock
,
flags
);
/* first is default sgid, which cannot be deleted. */
for
(
i
=
1
;
i
<
OCRDMA_MAX_SGID
;
i
++
)
{
if
(
!
memcmp
(
&
dev
->
sgid_tbl
[
i
],
&
sgid
,
sizeof
(
union
ib_gid
)))
{
if
(
!
memcmp
(
&
dev
->
sgid_tbl
[
i
],
sgid
,
sizeof
(
union
ib_gid
)))
{
/* found matching entry */
memset
(
&
dev
->
sgid_tbl
[
i
],
0
,
sizeof
(
union
ib_gid
));
found
=
true
;
...
...
@@ -141,75 +116,18 @@ static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
return
found
;
}
static
void
ocrdma_add_default_sgid
(
struct
ocrdma_dev
*
dev
)
{
/* GID Index 0 - Invariant manufacturer-assigned EUI-64 */
union
ib_gid
*
sgid
=
&
dev
->
sgid_tbl
[
0
];
sgid
->
global
.
subnet_prefix
=
cpu_to_be64
(
0xfe80000000000000LL
);
ocrdma_get_guid
(
dev
,
&
sgid
->
raw
[
8
]);
}
#if IS_ENABLED(CONFIG_VLAN_8021Q)
static
void
ocrdma_add_vlan_sgids
(
struct
ocrdma_dev
*
dev
)
{
struct
net_device
*
netdev
,
*
tmp
;
u16
vlan_id
;
bool
is_vlan
;
netdev
=
dev
->
nic_info
.
netdev
;
rcu_read_lock
();
for_each_netdev_rcu
(
&
init_net
,
tmp
)
{
if
(
netdev
==
tmp
||
vlan_dev_real_dev
(
tmp
)
==
netdev
)
{
if
(
!
netif_running
(
tmp
)
||
!
netif_oper_up
(
tmp
))
continue
;
if
(
netdev
!=
tmp
)
{
vlan_id
=
vlan_dev_vlan_id
(
tmp
);
is_vlan
=
true
;
}
else
{
is_vlan
=
false
;
vlan_id
=
0
;
tmp
=
netdev
;
}
ocrdma_add_sgid
(
dev
,
tmp
->
dev_addr
,
is_vlan
,
vlan_id
);
}
}
rcu_read_unlock
();
}
#else
static
void
ocrdma_add_vlan_sgids
(
struct
ocrdma_dev
*
dev
)
{
}
#endif
/* VLAN */
static
int
ocrdma_build_sgid_tbl
(
struct
ocrdma_dev
*
dev
)
static
int
ocrdma_addr_event
(
unsigned
long
event
,
struct
net_device
*
netdev
,
union
ib_gid
*
gid
)
{
ocrdma_add_default_sgid
(
dev
);
ocrdma_add_vlan_sgids
(
dev
);
return
0
;
}
#if IS_ENABLED(CONFIG_IPV6)
static
int
ocrdma_inet6addr_event
(
struct
notifier_block
*
notifier
,
unsigned
long
event
,
void
*
ptr
)
{
struct
inet6_ifaddr
*
ifa
=
(
struct
inet6_ifaddr
*
)
ptr
;
struct
net_device
*
netdev
=
ifa
->
idev
->
dev
;
struct
ib_event
gid_event
;
struct
ocrdma_dev
*
dev
;
bool
found
=
false
;
bool
updated
=
false
;
bool
is_vlan
=
false
;
u16
vid
=
0
;
is_vlan
=
netdev
->
priv_flags
&
IFF_802_1Q_VLAN
;
if
(
is_vlan
)
{
vid
=
vlan_dev_vlan_id
(
netdev
);
if
(
is_vlan
)
netdev
=
vlan_dev_real_dev
(
netdev
);
}
rcu_read_lock
();
list_for_each_entry_rcu
(
dev
,
&
ocrdma_dev_list
,
entry
)
{
...
...
@@ -222,16 +140,14 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
if
(
!
found
)
return
NOTIFY_DONE
;
if
(
!
rdma_link_local_addr
((
struct
in6_addr
*
)
&
ifa
->
addr
))
return
NOTIFY_DONE
;
mutex_lock
(
&
dev
->
dev_lock
);
switch
(
event
)
{
case
NETDEV_UP
:
updated
=
ocrdma_add_sgid
(
dev
,
netdev
->
dev_addr
,
is_vlan
,
v
id
);
updated
=
ocrdma_add_sgid
(
dev
,
g
id
);
break
;
case
NETDEV_DOWN
:
updated
=
ocrdma_del_sgid
(
dev
,
netdev
->
dev_addr
,
is_vlan
,
v
id
);
updated
=
ocrdma_del_sgid
(
dev
,
g
id
);
break
;
default:
break
;
...
...
@@ -247,6 +163,32 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
return
NOTIFY_OK
;
}
static
int
ocrdma_inetaddr_event
(
struct
notifier_block
*
notifier
,
unsigned
long
event
,
void
*
ptr
)
{
struct
in_ifaddr
*
ifa
=
ptr
;
union
ib_gid
gid
;
struct
net_device
*
netdev
=
ifa
->
ifa_dev
->
dev
;
ipv6_addr_set_v4mapped
(
ifa
->
ifa_address
,
(
struct
in6_addr
*
)
&
gid
);
return
ocrdma_addr_event
(
event
,
netdev
,
&
gid
);
}
static
struct
notifier_block
ocrdma_inetaddr_notifier
=
{
.
notifier_call
=
ocrdma_inetaddr_event
};
#if IS_ENABLED(CONFIG_IPV6)
static
int
ocrdma_inet6addr_event
(
struct
notifier_block
*
notifier
,
unsigned
long
event
,
void
*
ptr
)
{
struct
inet6_ifaddr
*
ifa
=
(
struct
inet6_ifaddr
*
)
ptr
;
union
ib_gid
*
gid
=
(
union
ib_gid
*
)
&
ifa
->
addr
;
struct
net_device
*
netdev
=
ifa
->
idev
->
dev
;
return
ocrdma_addr_event
(
event
,
netdev
,
gid
);
}
static
struct
notifier_block
ocrdma_inet6addr_notifier
=
{
.
notifier_call
=
ocrdma_inet6addr_event
};
...
...
@@ -423,10 +365,6 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
if
(
status
)
goto
alloc_err
;
status
=
ocrdma_build_sgid_tbl
(
dev
);
if
(
status
)
goto
alloc_err
;
status
=
ocrdma_register_device
(
dev
);
if
(
status
)
goto
alloc_err
;
...
...
@@ -553,6 +491,10 @@ static int __init ocrdma_init_module(void)
{
int
status
;
status
=
register_inetaddr_notifier
(
&
ocrdma_inetaddr_notifier
);
if
(
status
)
return
status
;
#if IS_ENABLED(CONFIG_IPV6)
status
=
register_inet6addr_notifier
(
&
ocrdma_inet6addr_notifier
);
if
(
status
)
...
...
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
浏览文件 @
fb1b5034
...
...
@@ -1326,7 +1326,8 @@ int ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
new_qps
=
old_qps
;
spin_unlock_irqrestore
(
&
qp
->
q_lock
,
flags
);
if
(
!
ib_modify_qp_is_ok
(
old_qps
,
new_qps
,
ibqp
->
qp_type
,
attr_mask
))
{
if
(
!
ib_modify_qp_is_ok
(
old_qps
,
new_qps
,
ibqp
->
qp_type
,
attr_mask
,
IB_LINK_LAYER_ETHERNET
))
{
pr_err
(
"%s(%d) invalid attribute mask=0x%x specified for
\n
"
"qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x
\n
"
,
__func__
,
dev
->
id
,
attr_mask
,
qp
->
id
,
ibqp
->
qp_type
,
...
...
drivers/infiniband/hw/qib/qib_qp.c
浏览文件 @
fb1b5034
...
...
@@ -585,7 +585,7 @@ int qib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
new_state
=
attr_mask
&
IB_QP_STATE
?
attr
->
qp_state
:
cur_state
;
if
(
!
ib_modify_qp_is_ok
(
cur_state
,
new_state
,
ibqp
->
qp_type
,
attr_mask
))
attr_mask
,
IB_LINK_LAYER_UNSPECIFIED
))
goto
inval
;
if
(
attr_mask
&
IB_QP_AV
)
{
...
...
drivers/net/ethernet/mellanox/mlx4/port.c
浏览文件 @
fb1b5034
...
...
@@ -123,6 +123,26 @@ static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
return
err
;
}
int
mlx4_find_cached_mac
(
struct
mlx4_dev
*
dev
,
u8
port
,
u64
mac
,
int
*
idx
)
{
struct
mlx4_port_info
*
info
=
&
mlx4_priv
(
dev
)
->
port
[
port
];
struct
mlx4_mac_table
*
table
=
&
info
->
mac_table
;
int
i
;
for
(
i
=
0
;
i
<
MLX4_MAX_MAC_NUM
;
i
++
)
{
if
(
!
table
->
refs
[
i
])
continue
;
if
(
mac
==
(
MLX4_MAC_MASK
&
be64_to_cpu
(
table
->
entries
[
i
])))
{
*
idx
=
i
;
return
0
;
}
}
return
-
ENOENT
;
}
EXPORT_SYMBOL_GPL
(
mlx4_find_cached_mac
);
int
__mlx4_register_mac
(
struct
mlx4_dev
*
dev
,
u8
port
,
u64
mac
)
{
struct
mlx4_port_info
*
info
=
&
mlx4_priv
(
dev
)
->
port
[
port
];
...
...
include/linux/mlx4/cq.h
浏览文件 @
fb1b5034
...
...
@@ -34,6 +34,7 @@
#define MLX4_CQ_H
#include <linux/types.h>
#include <uapi/linux/if_ether.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/doorbell.h>
...
...
@@ -43,10 +44,15 @@ struct mlx4_cqe {
__be32
immed_rss_invalid
;
__be32
g_mlpath_rqpn
;
__be16
sl_vid
;
__be16
rlid
;
__be16
status
;
u8
ipv6_ext_mask
;
u8
badfcs_enc
;
union
{
struct
{
__be16
rlid
;
__be16
status
;
u8
ipv6_ext_mask
;
u8
badfcs_enc
;
};
u8
smac
[
ETH_ALEN
];
};
__be32
byte_cnt
;
__be16
wqe_index
;
__be16
checksum
;
...
...
@@ -83,6 +89,7 @@ struct mlx4_ts_cqe {
enum
{
MLX4_CQE_VLAN_PRESENT_MASK
=
1
<<
29
,
MLX4_CQE_QPN_MASK
=
0xffffff
,
MLX4_CQE_VID_MASK
=
0xfff
,
};
enum
{
...
...
include/linux/mlx4/device.h
浏览文件 @
fb1b5034
...
...
@@ -1096,6 +1096,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
int
mlx4_SET_PORT_PRIO2TC
(
struct
mlx4_dev
*
dev
,
u8
port
,
u8
*
prio2tc
);
int
mlx4_SET_PORT_SCHEDULER
(
struct
mlx4_dev
*
dev
,
u8
port
,
u8
*
tc_tx_bw
,
u8
*
pg
,
u16
*
ratelimit
);
int
mlx4_find_cached_mac
(
struct
mlx4_dev
*
dev
,
u8
port
,
u64
mac
,
int
*
idx
);
int
mlx4_find_cached_vlan
(
struct
mlx4_dev
*
dev
,
u8
port
,
u16
vid
,
int
*
idx
);
int
mlx4_register_vlan
(
struct
mlx4_dev
*
dev
,
u8
port
,
u16
vlan
,
int
*
index
);
void
mlx4_unregister_vlan
(
struct
mlx4_dev
*
dev
,
u8
port
,
u16
vlan
);
...
...
include/rdma/ib_addr.h
浏览文件 @
fb1b5034
...
...
@@ -38,10 +38,15 @@
#include <linux/in6.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/socket.h>
#include <linux/if_vlan.h>
#include <net/ipv6.h>
#include <net/if_inet6.h>
#include <net/ip.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_pack.h>
#include <net/ipv6.h>
struct
rdma_addr_client
{
atomic_t
refcount
;
...
...
@@ -72,7 +77,8 @@ struct rdma_dev_addr {
* rdma_translate_ip - Translate a local IP address to an RDMA hardware
* address.
*/
int
rdma_translate_ip
(
struct
sockaddr
*
addr
,
struct
rdma_dev_addr
*
dev_addr
);
int
rdma_translate_ip
(
struct
sockaddr
*
addr
,
struct
rdma_dev_addr
*
dev_addr
,
u16
*
vlan_id
);
/**
* rdma_resolve_ip - Resolve source and destination IP addresses to
...
...
@@ -104,6 +110,10 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
int
rdma_addr_size
(
struct
sockaddr
*
addr
);
int
rdma_addr_find_smac_by_sgid
(
union
ib_gid
*
sgid
,
u8
*
smac
,
u16
*
vlan_id
);
int
rdma_addr_find_dmac_by_grh
(
union
ib_gid
*
sgid
,
union
ib_gid
*
dgid
,
u8
*
smac
,
u16
*
vlan_id
);
static
inline
u16
ib_addr_get_pkey
(
struct
rdma_dev_addr
*
dev_addr
)
{
return
((
u16
)
dev_addr
->
broadcast
[
8
]
<<
8
)
|
(
u16
)
dev_addr
->
broadcast
[
9
];
...
...
@@ -126,41 +136,60 @@ static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr)
return
dev_addr
->
dev_type
==
ARPHRD_INFINIBAND
?
4
:
0
;
}
static
inline
void
iboe_mac_vlan_to_ll
(
union
ib_gid
*
gid
,
u8
*
mac
,
u16
vid
)
static
inline
u16
rdma_vlan_dev_vlan_id
(
const
struct
net_device
*
dev
)
{
memset
(
gid
->
raw
,
0
,
16
);
*
((
__be32
*
)
gid
->
raw
)
=
cpu_to_be32
(
0xfe800000
);
if
(
vid
<
0x1000
)
{
gid
->
raw
[
12
]
=
vid
&
0xff
;
gid
->
raw
[
11
]
=
vid
>>
8
;
}
else
{
gid
->
raw
[
12
]
=
0xfe
;
gid
->
raw
[
11
]
=
0xff
;
return
dev
->
priv_flags
&
IFF_802_1Q_VLAN
?
vlan_dev_vlan_id
(
dev
)
:
0xffff
;
}
static
inline
int
rdma_ip2gid
(
struct
sockaddr
*
addr
,
union
ib_gid
*
gid
)
{
switch
(
addr
->
sa_family
)
{
case
AF_INET
:
ipv6_addr_set_v4mapped
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
.
s_addr
,
(
struct
in6_addr
*
)
gid
);
break
;
case
AF_INET6
:
memcpy
(
gid
->
raw
,
&
((
struct
sockaddr_in6
*
)
addr
)
->
sin6_addr
,
16
);
break
;
default:
return
-
EINVAL
;
}
memcpy
(
gid
->
raw
+
13
,
mac
+
3
,
3
);
memcpy
(
gid
->
raw
+
8
,
mac
,
3
);
gid
->
raw
[
8
]
^=
2
;
return
0
;
}
static
inline
u16
rdma_vlan_dev_vlan_id
(
const
struct
net_device
*
dev
)
/* Important - sockaddr should be a union of sockaddr_in and sockaddr_in6 */
static
inline
int
rdma_gid2ip
(
struct
sockaddr
*
out
,
union
ib_gid
*
gid
)
{
return
dev
->
priv_flags
&
IFF_802_1Q_VLAN
?
vlan_dev_vlan_id
(
dev
)
:
0xffff
;
if
(
ipv6_addr_v4mapped
((
struct
in6_addr
*
)
gid
))
{
struct
sockaddr_in
*
out_in
=
(
struct
sockaddr_in
*
)
out
;
memset
(
out_in
,
0
,
sizeof
(
*
out_in
));
out_in
->
sin_family
=
AF_INET
;
memcpy
(
&
out_in
->
sin_addr
.
s_addr
,
gid
->
raw
+
12
,
4
);
}
else
{
struct
sockaddr_in6
*
out_in
=
(
struct
sockaddr_in6
*
)
out
;
memset
(
out_in
,
0
,
sizeof
(
*
out_in
));
out_in
->
sin6_family
=
AF_INET6
;
memcpy
(
&
out_in
->
sin6_addr
.
s6_addr
,
gid
->
raw
,
16
);
}
return
0
;
}
static
inline
void
iboe_addr_get_sgid
(
struct
rdma_dev_addr
*
dev_addr
,
union
ib_gid
*
gid
)
{
struct
net_device
*
dev
;
u16
vid
=
0xffff
;
struct
in_device
*
ip4
;
dev
=
dev_get_by_index
(
&
init_net
,
dev_addr
->
bound_dev_if
);
if
(
dev
)
{
vid
=
rdma_vlan_dev_vlan_id
(
dev
);
ip4
=
(
struct
in_device
*
)
dev
->
ip_ptr
;
if
(
ip4
&&
ip4
->
ifa_list
&&
ip4
->
ifa_list
->
ifa_address
)
ipv6_addr_set_v4mapped
(
ip4
->
ifa_list
->
ifa_address
,
(
struct
in6_addr
*
)
gid
);
dev_put
(
dev
);
}
iboe_mac_vlan_to_ll
(
gid
,
dev_addr
->
src_dev_addr
,
vid
);
}
static
inline
void
rdma_addr_get_sgid
(
struct
rdma_dev_addr
*
dev_addr
,
union
ib_gid
*
gid
)
...
...
include/rdma/ib_cm.h
浏览文件 @
fb1b5034
...
...
@@ -601,4 +601,5 @@ struct ib_cm_sidr_rep_param {
int
ib_send_cm_sidr_rep
(
struct
ib_cm_id
*
cm_id
,
struct
ib_cm_sidr_rep_param
*
param
);
int
ib_update_cm_av
(
struct
ib_cm_id
*
id
,
const
u8
*
smac
,
const
u8
*
alt_smac
);
#endif
/* IB_CM_H */
include/rdma/ib_pack.h
浏览文件 @
fb1b5034
...
...
@@ -34,6 +34,7 @@
#define IB_PACK_H
#include <rdma/ib_verbs.h>
#include <uapi/linux/if_ether.h>
enum
{
IB_LRH_BYTES
=
8
,
...
...
include/rdma/ib_sa.h
浏览文件 @
fb1b5034
...
...
@@ -154,6 +154,9 @@ struct ib_sa_path_rec {
u8
packet_life_time_selector
;
u8
packet_life_time
;
u8
preference
;
u8
smac
[
ETH_ALEN
];
u8
dmac
[
ETH_ALEN
];
u16
vlan_id
;
};
#define IB_SA_MCMEMBER_REC_MGID IB_SA_COMP_MASK( 0)
...
...
include/rdma/ib_verbs.h
浏览文件 @
fb1b5034
...
...
@@ -48,6 +48,7 @@
#include <linux/rwsem.h>
#include <linux/scatterlist.h>
#include <linux/workqueue.h>
#include <uapi/linux/if_ether.h>
#include <linux/atomic.h>
#include <asm/uaccess.h>
...
...
@@ -474,6 +475,8 @@ struct ib_ah_attr {
u8
static_rate
;
u8
ah_flags
;
u8
port_num
;
u8
dmac
[
ETH_ALEN
];
u16
vlan_id
;
};
enum
ib_wc_status
{
...
...
@@ -526,6 +529,8 @@ enum ib_wc_flags {
IB_WC_WITH_IMM
=
(
1
<<
1
),
IB_WC_WITH_INVALIDATE
=
(
1
<<
2
),
IB_WC_IP_CSUM_OK
=
(
1
<<
3
),
IB_WC_WITH_SMAC
=
(
1
<<
4
),
IB_WC_WITH_VLAN
=
(
1
<<
5
),
};
struct
ib_wc
{
...
...
@@ -546,6 +551,8 @@ struct ib_wc {
u8
sl
;
u8
dlid_path_bits
;
u8
port_num
;
/* valid only for DR SMPs on switches */
u8
smac
[
ETH_ALEN
];
u16
vlan_id
;
};
enum
ib_cq_notify_flags
{
...
...
@@ -724,7 +731,11 @@ enum ib_qp_attr_mask {
IB_QP_MAX_DEST_RD_ATOMIC
=
(
1
<<
17
),
IB_QP_PATH_MIG_STATE
=
(
1
<<
18
),
IB_QP_CAP
=
(
1
<<
19
),
IB_QP_DEST_QPN
=
(
1
<<
20
)
IB_QP_DEST_QPN
=
(
1
<<
20
),
IB_QP_SMAC
=
(
1
<<
21
),
IB_QP_ALT_SMAC
=
(
1
<<
22
),
IB_QP_VID
=
(
1
<<
23
),
IB_QP_ALT_VID
=
(
1
<<
24
),
};
enum
ib_qp_state
{
...
...
@@ -774,6 +785,10 @@ struct ib_qp_attr {
u8
rnr_retry
;
u8
alt_port_num
;
u8
alt_timeout
;
u8
smac
[
ETH_ALEN
];
u8
alt_smac
[
ETH_ALEN
];
u16
vlan_id
;
u16
alt_vlan_id
;
};
enum
ib_wr_opcode
{
...
...
@@ -1505,6 +1520,7 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
* @next_state: Next QP state
* @type: QP type
* @mask: Mask of supplied QP attributes
* @ll : link layer of port
*
* This function is a helper function that a low-level driver's
* modify_qp method can use to validate the consumer's input. It
...
...
@@ -1513,7 +1529,8 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
* and that the attribute mask supplied is allowed for the transition.
*/
int
ib_modify_qp_is_ok
(
enum
ib_qp_state
cur_state
,
enum
ib_qp_state
next_state
,
enum
ib_qp_type
type
,
enum
ib_qp_attr_mask
mask
);
enum
ib_qp_type
type
,
enum
ib_qp_attr_mask
mask
,
enum
rdma_link_layer
ll
);
int
ib_register_event_handler
(
struct
ib_event_handler
*
event_handler
);
int
ib_unregister_event_handler
(
struct
ib_event_handler
*
event_handler
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录