RDMA/irdma: Implement egress VLAN priority
When a VLAN interface is in use, get and use the VLAN egress mapping. Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com> Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com> Link: https://lore.kernel.org/r/20230711175318.1301-1-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
parent
65e02e8408
commit
f877f22ac1
2 changed files with 99 additions and 12 deletions
|
@ -1555,6 +1555,41 @@ static int irdma_del_multiple_qhash(struct irdma_device *iwdev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 irdma_iw_get_vlan_prio(u32 *loc_addr, u8 prio, bool ipv4)
|
||||||
|
{
|
||||||
|
struct net_device *ndev = NULL;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
if (ipv4) {
|
||||||
|
ndev = ip_dev_find(&init_net, htonl(loc_addr[0]));
|
||||||
|
} else {
|
||||||
|
struct net_device *ip_dev;
|
||||||
|
struct in6_addr laddr6;
|
||||||
|
|
||||||
|
irdma_copy_ip_htonl(laddr6.in6_u.u6_addr32, loc_addr);
|
||||||
|
|
||||||
|
for_each_netdev_rcu (&init_net, ip_dev) {
|
||||||
|
if (ipv6_chk_addr(&init_net, &laddr6, ip_dev, 1)) {
|
||||||
|
ndev = ip_dev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ndev)
|
||||||
|
goto done;
|
||||||
|
if (is_vlan_dev(ndev))
|
||||||
|
prio = (vlan_dev_get_egress_qos_mask(ndev, prio) & VLAN_PRIO_MASK)
|
||||||
|
>> VLAN_PRIO_SHIFT;
|
||||||
|
if (ipv4)
|
||||||
|
dev_put(ndev);
|
||||||
|
|
||||||
|
done:
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
return prio;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* irdma_netdev_vlan_ipv6 - Gets the netdev and mac
|
* irdma_netdev_vlan_ipv6 - Gets the netdev and mac
|
||||||
* @addr: local IPv6 address
|
* @addr: local IPv6 address
|
||||||
|
@ -1667,6 +1702,12 @@ static int irdma_add_mqh_6(struct irdma_device *iwdev,
|
||||||
ifp->addr.in6_u.u6_addr32);
|
ifp->addr.in6_u.u6_addr32);
|
||||||
memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
|
memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
|
||||||
sizeof(cm_info->loc_addr));
|
sizeof(cm_info->loc_addr));
|
||||||
|
if (!iwdev->vsi.dscp_mode)
|
||||||
|
cm_info->user_pri =
|
||||||
|
irdma_iw_get_vlan_prio(child_listen_node->loc_addr,
|
||||||
|
cm_info->user_pri,
|
||||||
|
false);
|
||||||
|
|
||||||
ret = irdma_manage_qhash(iwdev, cm_info,
|
ret = irdma_manage_qhash(iwdev, cm_info,
|
||||||
IRDMA_QHASH_TYPE_TCP_SYN,
|
IRDMA_QHASH_TYPE_TCP_SYN,
|
||||||
IRDMA_QHASH_MANAGE_TYPE_ADD,
|
IRDMA_QHASH_MANAGE_TYPE_ADD,
|
||||||
|
@ -1751,6 +1792,11 @@ static int irdma_add_mqh_4(struct irdma_device *iwdev,
|
||||||
ntohl(ifa->ifa_address);
|
ntohl(ifa->ifa_address);
|
||||||
memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
|
memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
|
||||||
sizeof(cm_info->loc_addr));
|
sizeof(cm_info->loc_addr));
|
||||||
|
if (!iwdev->vsi.dscp_mode)
|
||||||
|
cm_info->user_pri =
|
||||||
|
irdma_iw_get_vlan_prio(child_listen_node->loc_addr,
|
||||||
|
cm_info->user_pri,
|
||||||
|
true);
|
||||||
ret = irdma_manage_qhash(iwdev, cm_info,
|
ret = irdma_manage_qhash(iwdev, cm_info,
|
||||||
IRDMA_QHASH_TYPE_TCP_SYN,
|
IRDMA_QHASH_TYPE_TCP_SYN,
|
||||||
IRDMA_QHASH_MANAGE_TYPE_ADD,
|
IRDMA_QHASH_MANAGE_TYPE_ADD,
|
||||||
|
@ -2219,6 +2265,10 @@ irdma_make_cm_node(struct irdma_cm_core *cm_core, struct irdma_device *iwdev,
|
||||||
} else {
|
} else {
|
||||||
cm_node->tos = max(listener->tos, cm_info->tos);
|
cm_node->tos = max(listener->tos, cm_info->tos);
|
||||||
cm_node->user_pri = rt_tos2priority(cm_node->tos);
|
cm_node->user_pri = rt_tos2priority(cm_node->tos);
|
||||||
|
cm_node->user_pri =
|
||||||
|
irdma_iw_get_vlan_prio(cm_info->loc_addr,
|
||||||
|
cm_node->user_pri,
|
||||||
|
cm_info->ipv4);
|
||||||
}
|
}
|
||||||
ibdev_dbg(&iwdev->ibdev,
|
ibdev_dbg(&iwdev->ibdev,
|
||||||
"DCB: listener: TOS:[%d] UP:[%d]\n", cm_node->tos,
|
"DCB: listener: TOS:[%d] UP:[%d]\n", cm_node->tos,
|
||||||
|
@ -3832,11 +3882,15 @@ int irdma_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
||||||
cm_info.cm_id = cm_id;
|
cm_info.cm_id = cm_id;
|
||||||
cm_info.qh_qpid = iwdev->vsi.ilq->qp_id;
|
cm_info.qh_qpid = iwdev->vsi.ilq->qp_id;
|
||||||
cm_info.tos = cm_id->tos;
|
cm_info.tos = cm_id->tos;
|
||||||
if (iwdev->vsi.dscp_mode)
|
if (iwdev->vsi.dscp_mode) {
|
||||||
cm_info.user_pri =
|
cm_info.user_pri =
|
||||||
iwqp->sc_qp.vsi->dscp_map[irdma_tos2dscp(cm_info.tos)];
|
iwqp->sc_qp.vsi->dscp_map[irdma_tos2dscp(cm_info.tos)];
|
||||||
else
|
} else {
|
||||||
cm_info.user_pri = rt_tos2priority(cm_id->tos);
|
cm_info.user_pri = rt_tos2priority(cm_id->tos);
|
||||||
|
cm_info.user_pri = irdma_iw_get_vlan_prio(cm_info.loc_addr,
|
||||||
|
cm_info.user_pri,
|
||||||
|
cm_info.ipv4);
|
||||||
|
}
|
||||||
|
|
||||||
if (iwqp->sc_qp.dev->ws_add(iwqp->sc_qp.vsi, cm_info.user_pri))
|
if (iwqp->sc_qp.dev->ws_add(iwqp->sc_qp.vsi, cm_info.user_pri))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -3990,6 +4044,12 @@ int irdma_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
|
if (!iwdev->vsi.dscp_mode)
|
||||||
|
cm_listen_node->user_pri =
|
||||||
|
irdma_iw_get_vlan_prio(cm_info.loc_addr,
|
||||||
|
cm_info.user_pri,
|
||||||
|
cm_info.ipv4);
|
||||||
|
cm_info.user_pri = cm_listen_node->user_pri;
|
||||||
err = irdma_manage_qhash(iwdev, &cm_info,
|
err = irdma_manage_qhash(iwdev, &cm_info,
|
||||||
IRDMA_QHASH_TYPE_TCP_SYN,
|
IRDMA_QHASH_TYPE_TCP_SYN,
|
||||||
IRDMA_QHASH_MANAGE_TYPE_ADD,
|
IRDMA_QHASH_MANAGE_TYPE_ADD,
|
||||||
|
|
|
@ -1098,6 +1098,24 @@ static int irdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 irdma_roce_get_vlan_prio(const struct ib_gid_attr *attr, u8 prio)
|
||||||
|
{
|
||||||
|
struct net_device *ndev;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
ndev = rcu_dereference(attr->ndev);
|
||||||
|
if (!ndev)
|
||||||
|
goto exit;
|
||||||
|
if (is_vlan_dev(ndev)) {
|
||||||
|
u16 vlan_qos = vlan_dev_get_egress_qos_mask(ndev, prio);
|
||||||
|
|
||||||
|
prio = (vlan_qos & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
rcu_read_unlock();
|
||||||
|
return prio;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* irdma_modify_qp_roce - modify qp request
|
* irdma_modify_qp_roce - modify qp request
|
||||||
* @ibqp: qp's pointer for modify
|
* @ibqp: qp's pointer for modify
|
||||||
|
@ -1174,7 +1192,8 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||||
|
|
||||||
if (attr_mask & IB_QP_AV) {
|
if (attr_mask & IB_QP_AV) {
|
||||||
struct irdma_av *av = &iwqp->roce_ah.av;
|
struct irdma_av *av = &iwqp->roce_ah.av;
|
||||||
const struct ib_gid_attr *sgid_attr;
|
const struct ib_gid_attr *sgid_attr =
|
||||||
|
attr->ah_attr.grh.sgid_attr;
|
||||||
u16 vlan_id = VLAN_N_VID;
|
u16 vlan_id = VLAN_N_VID;
|
||||||
u32 local_ip[4];
|
u32 local_ip[4];
|
||||||
|
|
||||||
|
@ -1189,17 +1208,22 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||||
roce_info->dest_qp);
|
roce_info->dest_qp);
|
||||||
irdma_qp_rem_qos(&iwqp->sc_qp);
|
irdma_qp_rem_qos(&iwqp->sc_qp);
|
||||||
dev->ws_remove(iwqp->sc_qp.vsi, ctx_info->user_pri);
|
dev->ws_remove(iwqp->sc_qp.vsi, ctx_info->user_pri);
|
||||||
|
if (iwqp->sc_qp.vsi->dscp_mode)
|
||||||
|
ctx_info->user_pri =
|
||||||
|
iwqp->sc_qp.vsi->dscp_map[irdma_tos2dscp(udp_info->tos)];
|
||||||
|
else
|
||||||
ctx_info->user_pri = rt_tos2priority(udp_info->tos);
|
ctx_info->user_pri = rt_tos2priority(udp_info->tos);
|
||||||
iwqp->sc_qp.user_pri = ctx_info->user_pri;
|
|
||||||
if (dev->ws_add(iwqp->sc_qp.vsi, ctx_info->user_pri))
|
|
||||||
return -ENOMEM;
|
|
||||||
irdma_qp_add_qos(&iwqp->sc_qp);
|
|
||||||
}
|
}
|
||||||
sgid_attr = attr->ah_attr.grh.sgid_attr;
|
|
||||||
ret = rdma_read_gid_l2_fields(sgid_attr, &vlan_id,
|
ret = rdma_read_gid_l2_fields(sgid_attr, &vlan_id,
|
||||||
ctx_info->roce_info->mac_addr);
|
ctx_info->roce_info->mac_addr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
ctx_info->user_pri = irdma_roce_get_vlan_prio(sgid_attr,
|
||||||
|
ctx_info->user_pri);
|
||||||
|
if (dev->ws_add(iwqp->sc_qp.vsi, ctx_info->user_pri))
|
||||||
|
return -ENOMEM;
|
||||||
|
iwqp->sc_qp.user_pri = ctx_info->user_pri;
|
||||||
|
irdma_qp_add_qos(&iwqp->sc_qp);
|
||||||
|
|
||||||
if (vlan_id >= VLAN_N_VID && iwdev->dcb_vlan_mode)
|
if (vlan_id >= VLAN_N_VID && iwdev->dcb_vlan_mode)
|
||||||
vlan_id = 0;
|
vlan_id = 0;
|
||||||
|
@ -4261,9 +4285,12 @@ static int irdma_setup_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *attr)
|
||||||
ah_info->vlan_tag = 0;
|
ah_info->vlan_tag = 0;
|
||||||
|
|
||||||
if (ah_info->vlan_tag < VLAN_N_VID) {
|
if (ah_info->vlan_tag < VLAN_N_VID) {
|
||||||
|
u8 prio = rt_tos2priority(ah_info->tc_tos);
|
||||||
|
|
||||||
|
prio = irdma_roce_get_vlan_prio(sgid_attr, prio);
|
||||||
|
|
||||||
|
ah_info->vlan_tag |= (u16)prio << VLAN_PRIO_SHIFT;
|
||||||
ah_info->insert_vlan_tag = true;
|
ah_info->insert_vlan_tag = true;
|
||||||
ah_info->vlan_tag |=
|
|
||||||
rt_tos2priority(ah_info->tc_tos) << VLAN_PRIO_SHIFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue