ixgbe_dcb_82598.c revision 315333
1/******************************************************************************
2
3  Copyright (c) 2001-2017, 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: stable/10/sys/dev/ixgbe/ixgbe_dcb_82598.c 315333 2017-03-15 21:20:17Z erj $*/
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 */
48s32 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 */
90s32 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 */
118s32 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 */
173s32 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 */
217s32 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 */
262s32 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 */
314s32 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 */
346s32 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