]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /******************************************************************************* |
2 | ||
3 | Copyright (c) 2001-2015, Intel Corporation | |
4 | All rights reserved. | |
5 | ||
6 | Redistribution and use in source and binary forms, with or without | |
7 | modification, are permitted provided that the following conditions are met: | |
8 | ||
9 | 1. Redistributions of source code must retain the above copyright notice, | |
10 | this list of conditions and the following disclaimer. | |
11 | ||
12 | 2. Redistributions in binary form must reproduce the above copyright | |
13 | notice, this list of conditions and the following disclaimer in the | |
14 | documentation and/or other materials provided with the distribution. | |
15 | ||
16 | 3. Neither the name of the Intel Corporation nor the names of its | |
17 | contributors may be used to endorse or promote products derived from | |
18 | this software without specific prior written permission. | |
19 | ||
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | POSSIBILITY OF SUCH DAMAGE. | |
31 | ||
32 | ***************************************************************************/ | |
33 | ||
34 | ||
35 | #include "ixgbe_type.h" | |
36 | #include "ixgbe_dcb.h" | |
37 | #include "ixgbe_dcb_82598.h" | |
38 | ||
39 | /** | |
40 | * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class | |
41 | * @hw: pointer to hardware structure | |
42 | * @stats: pointer to statistics structure | |
43 | * @tc_count: Number of elements in bwg_array. | |
44 | * | |
45 | * This function returns the status data for each of the Traffic Classes in use. | |
46 | */ | |
47 | s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw, | |
48 | struct ixgbe_hw_stats *stats, | |
49 | u8 tc_count) | |
50 | { | |
51 | int tc; | |
52 | ||
53 | DEBUGFUNC("dcb_get_tc_stats"); | |
54 | ||
55 | if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS) | |
56 | return IXGBE_ERR_PARAM; | |
57 | ||
58 | /* Statistics pertaining to each traffic class */ | |
59 | for (tc = 0; tc < tc_count; tc++) { | |
60 | /* Transmitted Packets */ | |
61 | stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); | |
62 | /* Transmitted Bytes */ | |
63 | stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc)); | |
64 | /* Received Packets */ | |
65 | stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); | |
66 | /* Received Bytes */ | |
67 | stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc)); | |
68 | ||
69 | #if 0 | |
70 | /* Can we get rid of these?? Consequently, getting rid | |
71 | * of the tc_stats structure. | |
72 | */ | |
73 | tc_stats_array[up]->in_overflow_discards = 0; | |
74 | tc_stats_array[up]->out_overflow_discards = 0; | |
75 | #endif | |
76 | } | |
77 | ||
78 | return IXGBE_SUCCESS; | |
79 | } | |
80 | ||
81 | /** | |
82 | * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data | |
83 | * @hw: pointer to hardware structure | |
84 | * @stats: pointer to statistics structure | |
85 | * @tc_count: Number of elements in bwg_array. | |
86 | * | |
87 | * This function returns the CBFC status data for each of the Traffic Classes. | |
88 | */ | |
89 | s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw, | |
90 | struct ixgbe_hw_stats *stats, | |
91 | u8 tc_count) | |
92 | { | |
93 | int tc; | |
94 | ||
95 | DEBUGFUNC("dcb_get_pfc_stats"); | |
96 | ||
97 | if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS) | |
98 | return IXGBE_ERR_PARAM; | |
99 | ||
100 | for (tc = 0; tc < tc_count; tc++) { | |
101 | /* Priority XOFF Transmitted */ | |
102 | stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); | |
103 | /* Priority XOFF Received */ | |
104 | stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc)); | |
105 | } | |
106 | ||
107 | return IXGBE_SUCCESS; | |
108 | } | |
109 | ||
110 | /** | |
111 | * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter | |
112 | * @hw: pointer to hardware structure | |
113 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
114 | * | |
115 | * Configure Rx Data Arbiter and credits for each traffic class. | |
116 | */ | |
117 | s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill, | |
118 | u16 *max, u8 *tsa) | |
119 | { | |
120 | u32 reg = 0; | |
121 | u32 credit_refill = 0; | |
122 | u32 credit_max = 0; | |
123 | u8 i = 0; | |
124 | ||
125 | reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA; | |
126 | IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg); | |
127 | ||
128 | reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | |
129 | /* Enable Arbiter */ | |
130 | reg &= ~IXGBE_RMCS_ARBDIS; | |
131 | /* Enable Receive Recycle within the BWG */ | |
132 | reg |= IXGBE_RMCS_RRM; | |
133 | /* Enable Deficit Fixed Priority arbitration*/ | |
134 | reg |= IXGBE_RMCS_DFP; | |
135 | ||
136 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); | |
137 | ||
138 | /* Configure traffic class credits and priority */ | |
139 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
140 | credit_refill = refill[i]; | |
141 | credit_max = max[i]; | |
142 | ||
143 | reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); | |
144 | ||
145 | if (tsa[i] == ixgbe_dcb_tsa_strict) | |
146 | reg |= IXGBE_RT2CR_LSP; | |
147 | ||
148 | IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); | |
149 | } | |
150 | ||
151 | reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); | |
152 | reg |= IXGBE_RDRXCTL_RDMTS_1_2; | |
153 | reg |= IXGBE_RDRXCTL_MPBEN; | |
154 | reg |= IXGBE_RDRXCTL_MCEN; | |
155 | IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); | |
156 | ||
157 | reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | |
158 | /* Make sure there is enough descriptors before arbitration */ | |
159 | reg &= ~IXGBE_RXCTRL_DMBYPS; | |
160 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg); | |
161 | ||
162 | return IXGBE_SUCCESS; | |
163 | } | |
164 | ||
165 | /** | |
166 | * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter | |
167 | * @hw: pointer to hardware structure | |
168 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
169 | * | |
170 | * Configure Tx Descriptor Arbiter and credits for each traffic class. | |
171 | */ | |
172 | s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | |
173 | u16 *refill, u16 *max, u8 *bwg_id, | |
174 | u8 *tsa) | |
175 | { | |
176 | u32 reg, max_credits; | |
177 | u8 i; | |
178 | ||
179 | reg = IXGBE_READ_REG(hw, IXGBE_DPMCS); | |
180 | ||
181 | /* Enable arbiter */ | |
182 | reg &= ~IXGBE_DPMCS_ARBDIS; | |
183 | reg |= IXGBE_DPMCS_TSOEF; | |
184 | ||
185 | /* Configure Max TSO packet size 34KB including payload and headers */ | |
186 | reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); | |
187 | ||
188 | IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg); | |
189 | ||
190 | /* Configure traffic class credits and priority */ | |
191 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
192 | max_credits = max[i]; | |
193 | reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; | |
194 | reg |= refill[i]; | |
195 | reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; | |
196 | ||
197 | if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee) | |
198 | reg |= IXGBE_TDTQ2TCCR_GSP; | |
199 | ||
200 | if (tsa[i] == ixgbe_dcb_tsa_strict) | |
201 | reg |= IXGBE_TDTQ2TCCR_LSP; | |
202 | ||
203 | IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); | |
204 | } | |
205 | ||
206 | return IXGBE_SUCCESS; | |
207 | } | |
208 | ||
209 | /** | |
210 | * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter | |
211 | * @hw: pointer to hardware structure | |
212 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
213 | * | |
214 | * Configure Tx Data Arbiter and credits for each traffic class. | |
215 | */ | |
216 | s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, | |
217 | u16 *refill, u16 *max, u8 *bwg_id, | |
218 | u8 *tsa) | |
219 | { | |
220 | u32 reg; | |
221 | u8 i; | |
222 | ||
223 | reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS); | |
224 | /* Enable Data Plane Arbiter */ | |
225 | reg &= ~IXGBE_PDPMCS_ARBDIS; | |
226 | /* Enable DFP and Transmit Recycle Mode */ | |
227 | reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM); | |
228 | ||
229 | IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg); | |
230 | ||
231 | /* Configure traffic class credits and priority */ | |
232 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
233 | reg = refill[i]; | |
234 | reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; | |
235 | reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; | |
236 | ||
237 | if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee) | |
238 | reg |= IXGBE_TDPT2TCCR_GSP; | |
239 | ||
240 | if (tsa[i] == ixgbe_dcb_tsa_strict) | |
241 | reg |= IXGBE_TDPT2TCCR_LSP; | |
242 | ||
243 | IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); | |
244 | } | |
245 | ||
246 | /* Enable Tx packet buffer division */ | |
247 | reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL); | |
248 | reg |= IXGBE_DTXCTL_ENDBUBD; | |
249 | IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg); | |
250 | ||
251 | return IXGBE_SUCCESS; | |
252 | } | |
253 | ||
254 | /** | |
255 | * ixgbe_dcb_config_pfc_82598 - Config priority flow control | |
256 | * @hw: pointer to hardware structure | |
257 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
258 | * | |
259 | * Configure Priority Flow Control for each traffic class. | |
260 | */ | |
261 | s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) | |
262 | { | |
263 | u32 fcrtl, reg; | |
264 | u8 i; | |
265 | ||
266 | /* Enable Transmit Priority Flow Control */ | |
267 | reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | |
268 | reg &= ~IXGBE_RMCS_TFCE_802_3X; | |
269 | reg |= IXGBE_RMCS_TFCE_PRIORITY; | |
270 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); | |
271 | ||
272 | /* Enable Receive Priority Flow Control */ | |
273 | reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | |
274 | reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); | |
275 | ||
276 | if (pfc_en) | |
277 | reg |= IXGBE_FCTRL_RPFCE; | |
278 | ||
279 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); | |
280 | ||
281 | /* Configure PFC Tx thresholds per TC */ | |
282 | for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { | |
283 | if (!(pfc_en & (1 << i))) { | |
284 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); | |
285 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); | |
286 | continue; | |
287 | } | |
288 | ||
289 | fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; | |
290 | reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; | |
291 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); | |
292 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); | |
293 | } | |
294 | ||
295 | /* Configure pause time */ | |
296 | reg = hw->fc.pause_time | (hw->fc.pause_time << 16); | |
297 | for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++) | |
298 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); | |
299 | ||
300 | /* Configure flow control refresh threshold value */ | |
301 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); | |
302 | ||
303 | return IXGBE_SUCCESS; | |
304 | } | |
305 | ||
306 | /** | |
307 | * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics | |
308 | * @hw: pointer to hardware structure | |
309 | * | |
310 | * Configure queue statistics registers, all queues belonging to same traffic | |
311 | * class uses a single set of queue statistics counters. | |
312 | */ | |
313 | s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) | |
314 | { | |
315 | u32 reg = 0; | |
316 | u8 i = 0; | |
317 | u8 j = 0; | |
318 | ||
319 | /* Receive Queues stats setting - 8 queues per statistics reg */ | |
320 | for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) { | |
321 | reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i)); | |
322 | reg |= ((0x1010101) * j); | |
323 | IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); | |
324 | reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1)); | |
325 | reg |= ((0x1010101) * j); | |
326 | IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg); | |
327 | } | |
328 | /* Transmit Queues stats setting - 4 queues per statistics reg*/ | |
329 | for (i = 0; i < 8; i++) { | |
330 | reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i)); | |
331 | reg |= ((0x1010101) * i); | |
332 | IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg); | |
333 | } | |
334 | ||
335 | return IXGBE_SUCCESS; | |
336 | } | |
337 | ||
338 | /** | |
339 | * ixgbe_dcb_hw_config_82598 - Config and enable DCB | |
340 | * @hw: pointer to hardware structure | |
341 | * @dcb_config: pointer to ixgbe_dcb_config structure | |
342 | * | |
343 | * Configure dcb settings and enable dcb mode. | |
344 | */ | |
345 | s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed, | |
346 | u16 *refill, u16 *max, u8 *bwg_id, | |
347 | u8 *tsa) | |
348 | { | |
349 | UNREFERENCED_1PARAMETER(link_speed); | |
350 | ||
351 | ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); | |
352 | ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, | |
353 | tsa); | |
354 | ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, | |
355 | tsa); | |
356 | ixgbe_dcb_config_tc_stats_82598(hw); | |
357 | ||
358 | ||
359 | return IXGBE_SUCCESS; | |
360 | } |