1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
2dee1ad47SJeff Kirsher /*******************************************************************************
3dee1ad47SJeff Kirsher 
4dee1ad47SJeff Kirsher   Intel 10 Gigabit PCI Express Linux driver
5434c5e39SDon Skidmore   Copyright(c) 1999 - 2013 Intel Corporation.
6dee1ad47SJeff Kirsher 
7dee1ad47SJeff Kirsher   This program is free software; you can redistribute it and/or modify it
8dee1ad47SJeff Kirsher   under the terms and conditions of the GNU General Public License,
9dee1ad47SJeff Kirsher   version 2, as published by the Free Software Foundation.
10dee1ad47SJeff Kirsher 
11dee1ad47SJeff Kirsher   This program is distributed in the hope it will be useful, but WITHOUT
12dee1ad47SJeff Kirsher   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13dee1ad47SJeff Kirsher   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14dee1ad47SJeff Kirsher   more details.
15dee1ad47SJeff Kirsher 
16dee1ad47SJeff Kirsher   You should have received a copy of the GNU General Public License along with
17dee1ad47SJeff Kirsher   this program; if not, write to the Free Software Foundation, Inc.,
18dee1ad47SJeff Kirsher   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19dee1ad47SJeff Kirsher 
20dee1ad47SJeff Kirsher   The full GNU General Public License is included in this distribution in
21dee1ad47SJeff Kirsher   the file called "COPYING".
22dee1ad47SJeff Kirsher 
23dee1ad47SJeff Kirsher   Contact Information:
24dee1ad47SJeff Kirsher   Linux NICS <linux.nics@intel.com>
25dee1ad47SJeff Kirsher   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
26dee1ad47SJeff Kirsher   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27dee1ad47SJeff Kirsher 
28dee1ad47SJeff Kirsher *******************************************************************************/
29dee1ad47SJeff Kirsher 
30dee1ad47SJeff Kirsher #include "ixgbe.h"
31dee1ad47SJeff Kirsher #include "ixgbe_type.h"
32dee1ad47SJeff Kirsher #include "ixgbe_dcb.h"
33dee1ad47SJeff Kirsher #include "ixgbe_dcb_82598.h"
34dee1ad47SJeff Kirsher 
35dee1ad47SJeff Kirsher /**
36dee1ad47SJeff Kirsher  * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
37dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
385ba643c6STony Nguyen  * @refill: refill credits index by traffic class
395ba643c6STony Nguyen  * @max: max credits index by traffic class
405ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
41dee1ad47SJeff Kirsher  *
42dee1ad47SJeff Kirsher  * Configure Rx Data Arbiter and credits for each traffic class.
43dee1ad47SJeff Kirsher  */
44dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
45dee1ad47SJeff Kirsher 					u16 *refill,
46dee1ad47SJeff Kirsher 					u16 *max,
47dee1ad47SJeff Kirsher 					u8 *prio_type)
48dee1ad47SJeff Kirsher {
49dee1ad47SJeff Kirsher 	u32    reg           = 0;
50dee1ad47SJeff Kirsher 	u32    credit_refill = 0;
51dee1ad47SJeff Kirsher 	u32    credit_max    = 0;
52dee1ad47SJeff Kirsher 	u8     i             = 0;
53dee1ad47SJeff Kirsher 
54dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
55dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
56dee1ad47SJeff Kirsher 
57dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
58dee1ad47SJeff Kirsher 	/* Enable Arbiter */
59dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RMCS_ARBDIS;
60dee1ad47SJeff Kirsher 	/* Enable Receive Recycle within the BWG */
61dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_RRM;
62dee1ad47SJeff Kirsher 	/* Enable Deficit Fixed Priority arbitration*/
63dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_DFP;
64dee1ad47SJeff Kirsher 
65dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
66dee1ad47SJeff Kirsher 
67dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
68dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
69dee1ad47SJeff Kirsher 		credit_refill = refill[i];
70dee1ad47SJeff Kirsher 		credit_max    = max[i];
71dee1ad47SJeff Kirsher 
72dee1ad47SJeff Kirsher 		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
73dee1ad47SJeff Kirsher 
74dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
75dee1ad47SJeff Kirsher 			reg |= IXGBE_RT2CR_LSP;
76dee1ad47SJeff Kirsher 
77dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
78dee1ad47SJeff Kirsher 	}
79dee1ad47SJeff Kirsher 
80dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
81dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
82dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_MPBEN;
83dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_MCEN;
84dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
85dee1ad47SJeff Kirsher 
86dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
87dee1ad47SJeff Kirsher 	/* Make sure there is enough descriptors before arbitration */
88dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RXCTRL_DMBYPS;
89dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
90dee1ad47SJeff Kirsher 
91dee1ad47SJeff Kirsher 	return 0;
92dee1ad47SJeff Kirsher }
93dee1ad47SJeff Kirsher 
94dee1ad47SJeff Kirsher /**
95dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
96dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
975ba643c6STony Nguyen  * @refill: refill credits index by traffic class
985ba643c6STony Nguyen  * @max: max credits index by traffic class
995ba643c6STony Nguyen  * @bwg_id: bandwidth grouping indexed by traffic class
1005ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
101dee1ad47SJeff Kirsher  *
102dee1ad47SJeff Kirsher  * Configure Tx Descriptor Arbiter and credits for each traffic class.
103dee1ad47SJeff Kirsher  */
104dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
105dee1ad47SJeff Kirsher 						u16 *refill,
106dee1ad47SJeff Kirsher 						u16 *max,
107dee1ad47SJeff Kirsher 						u8 *bwg_id,
108dee1ad47SJeff Kirsher 						u8 *prio_type)
109dee1ad47SJeff Kirsher {
110dee1ad47SJeff Kirsher 	u32    reg, max_credits;
111dee1ad47SJeff Kirsher 	u8     i;
112dee1ad47SJeff Kirsher 
113dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
114dee1ad47SJeff Kirsher 
115dee1ad47SJeff Kirsher 	/* Enable arbiter */
116dee1ad47SJeff Kirsher 	reg &= ~IXGBE_DPMCS_ARBDIS;
117dee1ad47SJeff Kirsher 	reg |= IXGBE_DPMCS_TSOEF;
1181eb9ac14SJacob Keller 
119dee1ad47SJeff Kirsher 	/* Configure Max TSO packet size 34KB including payload and headers */
120dee1ad47SJeff Kirsher 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
121dee1ad47SJeff Kirsher 
122dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
123dee1ad47SJeff Kirsher 
124dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
125dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
126dee1ad47SJeff Kirsher 		max_credits = max[i];
127dee1ad47SJeff Kirsher 		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
128dee1ad47SJeff Kirsher 		reg |= refill[i];
129dee1ad47SJeff Kirsher 		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
130dee1ad47SJeff Kirsher 
131dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_group)
132dee1ad47SJeff Kirsher 			reg |= IXGBE_TDTQ2TCCR_GSP;
133dee1ad47SJeff Kirsher 
134dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
135dee1ad47SJeff Kirsher 			reg |= IXGBE_TDTQ2TCCR_LSP;
136dee1ad47SJeff Kirsher 
137dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
138dee1ad47SJeff Kirsher 	}
139dee1ad47SJeff Kirsher 
140dee1ad47SJeff Kirsher 	return 0;
141dee1ad47SJeff Kirsher }
142dee1ad47SJeff Kirsher 
143dee1ad47SJeff Kirsher /**
144dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
145dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
1465ba643c6STony Nguyen  * @refill: refill credits index by traffic class
1475ba643c6STony Nguyen  * @max: max credits index by traffic class
1485ba643c6STony Nguyen  * @bwg_id: bandwidth grouping indexed by traffic class
1495ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
150dee1ad47SJeff Kirsher  *
151dee1ad47SJeff Kirsher  * Configure Tx Data Arbiter and credits for each traffic class.
152dee1ad47SJeff Kirsher  */
153dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
154dee1ad47SJeff Kirsher 						u16 *refill,
155dee1ad47SJeff Kirsher 						u16 *max,
156dee1ad47SJeff Kirsher 						u8 *bwg_id,
157dee1ad47SJeff Kirsher 						u8 *prio_type)
158dee1ad47SJeff Kirsher {
159dee1ad47SJeff Kirsher 	u32 reg;
160dee1ad47SJeff Kirsher 	u8 i;
161dee1ad47SJeff Kirsher 
162dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
163dee1ad47SJeff Kirsher 	/* Enable Data Plane Arbiter */
164dee1ad47SJeff Kirsher 	reg &= ~IXGBE_PDPMCS_ARBDIS;
165dee1ad47SJeff Kirsher 	/* Enable DFP and Transmit Recycle Mode */
166dee1ad47SJeff Kirsher 	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
167dee1ad47SJeff Kirsher 
168dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
169dee1ad47SJeff Kirsher 
170dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
171dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
172dee1ad47SJeff Kirsher 		reg = refill[i];
173dee1ad47SJeff Kirsher 		reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
174dee1ad47SJeff Kirsher 		reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
175dee1ad47SJeff Kirsher 
176dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_group)
177dee1ad47SJeff Kirsher 			reg |= IXGBE_TDPT2TCCR_GSP;
178dee1ad47SJeff Kirsher 
179dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
180dee1ad47SJeff Kirsher 			reg |= IXGBE_TDPT2TCCR_LSP;
181dee1ad47SJeff Kirsher 
182dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
183dee1ad47SJeff Kirsher 	}
184dee1ad47SJeff Kirsher 
185dee1ad47SJeff Kirsher 	/* Enable Tx packet buffer division */
186dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
187dee1ad47SJeff Kirsher 	reg |= IXGBE_DTXCTL_ENDBUBD;
188dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
189dee1ad47SJeff Kirsher 
190dee1ad47SJeff Kirsher 	return 0;
191dee1ad47SJeff Kirsher }
192dee1ad47SJeff Kirsher 
193dee1ad47SJeff Kirsher /**
194dee1ad47SJeff Kirsher  * ixgbe_dcb_config_pfc_82598 - Config priority flow control
195dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
1965ba643c6STony Nguyen  * @pfc_en: enabled pfc bitmask
197dee1ad47SJeff Kirsher  *
198dee1ad47SJeff Kirsher  * Configure Priority Flow Control for each traffic class.
199dee1ad47SJeff Kirsher  */
200dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
201dee1ad47SJeff Kirsher {
202943561d3SAlexander Duyck 	u32 fcrtl, reg;
203dee1ad47SJeff Kirsher 	u8  i;
204dee1ad47SJeff Kirsher 
205dee1ad47SJeff Kirsher 	/* Enable Transmit Priority Flow Control */
206dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
207dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RMCS_TFCE_802_3X;
208dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_TFCE_PRIORITY;
209dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
210dee1ad47SJeff Kirsher 
211dee1ad47SJeff Kirsher 	/* Enable Receive Priority Flow Control */
212dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
213943561d3SAlexander Duyck 	reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
214943561d3SAlexander Duyck 
215943561d3SAlexander Duyck 	if (pfc_en)
216dee1ad47SJeff Kirsher 		reg |= IXGBE_FCTRL_RPFCE;
217943561d3SAlexander Duyck 
218dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
219dee1ad47SJeff Kirsher 
220943561d3SAlexander Duyck 	/* Configure PFC Tx thresholds per TC */
221943561d3SAlexander Duyck 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
222b4f47a48SJacob Keller 		if (!(pfc_en & BIT(i))) {
223943561d3SAlexander Duyck 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
224943561d3SAlexander Duyck 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
225943561d3SAlexander Duyck 			continue;
226dee1ad47SJeff Kirsher 		}
227dee1ad47SJeff Kirsher 
228e5776620SJacob Keller 		fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
229943561d3SAlexander Duyck 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
230943561d3SAlexander Duyck 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
231dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
232dee1ad47SJeff Kirsher 	}
233dee1ad47SJeff Kirsher 
234943561d3SAlexander Duyck 	/* Configure pause time */
235943561d3SAlexander Duyck 	reg = hw->fc.pause_time * 0x00010001;
236943561d3SAlexander Duyck 	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
237943561d3SAlexander Duyck 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
238943561d3SAlexander Duyck 
239943561d3SAlexander Duyck 	/* Configure flow control refresh threshold value */
240943561d3SAlexander Duyck 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
241943561d3SAlexander Duyck 
242943561d3SAlexander Duyck 
243dee1ad47SJeff Kirsher 	return 0;
244dee1ad47SJeff Kirsher }
245dee1ad47SJeff Kirsher 
246dee1ad47SJeff Kirsher /**
247dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
248dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
249dee1ad47SJeff Kirsher  *
250dee1ad47SJeff Kirsher  * Configure queue statistics registers, all queues belonging to same traffic
251dee1ad47SJeff Kirsher  * class uses a single set of queue statistics counters.
252dee1ad47SJeff Kirsher  */
253dee1ad47SJeff Kirsher static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
254dee1ad47SJeff Kirsher {
255dee1ad47SJeff Kirsher 	u32 reg = 0;
256dee1ad47SJeff Kirsher 	u8  i   = 0;
257dee1ad47SJeff Kirsher 	u8  j   = 0;
258dee1ad47SJeff Kirsher 
259dee1ad47SJeff Kirsher 	/* Receive Queues stats setting -  8 queues per statistics reg */
260dee1ad47SJeff Kirsher 	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
261dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
262dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * j);
263dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
264dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
265dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * j);
266dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
267dee1ad47SJeff Kirsher 	}
268dee1ad47SJeff Kirsher 	/* Transmit Queues stats setting -  4 queues per statistics reg */
269dee1ad47SJeff Kirsher 	for (i = 0; i < 8; i++) {
270dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
271dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * i);
272dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
273dee1ad47SJeff Kirsher 	}
274dee1ad47SJeff Kirsher 
275dee1ad47SJeff Kirsher 	return 0;
276dee1ad47SJeff Kirsher }
277dee1ad47SJeff Kirsher 
278dee1ad47SJeff Kirsher /**
279dee1ad47SJeff Kirsher  * ixgbe_dcb_hw_config_82598 - Config and enable DCB
280dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
2815ba643c6STony Nguyen  * @pfc_en: enabled pfc bitmask
2825ba643c6STony Nguyen  * @refill: refill credits index by traffic class
2835ba643c6STony Nguyen  * @max: max credits index by traffic class
2845ba643c6STony Nguyen  * @bwg_id: bandwidth grouping indexed by traffic class
2855ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
286dee1ad47SJeff Kirsher  *
287dee1ad47SJeff Kirsher  * Configure dcb settings and enable dcb mode.
288dee1ad47SJeff Kirsher  */
289dee1ad47SJeff Kirsher s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill,
290dee1ad47SJeff Kirsher 			      u16 *max, u8 *bwg_id, u8 *prio_type)
291dee1ad47SJeff Kirsher {
292dee1ad47SJeff Kirsher 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type);
293dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
294dee1ad47SJeff Kirsher 					       bwg_id, prio_type);
295dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
296dee1ad47SJeff Kirsher 					       bwg_id, prio_type);
297dee1ad47SJeff Kirsher 	ixgbe_dcb_config_pfc_82598(hw, pfc_en);
298dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tc_stats_82598(hw);
299dee1ad47SJeff Kirsher 
300dee1ad47SJeff Kirsher 	return 0;
301dee1ad47SJeff Kirsher }
302