net/ice/base: support L3 DSCP QoS
authorQi Zhang <qi.z.zhang@intel.com>
Thu, 29 Apr 2021 00:41:41 +0000 (08:41 +0800)
committerQi Zhang <qi.z.zhang@intel.com>
Fri, 30 Apr 2021 13:47:50 +0000 (15:47 +0200)
The base code support to build configuration TLVs
in DSCP mode has not been implemented before, so
the functions to do so and the flow control to determine
if we are in VLAN or DSCP mode need to be added.

The current value for maximum number of DCB APPs
(ICE_DCBX_MAX_APPS) is not sufficient when supporting
DSCP mode.  Each DSCP->TC mapping will come in as a
single APP value.  So, there can be up to 64 APPs for
DSCP mapping.

Need to keep track of the current DSCP to TC mapping
so that TLVs can be built up to send to the FW.  Add
an u8 array to hold this info.

A u64 is also needed to keep track of the DSCP values
that have had an APP submitted to map its value to a
TC.  Since it would be unwise to allow an APP to be
overwritten by subsequent APPs, reject mappings for a
DSCP value that already has a user mapped value.  This
will allow us to easily track which DSCP values have
been mapped, and when the last one has been deleted.

Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
drivers/net/ice/base/ice_dcb.c
drivers/net/ice/base/ice_dcb.h
drivers/net/ice/base/ice_type.h

