[link-quality] define `LinkQuality` enumeration (#7673)

This commit adds `LinkQuality` enumeration which represents the
2-bit [0-3] link quality value
diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp
index e9c30a3..ff5922d 100644
--- a/src/core/api/link_api.cpp
+++ b/src/core/api/link_api.cpp
@@ -288,7 +288,7 @@
 int8_t otLinkConvertLinkQualityToRss(otInstance *aInstance, uint8_t aLinkQuality)
 {
     return LinkQualityInfo::ConvertLinkQualityToRss(AsCoreType(aInstance).Get<Mac::Mac>().GetNoiseFloor(),
-                                                    aLinkQuality);
+                                                    static_cast<LinkQuality>(aLinkQuality));
 }
 
 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
diff --git a/src/core/thread/link_quality.cpp b/src/core/thread/link_quality.cpp
index c16d114..f3e1cb2 100644
--- a/src/core/thread/link_quality.cpp
+++ b/src/core/thread/link_quality.cpp
@@ -131,7 +131,7 @@
 void LinkQualityInfo::Clear(void)
 {
     mRssAverager.Clear();
-    SetLinkQuality(0);
+    SetLinkQuality(kLinkQuality0);
     mLastRss = OT_RADIO_RSSI_INVALID;
 
     mFrameErrorRate.Clear();
@@ -186,31 +186,31 @@
     return static_cast<uint8_t>(linkMargin);
 }
 
-uint8_t LinkQualityInfo::ConvertLinkMarginToLinkQuality(uint8_t aLinkMargin)
+LinkQuality LinkQualityInfo::ConvertLinkMarginToLinkQuality(uint8_t aLinkMargin)
 {
     return CalculateLinkQuality(aLinkMargin, kNoLinkQuality);
 }
 
-uint8_t LinkQualityInfo::ConvertRssToLinkQuality(int8_t aNoiseFloor, int8_t aRss)
+LinkQuality LinkQualityInfo::ConvertRssToLinkQuality(int8_t aNoiseFloor, int8_t aRss)
 {
     return ConvertLinkMarginToLinkQuality(ConvertRssToLinkMargin(aNoiseFloor, aRss));
 }
 
-int8_t LinkQualityInfo::ConvertLinkQualityToRss(int8_t aNoiseFloor, uint8_t aLinkQuality)
+int8_t LinkQualityInfo::ConvertLinkQualityToRss(int8_t aNoiseFloor, LinkQuality aLinkQuality)
 {
     int8_t linkmargin = 0;
 
     switch (aLinkQuality)
     {
-    case 3:
+    case kLinkQuality3:
         linkmargin = kLinkQuality3LinkMargin;
         break;
 
-    case 2:
+    case kLinkQuality2:
         linkmargin = kLinkQuality2LinkMargin;
         break;
 
-    case 1:
+    case kLinkQuality1:
         linkmargin = kLinkQuality1LinkMargin;
         break;
 
@@ -222,7 +222,7 @@
     return linkmargin + aNoiseFloor;
 }
 
-uint8_t LinkQualityInfo::CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLastLinkQuality)
+LinkQuality LinkQualityInfo::CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLastLinkQuality)
 {
     // Static private method to calculate the link quality from a given
     // link margin while taking into account the last link quality
@@ -230,8 +230,8 @@
     // there is no previous value for link quality, the constant
     // kNoLinkQuality should be passed as the second argument.
 
-    uint8_t threshold1, threshold2, threshold3;
-    uint8_t linkQuality = 0;
+    uint8_t     threshold1, threshold2, threshold3;
+    LinkQuality linkQuality = kLinkQuality0;
 
     threshold1 = kThreshold1;
     threshold2 = kThreshold2;
@@ -262,15 +262,15 @@
 
     if (aLinkMargin > threshold3)
     {
-        linkQuality = 3;
+        linkQuality = kLinkQuality3;
     }
     else if (aLinkMargin > threshold2)
     {
-        linkQuality = 2;
+        linkQuality = kLinkQuality2;
     }
     else if (aLinkMargin > threshold1)
     {
-        linkQuality = 1;
+        linkQuality = kLinkQuality1;
     }
 
     return linkQuality;
diff --git a/src/core/thread/link_quality.hpp b/src/core/thread/link_quality.hpp
index a7d34e9..bc10957 100644
--- a/src/core/thread/link_quality.hpp
+++ b/src/core/thread/link_quality.hpp
@@ -227,6 +227,21 @@
 };
 
 /**
+ * This enumeration represents the link quality constants.
+ *
+ * Link Quality is an integer in [0, 3]. A higher link quality indicates a more usable link, with 0 indicating that the
+ * link is non-existent or unusable.
+ *
+ */
+enum LinkQuality : uint8_t
+{
+    kLinkQuality0 = 0, ///< Link quality 0 (non-existent link)
+    kLinkQuality1 = 1, ///< Link quality 1
+    kLinkQuality2 = 2, ///< Link quality 2
+    kLinkQuality3 = 3, ///< Link quality 3
+};
+
+/**
  * This class encapsulates/stores all relevant information about quality of a link, including average received signal
  * strength (RSS), last RSS, link margin, and link quality.
  *
@@ -312,7 +327,7 @@
      * @returns The current link quality value (value 0-3 as per Thread specification).
      *
      */
