Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "tp_qos.h"
12 :
13 : #include <cctype>
14 : #include <string>
15 : #include <vector>
16 :
17 : #include "log.h"
18 : #include "hccp.h"
19 :
20 : namespace Hccl {
21 :
22 : namespace {
23 :
24 : static constexpr uint32_t slPolicy2 = 2U;
25 : static constexpr uint32_t slPolicy3 = 3U;
26 : static constexpr uint32_t slPolicy4 = 4U;
27 : static constexpr uint32_t slPolicy5 = 5U;
28 : static constexpr uint32_t slPolicy7 = 7U;
29 : static constexpr uint32_t slPolicy8 = 8U;
30 : static constexpr uint32_t slGroupIdx0 = 0U;
31 : static constexpr uint32_t slGroupIdx1 = 1U;
32 : static constexpr uint32_t slGroupIdx2 = 2U;
33 :
34 : constexpr size_t kMaxQosDscpPairs = 8U;
35 : constexpr uint32_t kDecimalBase = 10U;
36 : constexpr unsigned int kHccnCfgValueBufLen = 2048U;
37 :
38 21 : static bool ParseUint32Field(const std::string& cfg, size_t& pos, uint32_t& out)
39 : {
40 21 : if (pos >= cfg.size() || std::isdigit(static_cast<unsigned char>(cfg[pos])) == 0) {
41 0 : return false;
42 : }
43 21 : uint32_t val = 0U;
44 51 : while (pos < cfg.size() && std::isdigit(static_cast<unsigned char>(cfg[pos])) != 0) {
45 30 : val = val * kDecimalBase + static_cast<uint32_t>(cfg[pos] - '0');
46 30 : ++pos;
47 : }
48 21 : out = val;
49 21 : return true;
50 : }
51 :
52 : // HCCN cfg value format: "qos:dscp,qos:dscp,..." (e.g. "0:33,1:65"), at most 8 pairs.
53 6 : static bool ParseDscpFromCfgByQos(const std::string& cfg, uint8_t qos, uint8_t& dscpOut)
54 : {
55 6 : size_t pos = 0U;
56 12 : for (size_t pairIdx = 0U; pairIdx < kMaxQosDscpPairs; ++pairIdx) {
57 12 : uint32_t cfgQos = 0U;
58 12 : uint32_t cfgDscp = 0U;
59 12 : if (!ParseUint32Field(cfg, pos, cfgQos)) {
60 6 : return false;
61 : }
62 12 : if (pos >= cfg.size() || cfg[pos] != ':') {
63 3 : return false;
64 : }
65 9 : ++pos;
66 9 : if (!ParseUint32Field(cfg, pos, cfgDscp)) {
67 0 : return false;
68 : }
69 :
70 9 : if (static_cast<uint8_t>(cfgQos) == qos) {
71 3 : dscpOut = static_cast<uint8_t>(cfgDscp);
72 3 : return true;
73 : }
74 :
75 6 : if (pos >= cfg.size()) {
76 0 : break;
77 : }
78 6 : if (cfg[pos] != ',') {
79 0 : return false;
80 : }
81 6 : ++pos;
82 : }
83 0 : return false;
84 : }
85 :
86 : } // namespace
87 :
88 29 : uint32_t TpQosResolveQosSlGroupIdx(const uint32_t qos, const uint32_t numGroups)
89 : {
90 29 : if (numGroups == slPolicy3) {
91 24 : if (qos < slPolicy3) {
92 13 : return slGroupIdx0;
93 : }
94 11 : if (qos < slPolicy5) {
95 4 : return slGroupIdx1;
96 : }
97 7 : return slGroupIdx2;
98 : }
99 5 : if (numGroups >= slPolicy4 && numGroups <= slPolicy7) {
100 0 : return qos / slPolicy2;
101 : }
102 5 : return (qos * numGroups) / slPolicy8;
103 : }
104 :
105 13 : bool TpQosGetDscpByQosFromHccnCfg(const uint32_t devPhyId, uint8_t qos, uint8_t& dscpOut)
106 : {
107 13 : struct RaInfo info {};
108 13 : info.mode = NETWORK_OFFLINE;
109 13 : info.phyId = devPhyId;
110 :
111 13 : std::vector<char> value(kHccnCfgValueBufLen, 0);
112 13 : unsigned int valueLen = kHccnCfgValueBufLen;
113 13 : const int ret = RaGetHccnCfg(&info, HCCN_CFG_QOS_DSCP, value.data(), &valueLen);
114 13 : unsigned int logLen = valueLen;
115 13 : if (logLen > kHccnCfgValueBufLen) {
116 0 : logLen = kHccnCfgValueBufLen;
117 : }
118 13 : const std::string cfgLog(value.data(), logLen);
119 19 : HCCL_INFO(
120 : "[TpQos][%s] RaGetHccnCfg ret[%d] phyId[%u] valueLen[%u] qos_dscp[%s].", __func__, ret, devPhyId, valueLen,
121 : cfgLog.c_str());
122 13 : if (ret != 0 || valueLen == 0U) {
123 7 : return false;
124 : }
125 6 : if (valueLen > kHccnCfgValueBufLen) {
126 0 : valueLen = kHccnCfgValueBufLen;
127 : }
128 6 : const std::string cfg(value.data(), valueLen);
129 6 : return ParseDscpFromCfgByQos(cfg, qos, dscpOut);
130 13 : }
131 :
132 : } // namespace Hccl
|