index d5e2cb6..0aaa5ae 100644 (file)
@@ -1207,7 +1207,140 @@ ice_add_ieee_app_pri_tlv(struct ice_lldp_org_tlv *tlv,
 }
 
 /**
- * ice_add_dcb_tlv - Add all IEEE TLVs
+ * ice_add_dscp_up_tlv - Prepare DSCP to UP TLV
+ * @tlv: location to build the TLV data
+ * @dcbcfg: location of data to convert to TLV
+ */
+static void
+ice_add_dscp_up_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
+{
+       u8 *buf = tlv->tlvinfo;
+       u32 ouisubtype;
+       u16 typelen;
+       int i;
+
+       typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
+                  ICE_DSCP_UP_TLV_LEN);
+       tlv->typelen = HTONS(typelen);
+
+       ouisubtype = (u32)((ICE_DSCP_OUI << ICE_LLDP_TLV_OUI_S) |
+                          ICE_DSCP_SUBTYPE_DSCP2UP);
+       tlv->ouisubtype = HTONL(ouisubtype);
+
+       /* bytes 0 - 63 - IPv4 DSCP2UP LUT */
+       for (i = 0; i < ICE_DSCP_NUM_VAL; i++) {
+               /* IPv4 mapping */
+               buf[i] = dcbcfg->dscp_map[i];
+               /* IPv6 mapping */
+               buf[i + ICE_DSCP_IPV6_OFFSET] = dcbcfg->dscp_map[i];
+       }
+
+       /* byte 64 - IPv4 untagged traffic */
+       buf[i] = 0;
+
+       /* byte 144 - IPv6 untagged traffic */
+       buf[i + ICE_DSCP_IPV6_OFFSET] = 0;
+}
+
+#define ICE_BYTES_PER_TC       8
+/**
+ * ice_add_dscp_enf_tlv - Prepare DSCP Enforcement TLV
+ * @tlv: location to build the TLV data
+ */
+static void
+ice_add_dscp_enf_tlv(struct ice_lldp_org_tlv *tlv)
+{
+       u8 *buf = tlv->tlvinfo;
+       u32 ouisubtype;
+       u16 typelen;
+
+       typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
+                  ICE_DSCP_ENF_TLV_LEN);
+       tlv->typelen = HTONS(typelen);
+
+       ouisubtype = (u32)((ICE_DSCP_OUI << ICE_LLDP_TLV_OUI_S) |
+                          ICE_DSCP_SUBTYPE_ENFORCE);
+       tlv->ouisubtype = HTONL(ouisubtype);
+
+       /* Allow all DSCP values to be valid for all TC's (IPv4 and IPv6) */
+       memset(buf, 0, 2 * (ICE_MAX_TRAFFIC_CLASS * ICE_BYTES_PER_TC));
+}
+
+/**
+ * ice_add_dscp_tc_bw_tlv - Prepare DSCP BW for TC TLV
+ * @tlv: location to build the TLV data
+ * @dcbcfg: location of the data to convert to TLV
+ */
+static void
+ice_add_dscp_tc_bw_tlv(struct ice_lldp_org_tlv *tlv,
+                      struct ice_dcbx_cfg *dcbcfg)
+{
+       struct ice_dcb_ets_cfg *etscfg;
+       u8 *buf = tlv->tlvinfo;
+       u32 ouisubtype;
+       u8 offset = 0;
+       u16 typelen;
+       int i;
+
+       typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
+                  ICE_DSCP_TC_BW_TLV_LEN);
+       tlv->typelen = HTONS(typelen);
+
+       ouisubtype = (u32)((ICE_DSCP_OUI << ICE_LLDP_TLV_OUI_S) |
+                          ICE_DSCP_SUBTYPE_TCBW);
+       tlv->ouisubtype = HTONL(ouisubtype);
+
+       /* First Octet after subtype
+        * ----------------------------
+        * | RSV | CBS | RSV | Max TCs |
+        * | 1b  | 1b  | 3b  | 3b      |
+        * ----------------------------
+        */
+       etscfg = &dcbcfg->etscfg;
+       buf[0] = etscfg->maxtcs & ICE_IEEE_ETS_MAXTC_M;
+
+       /* bytes 1 - 4 reserved */
+       offset = 5;
+
+       /* TC BW table
+        * bytes 0 - 7 for TC 0 - 7
+        *
+        * TSA Assignment table
+        * bytes 8 - 15 for TC 0 - 7
+        */
+       for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
+               buf[offset] = etscfg->tcbwtable[i];
+               buf[offset + ICE_MAX_TRAFFIC_CLASS] = etscfg->tsatable[i];
+               offset++;
+       }
+}
+
+/**
+ * ice_add_dscp_pfc_tlv - Prepare DSCP PFC TLV
+ * @tlv: Fill PFC TLV in IEEE format
+ * @dcbcfg: Local store which holds the PFC CFG data
+ */
+static void
+ice_add_dscp_pfc_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
+{
+       u8 *buf = tlv->tlvinfo;
+       u32 ouisubtype;
+       u16 typelen;
+
+       typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
+                  ICE_DSCP_PFC_TLV_LEN);
+       tlv->typelen = HTONS(typelen);
+
+       ouisubtype = (u32)((ICE_DSCP_OUI << ICE_LLDP_TLV_OUI_S) |
+                          ICE_DSCP_SUBTYPE_PFC);
+       tlv->ouisubtype = HTONL(ouisubtype);
+
+       buf[0] = dcbcfg->pfc.pfccap & 0xF;
+       buf[1] = dcbcfg->pfc.pfcena & 0xF;
+}
+
+/**
+ * ice_add_dcb_tlv - Add all IEEE or DSCP TLVs
  * @tlv: Fill TLV data in IEEE format
  * @dcbcfg: Local store which holds the DCB Config
  * @tlvid: Type of IEEE TLV
@@ -1218,21 +1351,41 @@ static void
 ice_add_dcb_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg,
                u16 tlvid)
 {
-       switch (tlvid) {
-       case ICE_IEEE_TLV_ID_ETS_CFG:
-               ice_add_ieee_ets_tlv(tlv, dcbcfg);
-               break;
-       case ICE_IEEE_TLV_ID_ETS_REC:
-               ice_add_ieee_etsrec_tlv(tlv, dcbcfg);
-               break;
-       case ICE_IEEE_TLV_ID_PFC_CFG:
-               ice_add_ieee_pfc_tlv(tlv, dcbcfg);
-               break;
-       case ICE_IEEE_TLV_ID_APP_PRI:
-               ice_add_ieee_app_pri_tlv(tlv, dcbcfg);
-               break;
-       default:
-               break;
+       if (dcbcfg->pfc_mode == ICE_QOS_MODE_VLAN) {
+               switch (tlvid) {
+               case ICE_IEEE_TLV_ID_ETS_CFG:
+                       ice_add_ieee_ets_tlv(tlv, dcbcfg);
+                       break;
+               case ICE_IEEE_TLV_ID_ETS_REC:
+                       ice_add_ieee_etsrec_tlv(tlv, dcbcfg);
+                       break;
+               case ICE_IEEE_TLV_ID_PFC_CFG:
+                       ice_add_ieee_pfc_tlv(tlv, dcbcfg);
+                       break;
+               case ICE_IEEE_TLV_ID_APP_PRI:
+                       ice_add_ieee_app_pri_tlv(tlv, dcbcfg);
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               /* pfc_mode == ICE_QOS_MODE_DSCP */
+               switch (tlvid) {
+               case ICE_TLV_ID_DSCP_UP:
+                       ice_add_dscp_up_tlv(tlv, dcbcfg);
+                       break;
+               case ICE_TLV_ID_DSCP_ENF:
+                       ice_add_dscp_enf_tlv(tlv);
+                       break;
+               case ICE_TLV_ID_DSCP_TC_BW:
+                       ice_add_dscp_tc_bw_tlv(tlv, dcbcfg);
+                       break;
+               case ICE_TLV_ID_DSCP_TO_PFC:
+                       ice_add_dscp_pfc_tlv(tlv, dcbcfg);
+                       break;
+               default:
+                       break;
+               }
        }
 }
 
