]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/ixgbe/ixgbe_dcb_82598.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / ixgbe / ixgbe_dcb_82598.c
1 /******************************************************************************
2
3   Copyright (c) 2001-2013, 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 /*$FreeBSD$*/
34
35
36 #include "ixgbe_type.h"
37 #include "ixgbe_dcb.h"
38 #include "ixgbe_dcb_82598.h"
39
40 /**
41  * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class
42  * @hw: pointer to hardware structure
43  * @stats: pointer to statistics structure
44  * @tc_count:  Number of elements in bwg_array.
45  *
46  * This function returns the status data for each of the Traffic Classes in use.
47  */
48 s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw,
49                                  struct ixgbe_hw_stats *stats,
50                                  u8 tc_count)
51 {
52         int tc;
53
54         DEBUGFUNC("dcb_get_tc_stats");
55
56         if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
57                 return IXGBE_ERR_PARAM;
58
59         /* Statistics pertaining to each traffic class */
60         for (tc = 0; tc < tc_count; tc++) {
61                 /* Transmitted Packets */
62                 stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
63                 /* Transmitted Bytes */
64                 stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
65                 /* Received Packets */
66                 stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
67                 /* Received Bytes */
68                 stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
69
70 #if 0
71                 /* Can we get rid of these??  Consequently, getting rid
72                  * of the tc_stats structure.
73                  */
74                 tc_stats_array[up]->in_overflow_discards = 0;
75                 tc_stats_array[up]->out_overflow_discards = 0;
76 #endif
77         }
78
79         return IXGBE_SUCCESS;
80 }
81
82 /**
83  * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
84  * @hw: pointer to hardware structure
85  * @stats: pointer to statistics structure
86  * @tc_count:  Number of elements in bwg_array.
87  *
88  * This function returns the CBFC status data for each of the Traffic Classes.
89  */
90 s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
91                                   struct ixgbe_hw_stats *stats,
92                                   u8 tc_count)
93 {
94         int tc;
95
96         DEBUGFUNC("dcb_get_pfc_stats");
97
98         if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
99                 return IXGBE_ERR_PARAM;
100
101         for (tc = 0; tc < tc_count; tc++) {
102                 /* Priority XOFF Transmitted */
103                 stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
104                 /* Priority XOFF Received */
105                 stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
106         }
107
108         return IXGBE_SUCCESS;
109 }
110
111 /**
112  * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
113  * @hw: pointer to hardware structure
114  * @dcb_config: pointer to ixgbe_dcb_config structure
115  *
116  * Configure Rx Data Arbiter and credits for each traffic class.
117  */
118 s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill,
119                                       u16 *max, u8 *tsa)
120 {
121         u32 reg = 0;
122         u32 credit_refill = 0;
123         u32 credit_max = 0;
124         u8 i = 0;
125
126         reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
127         IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
128
129         reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
130         /* Enable Arbiter */
131         reg &= ~IXGBE_RMCS_ARBDIS;
132         /* Enable Receive Recycle within the BWG */
133         reg |= IXGBE_RMCS_RRM;
134         /* Enable Deficit Fixed Priority arbitration*/
135         reg |= IXGBE_RMCS_DFP;
136
137         IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
138
139         /* Configure traffic class credits and priority */
140         for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
141                 credit_refill = refill[i];
142                 credit_max = max[i];
143
144                 reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
145
146                 if (tsa[i] == ixgbe_dcb_tsa_strict)
147                         reg |= IXGBE_RT2CR_LSP;
148
149                 IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
150         }
151
152         reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
153         reg |= IXGBE_RDRXCTL_RDMTS_1_2;
154         reg |= IXGBE_RDRXCTL_MPBEN;
155         reg |= IXGBE_RDRXCTL_MCEN;
156         IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
157
158         reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
159         /* Make sure there is enough descriptors before arbitration */
160         reg &= ~IXGBE_RXCTRL_DMBYPS;
161         IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
162
163         return IXGBE_SUCCESS;
164 }
165
166 /**
167  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
168  * @hw: pointer to hardware structure
169  * @dcb_config: pointer to ixgbe_dcb_config structure
170  *
171  * Configure Tx Descriptor Arbiter and credits for each traffic class.
172  */
173 s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
174                                            u16 *refill, u16 *max, u8 *bwg_id,
175                                            u8 *tsa)
176 {
177         u32 reg, max_credits;
178         u8 i;
179
180         reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
181
182         /* Enable arbiter */
183         reg &= ~IXGBE_DPMCS_ARBDIS;
184         reg |= IXGBE_DPMCS_TSOEF;
185
186         /* Configure Max TSO packet size 34KB including payload and headers */
187         reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
188
189         IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
190
191         /* Configure traffic class credits and priority */
192         for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
193                 max_credits = max[i];
194                 reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
195                 reg |= refill[i];
196                 reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
197
198                 if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
199                         reg |= IXGBE_TDTQ2TCCR_GSP;
200
201                 if (tsa[i] == ixgbe_dcb_tsa_strict)
202                         reg |= IXGBE_TDTQ2TCCR_LSP;
203
204                 IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
205         }
206
207         return IXGBE_SUCCESS;
208 }
209
210 /**
211  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
212  * @hw: pointer to hardware structure
213  * @dcb_config: pointer to ixgbe_dcb_config structure
214  *
215  * Configure Tx Data Arbiter and credits for each traffic class.
216  */
217 s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
218                                            u16 *refill, u16 *max, u8 *bwg_id,
219                                            u8 *tsa)
220 {
221         u32 reg;
222         u8 i;
223
224         reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
225         /* Enable Data Plane Arbiter */
226         reg &= ~IXGBE_PDPMCS_ARBDIS;
227         /* Enable DFP and Transmit Recycle Mode */
228         reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
229
230         IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
231
232         /* Configure traffic class credits and priority */
233         for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
234                 reg = refill[i];
235                 reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
236                 reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
237
238                 if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
239                         reg |= IXGBE_TDPT2TCCR_GSP;
240
241                 if (tsa[i] == ixgbe_dcb_tsa_strict)
242                         reg |= IXGBE_TDPT2TCCR_LSP;
243
244                 IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
245         }
246
247         /* Enable Tx packet buffer division */
248         reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
249         reg |= IXGBE_DTXCTL_ENDBUBD;
250         IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
251
252         return IXGBE_SUCCESS;
253 }
254
255 /**
256  * ixgbe_dcb_config_pfc_82598 - Config priority flow control
257  * @hw: pointer to hardware structure
258  * @dcb_config: pointer to ixgbe_dcb_config structure
259  *
260  * Configure Priority Flow Control for each traffic class.
261  */
262 s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
263 {
264         u32 fcrtl, reg;
265         u8 i;
266
267         /* Enable Transmit Priority Flow Control */
268         reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
269         reg &= ~IXGBE_RMCS_TFCE_802_3X;
270         reg |= IXGBE_RMCS_TFCE_PRIORITY;
271         IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
272
273         /* Enable Receive Priority Flow Control */
274         reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
275         reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
276
277         if (pfc_en)
278                 reg |= IXGBE_FCTRL_RPFCE;
279
280         IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
281
282         /* Configure PFC Tx thresholds per TC */
283         for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
284                 if (!(pfc_en & (1 << i))) {
285                         IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
286                         IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
287                         continue;
288                 }
289
290                 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
291                 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
292                 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
293                 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
294         }
295
296         /* Configure pause time */
297         reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
298         for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
299                 IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
300
301         /* Configure flow control refresh threshold value */
302         IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
303
304         return IXGBE_SUCCESS;
305 }
306
307 /**
308  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
309  * @hw: pointer to hardware structure
310  *
311  * Configure queue statistics registers, all queues belonging to same traffic
312  * class uses a single set of queue statistics counters.
313  */
314 s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
315 {
316         u32 reg = 0;
317         u8 i = 0;
318         u8 j = 0;
319
320         /* Receive Queues stats setting -  8 queues per statistics reg */
321         for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
322                 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
323                 reg |= ((0x1010101) * j);
324                 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
325                 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
326                 reg |= ((0x1010101) * j);
327                 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
328         }
329         /* Transmit Queues stats setting -  4 queues per statistics reg*/
330         for (i = 0; i < 8; i++) {
331                 reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
332                 reg |= ((0x1010101) * i);
333                 IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
334         }
335
336         return IXGBE_SUCCESS;
337 }
338
339 /**
340  * ixgbe_dcb_hw_config_82598 - Config and enable DCB
341  * @hw: pointer to hardware structure
342  * @dcb_config: pointer to ixgbe_dcb_config structure
343  *
344  * Configure dcb settings and enable dcb mode.
345  */
346 s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed,
347                               u16 *refill, u16 *max, u8 *bwg_id,
348                               u8 *tsa)
349 {
350         ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
351         ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
352                                                tsa);
353         ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
354                                                tsa);
355         ixgbe_dcb_config_tc_stats_82598(hw);
356
357
358         return IXGBE_SUCCESS;
359 }