1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright(c) 1999 - 2018 Intel Corporation. */ |
3 | |
4 | #include "ixgbe.h" |
5 | #include "ixgbe_type.h" |
6 | #include "ixgbe_dcb.h" |
7 | #include "ixgbe_dcb_82598.h" |
8 | |
9 | /** |
10 | * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter |
11 | * @hw: pointer to hardware structure |
12 | * @refill: refill credits index by traffic class |
13 | * @max: max credits index by traffic class |
14 | * @prio_type: priority type indexed by traffic class |
15 | * |
16 | * Configure Rx Data Arbiter and credits for each traffic class. |
17 | */ |
18 | int ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill, |
19 | u16 *max, u8 *prio_type) |
20 | { |
21 | u32 reg = 0; |
22 | u32 credit_refill = 0; |
23 | u32 credit_max = 0; |
24 | u8 i = 0; |
25 | |
26 | reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA; |
27 | IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg); |
28 | |
29 | reg = IXGBE_READ_REG(hw, IXGBE_RMCS); |
30 | /* Enable Arbiter */ |
31 | reg &= ~IXGBE_RMCS_ARBDIS; |
32 | /* Enable Receive Recycle within the BWG */ |
33 | reg |= IXGBE_RMCS_RRM; |
34 | /* Enable Deficit Fixed Priority arbitration*/ |
35 | reg |= IXGBE_RMCS_DFP; |
36 | |
37 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); |
38 | |
39 | /* Configure traffic class credits and priority */ |
40 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
41 | credit_refill = refill[i]; |
42 | credit_max = max[i]; |
43 | |
44 | reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); |
45 | |
46 | if (prio_type[i] == prio_link) |
47 | reg |= IXGBE_RT2CR_LSP; |
48 | |
49 | IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); |
50 | } |
51 | |
52 | reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); |
53 | reg |= IXGBE_RDRXCTL_RDMTS_1_2; |
54 | reg |= IXGBE_RDRXCTL_MPBEN; |
55 | reg |= IXGBE_RDRXCTL_MCEN; |
56 | IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); |
57 | |
58 | reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL); |
59 | /* Make sure there is enough descriptors before arbitration */ |
60 | reg &= ~IXGBE_RXCTRL_DMBYPS; |
61 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg); |
62 | |
63 | return 0; |
64 | } |
65 | |
66 | /** |
67 | * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter |
68 | * @hw: pointer to hardware structure |
69 | * @refill: refill credits index by traffic class |
70 | * @max: max credits index by traffic class |
71 | * @bwg_id: bandwidth grouping indexed by traffic class |
72 | * @prio_type: priority type indexed by traffic class |
73 | * |
74 | * Configure Tx Descriptor Arbiter and credits for each traffic class. |
75 | */ |
76 | int ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, u16 *refill, |
77 | u16 *max, u8 *bwg_id, u8 *prio_type) |
78 | { |
79 | u32 reg, max_credits; |
80 | u8 i; |
81 | |
82 | reg = IXGBE_READ_REG(hw, IXGBE_DPMCS); |
83 | |
84 | /* Enable arbiter */ |
85 | reg &= ~IXGBE_DPMCS_ARBDIS; |
86 | reg |= IXGBE_DPMCS_TSOEF; |
87 | |
88 | /* Configure Max TSO packet size 34KB including payload and headers */ |
89 | reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); |
90 | |
91 | IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg); |
92 | |
93 | /* Configure traffic class credits and priority */ |
94 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
95 | max_credits = max[i]; |
96 | reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; |
97 | reg |= refill[i]; |
98 | reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; |
99 | |
100 | if (prio_type[i] == prio_group) |
101 | reg |= IXGBE_TDTQ2TCCR_GSP; |
102 | |
103 | if (prio_type[i] == prio_link) |
104 | reg |= IXGBE_TDTQ2TCCR_LSP; |
105 | |
106 | IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); |
107 | } |
108 | |
109 | return 0; |
110 | } |
111 | |
112 | /** |
113 | * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter |
114 | * @hw: pointer to hardware structure |
115 | * @refill: refill credits index by traffic class |
116 | * @max: max credits index by traffic class |
117 | * @bwg_id: bandwidth grouping indexed by traffic class |
118 | * @prio_type: priority type indexed by traffic class |
119 | * |
120 | * Configure Tx Data Arbiter and credits for each traffic class. |
121 | */ |
122 | int ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, u16 *refill, |
123 | u16 *max, u8 *bwg_id, u8 *prio_type) |
124 | { |
125 | u32 reg; |
126 | u8 i; |
127 | |
128 | reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS); |
129 | /* Enable Data Plane Arbiter */ |
130 | reg &= ~IXGBE_PDPMCS_ARBDIS; |
131 | /* Enable DFP and Transmit Recycle Mode */ |
132 | reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM); |
133 | |
134 | IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg); |
135 | |
136 | /* Configure traffic class credits and priority */ |
137 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
138 | reg = refill[i]; |
139 | reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; |
140 | reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; |
141 | |
142 | if (prio_type[i] == prio_group) |
143 | reg |= IXGBE_TDPT2TCCR_GSP; |
144 | |
145 | if (prio_type[i] == prio_link) |
146 | reg |= IXGBE_TDPT2TCCR_LSP; |
147 | |
148 | IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); |
149 | } |
150 | |
151 | /* Enable Tx packet buffer division */ |
152 | reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL); |
153 | reg |= IXGBE_DTXCTL_ENDBUBD; |
154 | IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg); |
155 | |
156 | return 0; |
157 | } |
158 | |
159 | /** |
160 | * ixgbe_dcb_config_pfc_82598 - Config priority flow control |
161 | * @hw: pointer to hardware structure |
162 | * @pfc_en: enabled pfc bitmask |
163 | * |
164 | * Configure Priority Flow Control for each traffic class. |
165 | */ |
166 | int ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) |
167 | { |
168 | u32 fcrtl, reg; |
169 | u8 i; |
170 | |
171 | /* Enable Transmit Priority Flow Control */ |
172 | reg = IXGBE_READ_REG(hw, IXGBE_RMCS); |
173 | reg &= ~IXGBE_RMCS_TFCE_802_3X; |
174 | reg |= IXGBE_RMCS_TFCE_PRIORITY; |
175 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); |
176 | |
177 | /* Enable Receive Priority Flow Control */ |
178 | reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); |
179 | reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); |
180 | |
181 | if (pfc_en) |
182 | reg |= IXGBE_FCTRL_RPFCE; |
183 | |
184 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); |
185 | |
186 | /* Configure PFC Tx thresholds per TC */ |
187 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
188 | if (!(pfc_en & BIT(i))) { |
189 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); |
190 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); |
191 | continue; |
192 | } |
193 | |
194 | fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; |
195 | reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; |
196 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); |
197 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); |
198 | } |
199 | |
200 | /* Configure pause time */ |
201 | reg = hw->fc.pause_time * 0x00010001; |
202 | for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) |
203 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); |
204 | |
205 | /* Configure flow control refresh threshold value */ |
206 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); |
207 | |
208 | |
209 | return 0; |
210 | } |
211 | |
212 | /** |
213 | * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics |
214 | * @hw: pointer to hardware structure |
215 | * |
216 | * Configure queue statistics registers, all queues belonging to same traffic |
217 | * class uses a single set of queue statistics counters. |
218 | */ |
219 | static int ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) |
220 | { |
221 | u32 reg = 0; |
222 | u8 i = 0; |
223 | u8 j = 0; |
224 | |
225 | /* Receive Queues stats setting - 8 queues per statistics reg */ |
226 | for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) { |
227 | reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i)); |
228 | reg |= ((0x1010101) * j); |
229 | IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); |
230 | reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1)); |
231 | reg |= ((0x1010101) * j); |
232 | IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg); |
233 | } |
234 | /* Transmit Queues stats setting - 4 queues per statistics reg */ |
235 | for (i = 0; i < 8; i++) { |
236 | reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i)); |
237 | reg |= ((0x1010101) * i); |
238 | IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg); |
239 | } |
240 | |
241 | return 0; |
242 | } |
243 | |
244 | /** |
245 | * ixgbe_dcb_hw_config_82598 - Config and enable DCB |
246 | * @hw: pointer to hardware structure |
247 | * @pfc_en: enabled pfc bitmask |
248 | * @refill: refill credits index by traffic class |
249 | * @max: max credits index by traffic class |
250 | * @bwg_id: bandwidth grouping indexed by traffic class |
251 | * @prio_type: priority type indexed by traffic class |
252 | * |
253 | * Configure dcb settings and enable dcb mode. |
254 | */ |
255 | int ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, |
256 | u16 *max, u8 *bwg_id, u8 *prio_type) |
257 | { |
258 | ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); |
259 | ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, |
260 | bwg_id, prio_type); |
261 | ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, |
262 | bwg_id, prio_type); |
263 | ixgbe_dcb_config_pfc_82598(hw, pfc_en); |
264 | ixgbe_dcb_config_tc_stats_82598(hw); |
265 | |
266 | return 0; |
267 | } |
268 | |