-    uint8_t GetLinkQuality(void) const { return mLinkQuality; }
+    LinkQuality GetLinkQuality(void) const { return mLinkQuality; }
 
     /**
      * Returns the most recent RSS value.
@@ -391,7 +406,7 @@
      * @returns The link quality value (0-3).
      *
      */
-    static uint8_t ConvertLinkMarginToLinkQuality(uint8_t aLinkMargin);
+    static LinkQuality ConvertLinkMarginToLinkQuality(uint8_t aLinkMargin);
 
     /**
      * This method converts a received signal strength value to a link quality value.
@@ -402,7 +417,7 @@
      * @returns The link quality value (0-3).
      *
      */
-    static uint8_t ConvertRssToLinkQuality(int8_t aNoiseFloor, int8_t aRss);
+    static LinkQuality ConvertRssToLinkQuality(int8_t aNoiseFloor, int8_t aRss);
 
     /**
      * This method converts a link quality value to a typical received signal strength value.
@@ -415,7 +430,7 @@
      * @returns The typical platform RSSI.
      *
      */
-    static int8_t ConvertLinkQualityToRss(int8_t aNoiseFloor, uint8_t aLinkQuality);
+    static int8_t ConvertLinkQualityToRss(int8_t aNoiseFloor, LinkQuality aLinkQuality);
 
 private:
     // Constants for obtaining link quality from link margin:
@@ -432,12 +447,12 @@
 
     static constexpr uint8_t kNoLinkQuality = 0xff; // Indicate that there is no previous/last link quality.
 
-    void SetLinkQuality(uint8_t aLinkQuality) { mLinkQuality = aLinkQuality; }
+    void SetLinkQuality(LinkQuality aLinkQuality) { mLinkQuality = aLinkQuality; }
 
-    static uint8_t CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLastLinkQuality);
+    static LinkQuality CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLastLinkQuality);
 
     RssAverager mRssAverager;
