| .. | .. |
|---|
| 53 | 53 | |
|---|
| 54 | 54 | for (i = 0; i < HNAE3_MAX_TC; i++) { |
|---|
| 55 | 55 | ets->prio_tc[i] = hdev->tm_info.prio_tc[i]; |
|---|
| 56 | | - ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i]; |
|---|
| 56 | + if (i < hdev->tm_info.num_tc) |
|---|
| 57 | + ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i]; |
|---|
| 58 | + else |
|---|
| 59 | + ets->tc_tx_bw[i] = 0; |
|---|
| 57 | 60 | |
|---|
| 58 | 61 | if (hdev->tm_info.tc_info[i].tc_sch_mode == |
|---|
| 59 | 62 | HCLGE_SCH_MODE_SP) |
|---|
| .. | .. |
|---|
| 105 | 108 | return 0; |
|---|
| 106 | 109 | } |
|---|
| 107 | 110 | |
|---|
| 108 | | -static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets, |
|---|
| 109 | | - u8 *tc, bool *changed) |
|---|
| 111 | +static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets, |
|---|
| 112 | + bool *changed) |
|---|
| 110 | 113 | { |
|---|
| 111 | | - bool has_ets_tc = false; |
|---|
| 112 | | - u32 total_ets_bw = 0; |
|---|
| 113 | | - u8 max_tc = 0; |
|---|
| 114 | | - int ret; |
|---|
| 114 | + u8 max_tc_id = 0; |
|---|
| 115 | 115 | u8 i; |
|---|
| 116 | 116 | |
|---|
| 117 | 117 | for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) { |
|---|
| 118 | 118 | if (ets->prio_tc[i] != hdev->tm_info.prio_tc[i]) |
|---|
| 119 | 119 | *changed = true; |
|---|
| 120 | 120 | |
|---|
| 121 | | - if (ets->prio_tc[i] > max_tc) |
|---|
| 122 | | - max_tc = ets->prio_tc[i]; |
|---|
| 121 | + if (ets->prio_tc[i] > max_tc_id) |
|---|
| 122 | + max_tc_id = ets->prio_tc[i]; |
|---|
| 123 | 123 | } |
|---|
| 124 | 124 | |
|---|
| 125 | | - ret = hclge_dcb_common_validate(hdev, max_tc + 1, ets->prio_tc); |
|---|
| 126 | | - if (ret) |
|---|
| 127 | | - return ret; |
|---|
| 125 | + /* return max tc number, max tc id need to plus 1 */ |
|---|
| 126 | + return max_tc_id + 1; |
|---|
| 127 | +} |
|---|
| 128 | + |
|---|
| 129 | +static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, |
|---|
| 130 | + struct ieee_ets *ets, bool *changed, |
|---|
| 131 | + u8 tc_num) |
|---|
| 132 | +{ |
|---|
| 133 | + bool has_ets_tc = false; |
|---|
| 134 | + u32 total_ets_bw = 0; |
|---|
| 135 | + u8 i; |
|---|
| 128 | 136 | |
|---|
| 129 | 137 | for (i = 0; i < HNAE3_MAX_TC; i++) { |
|---|
| 130 | 138 | switch (ets->tc_tsa[i]) { |
|---|
| .. | .. |
|---|
| 134 | 142 | *changed = true; |
|---|
| 135 | 143 | break; |
|---|
| 136 | 144 | case IEEE_8021QAZ_TSA_ETS: |
|---|
| 145 | + if (i >= tc_num) { |
|---|
| 146 | + dev_err(&hdev->pdev->dev, |
|---|
| 147 | + "tc%u is disabled, cannot set ets bw\n", |
|---|
| 148 | + i); |
|---|
| 149 | + return -EINVAL; |
|---|
| 150 | + } |
|---|
| 151 | + |
|---|
| 137 | 152 | /* The hardware will switch to sp mode if bandwidth is |
|---|
| 138 | 153 | * 0, so limit ets bandwidth must be greater than 0. |
|---|
| 139 | 154 | */ |
|---|
| .. | .. |
|---|
| 158 | 173 | if (has_ets_tc && total_ets_bw != BW_PERCENT) |
|---|
| 159 | 174 | return -EINVAL; |
|---|
| 160 | 175 | |
|---|
| 161 | | - *tc = max_tc + 1; |
|---|
| 176 | + return 0; |
|---|
| 177 | +} |
|---|
| 178 | + |
|---|
| 179 | +static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets, |
|---|
| 180 | + u8 *tc, bool *changed) |
|---|
| 181 | +{ |
|---|
| 182 | + u8 tc_num; |
|---|
| 183 | + int ret; |
|---|
| 184 | + |
|---|
| 185 | + tc_num = hclge_ets_tc_changed(hdev, ets, changed); |
|---|
| 186 | + |
|---|
| 187 | + ret = hclge_dcb_common_validate(hdev, tc_num, ets->prio_tc); |
|---|
| 188 | + if (ret) |
|---|
| 189 | + return ret; |
|---|
| 190 | + |
|---|
| 191 | + ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num); |
|---|
| 192 | + if (ret) |
|---|
| 193 | + return ret; |
|---|
| 194 | + |
|---|
| 195 | + *tc = tc_num; |
|---|
| 162 | 196 | if (*tc != hdev->tm_info.num_tc) |
|---|
| 163 | 197 | *changed = true; |
|---|
| 164 | 198 | |
|---|