xref: /titanic_44/usr/src/uts/common/io/ixgbe/core/ixgbe_dcb_82598.c (revision 313ba7960502dc67eab67213cf5240fb5191b470)
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 /*$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  */
ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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  */
ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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  */
ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * tsa)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  */
ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)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  */
ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)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  */
ixgbe_dcb_config_pfc_82598(struct ixgbe_hw * hw,u8 pfc_en)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  */
ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw * hw)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  */
ixgbe_dcb_hw_config_82598(struct ixgbe_hw * hw,int link_speed,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)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 	UNREFERENCED_1PARAMETER(link_speed);
351 
352 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
353 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
354 					       tsa);
355 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
356 					       tsa);
357 	ixgbe_dcb_config_tc_stats_82598(hw);
358 
359 
360 	return IXGBE_SUCCESS;
361 }
362