index 6582119..a053adb 100644 (file)
 #define ICE_CEE_DCBX_OUI               0x001B21
 #define ICE_CEE_DCBX_TYPE              2
 
+#define ICE_DSCP_OUI                   0xFFFFFF
+#define ICE_DSCP_SUBTYPE_DSCP2UP       0x41
+#define ICE_DSCP_SUBTYPE_ENFORCE       0x42
+#define ICE_DSCP_SUBTYPE_TCBW          0x43
+#define ICE_DSCP_SUBTYPE_PFC           0x44
+#define ICE_DSCP_IPV6_OFFSET           80
+
 #define ICE_CEE_SUBTYPE_CTRL           1
 #define ICE_CEE_SUBTYPE_PG_CFG         2
 #define ICE_CEE_SUBTYPE_PFC_CFG                3
 #define ICE_IEEE_TLV_ID_APP_PRI                6
 #define ICE_TLV_ID_END_OF_LLDPPDU      7
 #define ICE_TLV_ID_START               ICE_IEEE_TLV_ID_ETS_CFG
+#define ICE_TLV_ID_DSCP_UP             3
+#define ICE_TLV_ID_DSCP_ENF            4
+#define ICE_TLV_ID_DSCP_TC_BW          5
+#define ICE_TLV_ID_DSCP_TO_PFC         6
 
 #define ICE_IEEE_ETS_TLV_LEN           25
 #define ICE_IEEE_PFC_TLV_LEN           6
 #define ICE_IEEE_APP_TLV_LEN           11
 
+#define ICE_DSCP_UP_TLV_LEN            148
+#define ICE_DSCP_ENF_TLV_LEN           132
+#define ICE_DSCP_TC_BW_TLV_LEN         25
+#define ICE_DSCP_PFC_TLV_LEN           6
+
 #pragma pack(1)
 /* IEEE 802.1AB LLDP Organization specific TLV */
 struct ice_lldp_org_tlv {
index 3c534a7..637dd30 100644 (file)
@@ -797,7 +797,8 @@ struct ice_dcb_app_priority_table {
 };
 
 #define ICE_MAX_USER_PRIORITY          8
-#define ICE_DCBX_MAX_APPS              32
+#define ICE_DCBX_MAX_APPS              64
+#define ICE_DSCP_NUM_VAL               64
 #define ICE_LLDPDU_SIZE                        1500
 #define ICE_TLV_STATUS_OPER            0x1
 #define ICE_TLV_STATUS_SYNC            0x2
@@ -817,7 +818,14 @@ struct ice_dcbx_cfg {
        struct ice_dcb_ets_cfg etscfg;
        struct ice_dcb_ets_cfg etsrec;
        struct ice_dcb_pfc_cfg pfc;
+#define ICE_QOS_MODE_VLAN      0x0
+#define ICE_QOS_MODE_DSCP      0x1
+       u8 pfc_mode;
        struct ice_dcb_app_priority_table app[ICE_DCBX_MAX_APPS];
+       /* when DSCP mapping defined by user set its bit to 1 */
+       ice_declare_bitmap(dscp_mapped, ICE_DSCP_NUM_VAL);
+       /* array holding DSCP -> UP/TC values for DSCP L3 QoS mode */
+       u8 dscp_map[ICE_DSCP_NUM_VAL];
        u8 dcbx_mode;
 #define ICE_DCBX_MODE_CEE      0x1
 #define ICE_DCBX_MODE_IEEE     0x2