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