1/******************************************************************************
2  SPDX-License-Identifier: BSD-3-Clause
3
4  Copyright (c) 2001-2020, Intel Corporation
5  All rights reserved.
6
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9
10   1. Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12
13   2. Redistributions in binary form must reproduce the above copyright
14      notice, this list of conditions and the following disclaimer in the
15      documentation and/or other materials provided with the distribution.
16
17   3. Neither the name of the Intel Corporation nor the names of its
18      contributors may be used to endorse or promote products derived from
19      this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  POSSIBILITY OF SUCH DAMAGE.
32
33******************************************************************************/
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
71	return IXGBE_SUCCESS;
72}
73
74/**
75 * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
76 * @hw: pointer to hardware structure
77 * @stats: pointer to statistics structure
78 * @tc_count:  Number of elements in bwg_array.
79 *
80 * This function returns the CBFC status data for each of the Traffic Classes.
81 */
82s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
83				  struct ixgbe_hw_stats *stats,
84				  u8 tc_count)
85{
86	int tc;
87
88	DEBUGFUNC("dcb_get_pfc_stats");
89
90	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
91		return IXGBE_ERR_PARAM;
92
93	for (tc = 0; tc < tc_count; tc++) {
94		/* Priority XOFF Transmitted */
95		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
96		/* Priority XOFF Received */
97		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
98	}
99
100	return IXGBE_SUCCESS;
101}
102
103/**
104 * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
105 * @hw: pointer to hardware structure
106 * @refill: refill credits index by traffic class
107 * @max: max credits index by traffic class
108 * @tsa: transmission selection algorithm indexed by traffic class
109 *
110 * Configure Rx Data Arbiter and credits for each traffic class.
111 */
112s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill,
113				      u16 *max, u8 *tsa)
114{
115	u32 reg = 0;
116	u32 credit_refill = 0;
117	u32 credit_max = 0;
118	u8 i = 0;
119
120	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
121	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
122
123	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
124	/* Enable Arbiter */
125	reg &= ~IXGBE_RMCS_ARBDIS;
126	/* Enable Receive Recycle within the BWG */
127	reg |= IXGBE_RMCS_RRM;
128	/* Enable Deficit Fixed Priority arbitration*/
129	reg |= IXGBE_RMCS_DFP;
130
131	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
132
133	/* Configure traffic class credits and priority */
134	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
135		credit_refill = refill[i];
136		credit_max = max[i];
137
138		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
139
140		if (tsa[i] == ixgbe_dcb_tsa_strict)
141			reg |= IXGBE_RT2CR_LSP;
142
143		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
144	}
145
146	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
147	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
148	reg |= IXGBE_RDRXCTL_MPBEN;
149	reg |= IXGBE_RDRXCTL_MCEN;
150	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
151
152	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
153	/* Make sure there is enough descriptors before arbitration */
154	reg &= ~IXGBE_RXCTRL_DMBYPS;
155	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
156
157	return IXGBE_SUCCESS;
158}
159
160/**
161 * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
162 * @hw: pointer to hardware structure
163 * @refill: refill credits index by traffic class
164 * @max: max credits index by traffic class
165 * @bwg_id: bandwidth grouping indexed by traffic class
166 * @tsa: transmission selection algorithm indexed by traffic class
167 *
168 * Configure Tx Descriptor Arbiter and credits for each traffic class.
169 */
170s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
171					   u16 *refill, u16 *max, u8 *bwg_id,
172					   u8 *tsa)
173{
174	u32 reg, max_credits;
175	u8 i;
176
177	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
178
179	/* Enable arbiter */
180	reg &= ~IXGBE_DPMCS_ARBDIS;
181	reg |= IXGBE_DPMCS_TSOEF;
182
183	/* Configure Max TSO packet size 34KB including payload and headers */
184	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
185
186	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
187
188	/* Configure traffic class credits and priority */
189	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
190		max_credits = max[i];
191		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
192		reg |= (u32)(refill[i]);
193		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
194
195		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
196			reg |= IXGBE_TDTQ2TCCR_GSP;
197
198		if (tsa[i] == ixgbe_dcb_tsa_strict)
199			reg |= IXGBE_TDTQ2TCCR_LSP;
200
201		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
202	}
203
204	return IXGBE_SUCCESS;
205}
206
207/**
208 * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
209 * @hw: pointer to hardware structure
210 * @refill: refill credits index by traffic class
211 * @max: max credits index by traffic class
212 * @bwg_id: bandwidth grouping indexed by traffic class
213 * @tsa: transmission selection algorithm indexed by traffic class
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 * @pfc_en: enabled pfc bitmask
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 * @link_speed: unused
343 * @refill: refill credits index by traffic class
344 * @max: max credits index by traffic class
345 * @bwg_id: bandwidth grouping indexed by traffic class
346 * @tsa: transmission selection algorithm indexed by traffic class
347 *
348 * Configure dcb settings and enable dcb mode.
349 */
350s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed,
351			      u16 *refill, u16 *max, u8 *bwg_id,
352			      u8 *tsa)
353{
354	UNREFERENCED_1PARAMETER(link_speed);
355
356	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
357	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
358					       tsa);
359	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
360					       tsa);
361	ixgbe_dcb_config_tc_stats_82598(hw);
362
363
364	return IXGBE_SUCCESS;
365}
366