-    uint8_t     mLinkQuality;
+    LinkQuality mLinkQuality;
     int8_t      mLastRss;
 
     SuccessRateTracker mFrameErrorRate;
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index 3e5c3c0..831ef87 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -1769,8 +1769,8 @@
 
 bool Mle::HasAcceptableParentCandidate(void) const
 {
-    bool    hasAcceptableParent = false;
-    uint8_t linkQuality;
+    bool        hasAcceptableParent = false;
+    LinkQuality linkQuality;
 
     VerifyOrExit(mParentCandidate.IsStateParentResponse());
 
@@ -1786,7 +1786,7 @@
         // candidate and forward to REED stage to potentially find a
         // better parent.
         linkQuality = OT_MIN(mParentCandidate.GetLinkInfo().GetLinkQuality(), mParentCandidate.GetLinkQualityOut());
-        VerifyOrExit(linkQuality == 3);
+        VerifyOrExit(linkQuality == kLinkQuality3);
         break;
 
     case kAttachStateParentRequestReed:
@@ -3398,7 +3398,7 @@
 }
 
 bool Mle::IsBetterParent(uint16_t               aRloc16,
-                         uint8_t                aLinkQuality,
+                         LinkQuality            aLinkQuality,
                          uint8_t                aLinkMargin,
                          const ConnectivityTlv &aConnectivityTlv,
                          uint8_t                aVersion,
@@ -3407,10 +3407,8 @@
 {
     bool rval = false;
 
-    uint8_t candidateLinkQualityIn     = mParentCandidate.GetLinkInfo().GetLinkQuality();
-    uint8_t candidateTwoWayLinkQuality = (candidateLinkQualityIn < mParentCandidate.GetLinkQualityOut())
-                                             ? candidateLinkQualityIn
-                                             : mParentCandidate.GetLinkQualityOut();
+    LinkQuality candidateLinkQualityIn     = mParentCandidate.GetLinkInfo().GetLinkQuality();
+    LinkQuality candidateTwoWayLinkQuality = OT_MIN(candidateLinkQualityIn, mParentCandidate.GetLinkQualityOut());
 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
     uint64_t candidateCslMetric = 0;
     uint64_t cslMetric          = 0;
@@ -3498,7 +3496,7 @@
     LeaderData            leaderData;
     uint8_t               linkMarginFromTlv;
     uint8_t               linkMargin;
-    uint8_t               linkQuality;
+    LinkQuality           linkQuality;
     ConnectivityTlv       connectivity;
     uint32_t              linkFrameCounter;
     uint32_t              mleFrameCounter;
diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp
index 56c03d9..b5a24d6 100644
--- a/src/core/thread/mle.hpp
+++ b/src/core/thread/mle.hpp
@@ -1811,7 +1811,7 @@
     bool     HasAcceptableParentCandidate(void) const;
 
     bool IsBetterParent(uint16_t               aRloc16,
-                        uint8_t                aLinkQuality,
+                        LinkQuality            aLinkQuality,
                         uint8_t                aLinkMargin,
                         const ConnectivityTlv &aConnectivityTlv,
                         uint8_t                aVersion,
diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp
index 42446ee..bde4042 100644
--- a/src/core/thread/mle_router.cpp
+++ b/src/core/thread/mle_router.cpp
@@ -1602,12 +1602,12 @@
 
 bool MleRouter::UpdateLinkQualityOut(const RouteTlv &aRoute, Router &aNeighbor, bool &aResetAdvInterval)
 {
-    bool    changed = false;
-    uint8_t linkQuality;
-    uint8_t myRouterId;
-    uint8_t myRouteCount;
-    uint8_t oldLinkCost;
-    Router *nextHop;
+    bool        changed = false;
+    LinkQuality linkQuality;
+    uint8_t     myRouterId;
+    uint8_t     myRouteCount;
+    uint8_t     oldLinkCost;
+    Router *    nextHop;
 
     myRouterId = RouterIdFromRloc16(GetRloc16());
     VerifyOrExit(aRoute.IsRouterIdSet(myRouterId));
@@ -4017,15 +4017,18 @@
     case kRoleChild:
         switch (mParent.GetLinkInfo().GetLinkQuality())
         {
-        case 1:
+        case kLinkQuality0:
+            break;
+
+        case kLinkQuality1:
             aTlv.SetLinkQuality1(aTlv.GetLinkQuality1() + 1);
             break;
 
-        case 2:
+        case kLinkQuality2:
             aTlv.SetLinkQuality2(aTlv.GetLinkQuality2() + 1);
             break;
 
-        case 3:
+        case kLinkQuality3:
             aTlv.SetLinkQuality3(aTlv.GetLinkQuality3() + 1);
             break;
         }
@@ -4055,7 +4058,7 @@
 
     for (Router &router : Get<RouterTable>().Iterate())
     {
-        uint8_t linkQuality;
+        LinkQuality linkQuality;
 
         if (router.GetRloc16() == GetRloc16())
         {
@@ -4078,15 +4081,18 @@
 
         switch (linkQuality)
         {
-        case 1:
+        case kLinkQuality0:
+            break;
+
+        case kLinkQuality1:
             aTlv.SetLinkQuality1(aTlv.GetLinkQuality1() + 1);
             break;
 
-        case 2:
+        case kLinkQuality2:
             aTlv.SetLinkQuality2(aTlv.GetLinkQuality2() + 1);
             break;
 
-        case 3:
+        case kLinkQuality3:
             aTlv.SetLinkQuality3(aTlv.GetLinkQuality3() + 1);
             break;
         }
@@ -4208,8 +4214,8 @@
 
         if (router.GetRloc16() == GetRloc16())
         {
-            aTlv.SetLinkQualityIn(routerCount, 0);
-            aTlv.SetLinkQualityOut(routerCount, 0);
+            aTlv.SetLinkQualityIn(routerCount, kLinkQuality0);
+            aTlv.SetLinkQualityOut(routerCount, kLinkQuality0);
             aTlv.SetRouteCost(routerCount, 1);
         }
         else
diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp
index 25934be..4b1dd67 100644
--- a/src/core/thread/mle_tlvs.hpp
+++ b/src/core/thread/mle_tlvs.hpp
@@ -360,9 +360,9 @@
      * @returns The Link Quality In value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityIn(uint8_t aRouterIndex) const
+    LinkQuality GetLinkQualityIn(uint8_t aRouterIndex) const
     {
-        return (mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset;
+        return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset);
     }
 
     /**
@@ -372,7 +372,7 @@
      * @param[in]  aLinkQuality  The Link Quality In value for a given Router index.
      *
      */
-    void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality)
+    void SetLinkQualityIn(uint8_t aRouterIndex, LinkQuality aLinkQuality)
     {
         mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityInMask) |
                                    ((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask);
@@ -386,9 +386,9 @@
      * @returns The Link Quality Out value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityOut(uint8_t aRouterIndex) const
+    LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const
     {
-        return (mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset;
+        return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset);
     }
 
     /**
@@ -398,7 +398,7 @@
      * @param[in]  aLinkQuality  The Link Quality Out value for a given Router index.
      *
      */
-    void SetLinkQualityOut(uint8_t aRouterIndex, uint8_t aLinkQuality)
+    void SetLinkQualityOut(uint8_t aRouterIndex, LinkQuality aLinkQuality)
     {
         mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityOutMask) |
                                    ((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask);
@@ -600,11 +600,12 @@
      * @returns The Link Quality Out value for a given Router index.
      *
      */
-    uint8_t GetLinkQualityOut(uint8_t aRouterIndex) const
+    LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const
     {
         int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
-        return (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityOutMask >> offset)) >>
-               (kLinkQualityOutOffset - offset);
+        return static_cast<LinkQuality>(
+            (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityOutMask >> offset)) >>
+            (kLinkQualityOutOffset - offset));
     }
 
     /**
@@ -614,7 +615,7 @@
      * @param[in]  aLinkQuality  The Link Quality Out value for a given Router index.
      *
      */
-    void SetLinkQualityOut(uint8_t aRouterIndex, uint8_t aLinkQuality)
+    void SetLinkQualityOut(uint8_t aRouterIndex, LinkQuality aLinkQuality)
     {
         int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
         mRouteData[aRouterIndex + aRouterIndex / 2] =
diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp
index c7b37b8..db90327 100644
--- a/src/core/thread/router_table.cpp
+++ b/src/core/thread/router_table.cpp
@@ -323,7 +323,7 @@
 
 void RouterTable::RemoveRouterLink(Router &aRouter)
 {
-    aRouter.SetLinkQualityOut(0);
+    aRouter.SetLinkQualityOut(kLinkQuality0);
     aRouter.SetLastHeard(TimerMilli::GetNow());
 
     for (Router *cur = GetFirstEntry(); cur != nullptr; cur = GetNextEntry(cur))
diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp
index 7c6ac7e..dc39d9d 100644
--- a/src/core/thread/topology.hpp
+++ b/src/core/thread/topology.hpp
@@ -1397,7 +1397,7 @@
      * @returns The link quality out value for this router.
      *
      */
-    uint8_t GetLinkQualityOut(void) const { return mLinkQualityOut; }
+    LinkQuality GetLinkQualityOut(void) const { return static_cast<LinkQuality>(mLinkQualityOut); }
 
     /**
      * This method sets the link quality out value for this router.
@@ -1405,7 +1405,7 @@
      * @param[in]  aLinkQuality  The link quality out value for this router.
      *
      */
-    void SetLinkQualityOut(uint8_t aLinkQuality) { mLinkQualityOut = aLinkQuality; }
+    void SetLinkQualityOut(LinkQuality aLinkQuality) { mLinkQualityOut = aLinkQuality; }
 
     /**
      * This method get the route cost to this router.