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
  * @addr: local IPv6 address
                                            ifp->addr.in6_u.u6_addr32);
                        memcpy(cm_info->loc_addr, child_listen_node->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,
                                                 IRDMA_QHASH_TYPE_TCP_SYN,
                                                 IRDMA_QHASH_MANAGE_TYPE_ADD,
                                ntohl(ifa->ifa_address);
                        memcpy(cm_info->loc_addr, child_listen_node->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,
                                                 IRDMA_QHASH_TYPE_TCP_SYN,
                                                 IRDMA_QHASH_MANAGE_TYPE_ADD,
                } else {
                        cm_node->tos = max(listener->tos, cm_info->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,
                          "DCB: listener: TOS:[%d] UP:[%d]\n", cm_node->tos,
        cm_info.cm_id = cm_id;
        cm_info.qh_qpid = iwdev->vsi.ilq->qp_id;
        cm_info.tos = cm_id->tos;
-       if (iwdev->vsi.dscp_mode)
+       if (iwdev->vsi.dscp_mode) {
                cm_info.user_pri =
                        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 = 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))
                return -ENOMEM;
        cm_listen_node->tos = cm_id->tos;
        if (iwdev->vsi.dscp_mode)
                cm_listen_node->user_pri =
-                       iwdev->vsi.dscp_map[irdma_tos2dscp(cm_id->tos)];
+               iwdev->vsi.dscp_map[irdma_tos2dscp(cm_id->tos)];
        else
                cm_listen_node->user_pri = rt_tos2priority(cm_id->tos);
        cm_info.user_pri = cm_listen_node->user_pri;
                        if (err)
                                goto error;
                } 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,
                                                 IRDMA_QHASH_TYPE_TCP_SYN,
                                                 IRDMA_QHASH_MANAGE_TYPE_ADD,
 
        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
  * @ibqp: qp's pointer for modify
 
        if (attr_mask & IB_QP_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;
                u32 local_ip[4];
 
                                                   roce_info->dest_qp);
                        irdma_qp_rem_qos(&iwqp->sc_qp);
                        dev->ws_remove(iwqp->sc_qp.vsi, ctx_info->user_pri);
-                       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);
+                       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);
                }
-               sgid_attr = attr->ah_attr.grh.sgid_attr;
                ret = rdma_read_gid_l2_fields(sgid_attr, &vlan_id,
                                              ctx_info->roce_info->mac_addr);
                if (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)
                        vlan_id = 0;
                ah_info->vlan_tag = 0;
 
        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->vlan_tag |=
-                       rt_tos2priority(ah_info->tc_tos) << VLAN_PRIO_SHIFT;
        }
 
        return 0;