RDMA/irdma: Add support for DSCP
authorMustafa Ismail <mustafa.ismail@intel.com>
Wed, 2 Feb 2022 19:19:21 +0000 (13:19 -0600)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 8 Feb 2022 16:54:47 +0000 (12:54 -0400)
Add DSCP support for the Intel Ethernet 800 Series devices.  Setup VSI
DSCP info when PCI driver indicates DSCP mode during driver probe or as
notification event.

Link: https://lore.kernel.org/r/20220202191921.1638-4-shiraz.saleem@intel.com
Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/irdma/cm.c
drivers/infiniband/hw/irdma/cm.h
drivers/infiniband/hw/irdma/ctrl.c
drivers/infiniband/hw/irdma/main.c
drivers/infiniband/hw/irdma/osdep.h
drivers/infiniband/hw/irdma/type.h

index 6ff18004ecaa765fd39f2ea79bbbb4d81f46f372..abc101b5fd42665da36b5b7d943776e9fdcb2e8e 100644 (file)
@@ -2209,8 +2209,12 @@ irdma_make_cm_node(struct irdma_cm_core *cm_core, struct irdma_device *iwdev,
                        ibdev_warn(&iwdev->ibdev,
                                   "application TOS[%d] and remote client TOS[%d] mismatch\n",
                                   listener->tos, cm_info->tos);
-               cm_node->tos = max(listener->tos, cm_info->tos);
-               cm_node->user_pri = rt_tos2priority(cm_node->tos);
+               if (iwdev->vsi.dscp_mode) {
+                       cm_node->user_pri = listener->user_pri;
+               } else {
+                       cm_node->tos = max(listener->tos, cm_info->tos);
+                       cm_node->user_pri = rt_tos2priority(cm_node->tos);
+               }
                ibdev_dbg(&iwdev->ibdev,
                          "DCB: listener: TOS:[%d] UP:[%d]\n", cm_node->tos,
                          cm_node->user_pri);
@@ -3835,7 +3839,11 @@ int irdma_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        cm_info.cm_id = cm_id;
        cm_info.qh_qpid = iwdev->vsi.ilq->qp_id;
        cm_info.tos = cm_id->tos;
-       cm_info.user_pri = rt_tos2priority(cm_id->tos);
+       if (iwdev->vsi.dscp_mode)
+               cm_info.user_pri =
+                       iwqp->sc_qp.vsi->dscp_map[irdma_tos2dscp(cm_info.tos)];
+       else
+               cm_info.user_pri = rt_tos2priority(cm_id->tos);
 
        if (iwqp->sc_qp.dev->ws_add(iwqp->sc_qp.vsi, cm_info.user_pri))
                return -ENOMEM;
@@ -3977,7 +3985,11 @@ int irdma_create_listen(struct iw_cm_id *cm_id, int backlog)
        cm_id->provider_data = cm_listen_node;
 
        cm_listen_node->tos = cm_id->tos;
-       cm_listen_node->user_pri = rt_tos2priority(cm_id->tos);
+       if (iwdev->vsi.dscp_mode)
+               cm_listen_node->user_pri =
+                       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 (!cm_listen_node->reused_node) {
                if (wildcard) {
index 3bf42728e9b7b9b554a745b37714dfeb07af7c63..19c284975fc7c874cc62d1253d4b60664c1a8aa9 100644 (file)
@@ -384,6 +384,13 @@ int irdma_schedule_cm_timer(struct irdma_cm_node *cm_node,
                            struct irdma_puda_buf *sqbuf,
                            enum irdma_timer_type type, int send_retrans,
                            int close_when_complete);
+
+static inline u8 irdma_tos2dscp(u8 tos)
+{
+#define IRDMA_DSCP_VAL GENMASK(7, 2)
+       return (u8)FIELD_GET(IRDMA_DSCP_VAL, tos);
+}
+
 int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
 int irdma_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
 int irdma_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
index ef1d6ad0f1fe19b5dc99a8250e5654939914889d..94a9c26ac83ffeaa8a392589eb0031caeffb794e 100644 (file)
@@ -77,6 +77,12 @@ static void irdma_set_qos_info(struct irdma_sc_vsi  *vsi,
 
        vsi->qos_rel_bw = l2p->vsi_rel_bw;
        vsi->qos_prio_type = l2p->vsi_prio_type;
+       vsi->dscp_mode = l2p->dscp_mode;
+       if (l2p->dscp_mode) {
+               memcpy(vsi->dscp_map, l2p->dscp_map, sizeof(vsi->dscp_map));
+               for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++)
+                       l2p->up2tc[i] = i;
+       }
        for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
                if (vsi->dev->hw_attrs.uk_attrs.hw_rev == IRDMA_GEN_1)
                        vsi->qos[i].qs_handle = l2p->qs_handle_list[i];
index 179667b3e0b8c041796a6472cbc05a7e9d0fa278..97625263899fafe3732057b24ae41371a7b0ed7b 100644 (file)
@@ -79,6 +79,10 @@ static void irdma_fill_qos_info(struct irdma_l2params *l2params,
        }
        for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
                l2params->up2tc[i] = qos_info->up2tc[i];
+       if (qos_info->pfc_mode == IIDC_DSCP_PFC_MODE) {
+               l2params->dscp_mode = true;
+               memcpy(l2params->dscp_map, qos_info->dscp_map, sizeof(l2params->dscp_map));
+       }
 }
 
 static void irdma_iidc_event_handler(struct ice_pf *pf, struct iidc_event *event)
@@ -110,7 +114,7 @@ static void irdma_iidc_event_handler(struct ice_pf *pf, struct iidc_event *event
                ice_get_qos_params(pf, &qos_info);
                irdma_fill_qos_info(&l2params, &qos_info);
                if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
-                       iwdev->dcb_vlan_mode = qos_info.num_tc > 1;
+                       iwdev->dcb_vlan_mode = qos_info.num_tc > 1 && !l2params.dscp_mode;
                irdma_change_l2params(&iwdev->vsi, &l2params);
        } else if (*event->type & BIT(IIDC_EVENT_CRIT_ERR)) {
                ibdev_warn(&iwdev->ibdev, "ICE OICR event notification: oicr = 0x%08x\n",
@@ -285,7 +289,7 @@ static int irdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary_
        ice_get_qos_params(pf, &qos_info);
        irdma_fill_qos_info(&l2params, &qos_info);
        if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
-               iwdev->dcb_vlan_mode = l2params.num_tc > 1;
+               iwdev->dcb_vlan_mode = l2params.num_tc > 1 && !l2params.dscp_mode;
 
        if (irdma_rt_init_hw(iwdev, &l2params)) {
                err = -EIO;
index 63d8bb3a69037054186e1f552220314479966a9c..6e28e437b6fba1a38093b7521ac70611d1208d30 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/pci.h>
 #include <linux/bitfield.h>
+#include <linux/net/intel/iidc.h>
 #include <crypto/hash.h>
 #include <rdma/ib_verbs.h>
 
index 9483bb3e10ea1b7f355b6815cbf11859922a2522..4290a2ce810ad2bc34a935ac0d4d01dfc4ccf303 100644 (file)
@@ -611,6 +611,8 @@ struct irdma_sc_vsi {
                                struct irdma_ws_node *tc_node);
        u8 qos_rel_bw;
        u8 qos_prio_type;
+       u8 dscp_map[IIDC_MAX_DSCP_MAPPING];
+       bool dscp_mode:1;
 };
 
 struct irdma_sc_dev {
@@ -735,11 +737,13 @@ struct irdma_l2params {
        u16 qs_handle_list[IRDMA_MAX_USER_PRIORITY];
        u16 mtu;
        u8 up2tc[IRDMA_MAX_USER_PRIORITY];
+       u8 dscp_map[IIDC_MAX_DSCP_MAPPING];
        u8 num_tc;
        u8 vsi_rel_bw;
        u8 vsi_prio_type;
        bool mtu_changed:1;
        bool tc_changed:1;
+       bool dscp_mode:1;
 };
 
 struct irdma_vsi_init_info {