1dee1ad47SJeff Kirsher /*******************************************************************************
2dee1ad47SJeff Kirsher 
3dee1ad47SJeff Kirsher   Intel 10 Gigabit PCI Express Linux driver
494971820SDon Skidmore   Copyright(c) 1999 - 2012 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
37dee1ad47SJeff Kirsher  * @dcb_config: pointer to ixgbe_dcb_config structure
38dee1ad47SJeff Kirsher  *
39dee1ad47SJeff Kirsher  * Configure Rx Data Arbiter and credits for each traffic class.
40dee1ad47SJeff Kirsher  */
41dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
42dee1ad47SJeff Kirsher 					u16 *refill,
43dee1ad47SJeff Kirsher 					u16 *max,
44dee1ad47SJeff Kirsher 					u8 *prio_type)
45dee1ad47SJeff Kirsher {
46dee1ad47SJeff Kirsher 	u32    reg           = 0;
47dee1ad47SJeff Kirsher 	u32    credit_refill = 0;
48dee1ad47SJeff Kirsher 	u32    credit_max    = 0;
49dee1ad47SJeff Kirsher 	u8     i             = 0;
50dee1ad47SJeff Kirsher 
51dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
52dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
53dee1ad47SJeff Kirsher 
54dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
55dee1ad47SJeff Kirsher 	/* Enable Arbiter */
56dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RMCS_ARBDIS;
57dee1ad47SJeff Kirsher 	/* Enable Receive Recycle within the BWG */
58dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_RRM;
59dee1ad47SJeff Kirsher 	/* Enable Deficit Fixed Priority arbitration*/
60dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_DFP;
61dee1ad47SJeff Kirsher 
62dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
63dee1ad47SJeff Kirsher 
64dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
65dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
66dee1ad47SJeff Kirsher 		credit_refill = refill[i];
67dee1ad47SJeff Kirsher 		credit_max    = max[i];
68dee1ad47SJeff Kirsher 
69dee1ad47SJeff Kirsher 		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
70dee1ad47SJeff Kirsher 
71dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
72dee1ad47SJeff Kirsher 			reg |= IXGBE_RT2CR_LSP;
73dee1ad47SJeff Kirsher 
74dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
75dee1ad47SJeff Kirsher 	}
76dee1ad47SJeff Kirsher 
77dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
78dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
79dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_MPBEN;
80dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_MCEN;
81dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
82dee1ad47SJeff Kirsher 
83dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
84dee1ad47SJeff Kirsher 	/* Make sure there is enough descriptors before arbitration */
85dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RXCTRL_DMBYPS;
86dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
87dee1ad47SJeff Kirsher 
88dee1ad47SJeff Kirsher 	return 0;
89dee1ad47SJeff Kirsher }
90dee1ad47SJeff Kirsher 
91dee1ad47SJeff Kirsher /**
92dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
93dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
94dee1ad47SJeff Kirsher  * @dcb_config: pointer to ixgbe_dcb_config structure
95dee1ad47SJeff Kirsher  *
96dee1ad47SJeff Kirsher  * Configure Tx Descriptor Arbiter and credits for each traffic class.
97dee1ad47SJeff Kirsher  */
98dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
99dee1ad47SJeff Kirsher 						u16 *refill,
100dee1ad47SJeff Kirsher 						u16 *max,
101dee1ad47SJeff Kirsher 						u8 *bwg_id,
102dee1ad47SJeff Kirsher 						u8 *prio_type)
103dee1ad47SJeff Kirsher {
104dee1ad47SJeff Kirsher 	u32    reg, max_credits;
105dee1ad47SJeff Kirsher 	u8     i;
106dee1ad47SJeff Kirsher 
107dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
108dee1ad47SJeff Kirsher 
109dee1ad47SJeff Kirsher 	/* Enable arbiter */
110dee1ad47SJeff Kirsher 	reg &= ~IXGBE_DPMCS_ARBDIS;
111dee1ad47SJeff Kirsher 	/* Enable DFP and Recycle mode */
112dee1ad47SJeff Kirsher 	reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM);
113dee1ad47SJeff Kirsher 	reg |= IXGBE_DPMCS_TSOEF;
114dee1ad47SJeff Kirsher 	/* Configure Max TSO packet size 34KB including payload and headers */
115dee1ad47SJeff Kirsher 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
116dee1ad47SJeff Kirsher 
117dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
118dee1ad47SJeff Kirsher 
119dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
120dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
121dee1ad47SJeff Kirsher 		max_credits = max[i];
122dee1ad47SJeff Kirsher 		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
123dee1ad47SJeff Kirsher 		reg |= refill[i];
124dee1ad47SJeff Kirsher 		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
125dee1ad47SJeff Kirsher 
126dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_group)
127dee1ad47SJeff Kirsher 			reg |= IXGBE_TDTQ2TCCR_GSP;
128dee1ad47SJeff Kirsher 
129dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
130dee1ad47SJeff Kirsher 			reg |= IXGBE_TDTQ2TCCR_LSP;
131dee1ad47SJeff Kirsher 
132dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
133dee1ad47SJeff Kirsher 	}
134dee1ad47SJeff Kirsher 
135dee1ad47SJeff Kirsher 	return 0;
136dee1ad47SJeff Kirsher }
137dee1ad47SJeff Kirsher 
138dee1ad47SJeff Kirsher /**
139dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
140dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
141dee1ad47SJeff Kirsher  * @dcb_config: pointer to ixgbe_dcb_config structure
142dee1ad47SJeff Kirsher  *
143dee1ad47SJeff Kirsher  * Configure Tx Data Arbiter and credits for each traffic class.
144dee1ad47SJeff Kirsher  */
145dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
146dee1ad47SJeff Kirsher 						u16 *refill,
147dee1ad47SJeff Kirsher 						u16 *max,
148dee1ad47SJeff Kirsher 						u8 *bwg_id,
149dee1ad47SJeff Kirsher 						u8 *prio_type)
150dee1ad47SJeff Kirsher {
151dee1ad47SJeff Kirsher 	u32 reg;
152dee1ad47SJeff Kirsher 	u8 i;
153dee1ad47SJeff Kirsher 
154dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
155dee1ad47SJeff Kirsher 	/* Enable Data Plane Arbiter */
156dee1ad47SJeff Kirsher 	reg &= ~IXGBE_PDPMCS_ARBDIS;
157dee1ad47SJeff Kirsher 	/* Enable DFP and Transmit Recycle Mode */
158dee1ad47SJeff Kirsher 	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
159dee1ad47SJeff Kirsher 
160dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
161dee1ad47SJeff Kirsher 
162dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
163dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
164dee1ad47SJeff Kirsher 		reg = refill[i];
165dee1ad47SJeff Kirsher 		reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
166dee1ad47SJeff Kirsher 		reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
167dee1ad47SJeff Kirsher 
168dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_group)
169dee1ad47SJeff Kirsher 			reg |= IXGBE_TDPT2TCCR_GSP;
170dee1ad47SJeff Kirsher 
171dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
172dee1ad47SJeff Kirsher 			reg |= IXGBE_TDPT2TCCR_LSP;
173dee1ad47SJeff Kirsher 
174dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
175dee1ad47SJeff Kirsher 	}
176dee1ad47SJeff Kirsher 
177dee1ad47SJeff Kirsher 	/* Enable Tx packet buffer division */
178dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
179dee1ad47SJeff Kirsher 	reg |= IXGBE_DTXCTL_ENDBUBD;
180dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
181dee1ad47SJeff Kirsher 
182dee1ad47SJeff Kirsher 	return 0;
183dee1ad47SJeff Kirsher }
184dee1ad47SJeff Kirsher 
185dee1ad47SJeff Kirsher /**
186dee1ad47SJeff Kirsher  * ixgbe_dcb_config_pfc_82598 - Config priority flow control
187dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
188dee1ad47SJeff Kirsher  * @dcb_config: pointer to ixgbe_dcb_config structure
189dee1ad47SJeff Kirsher  *
190dee1ad47SJeff Kirsher  * Configure Priority Flow Control for each traffic class.
191dee1ad47SJeff Kirsher  */
192dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
193dee1ad47SJeff Kirsher {
194943561d3SAlexander Duyck 	u32 fcrtl, reg;
195dee1ad47SJeff Kirsher 	u8  i;
196dee1ad47SJeff Kirsher 
197dee1ad47SJeff Kirsher 	/* Enable Transmit Priority Flow Control */
198dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
199dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RMCS_TFCE_802_3X;
200dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_TFCE_PRIORITY;
201dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
202dee1ad47SJeff Kirsher 
203dee1ad47SJeff Kirsher 	/* Enable Receive Priority Flow Control */
204dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
205943561d3SAlexander Duyck 	reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
206943561d3SAlexander Duyck 
207943561d3SAlexander Duyck 	if (pfc_en)
208dee1ad47SJeff Kirsher 		reg |= IXGBE_FCTRL_RPFCE;
209943561d3SAlexander Duyck 
210dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
211dee1ad47SJeff Kirsher 
212943561d3SAlexander Duyck 	fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
213943561d3SAlexander Duyck 	/* Configure PFC Tx thresholds per TC */
214943561d3SAlexander Duyck 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
215943561d3SAlexander Duyck 		if (!(pfc_en & (1 << i))) {
216943561d3SAlexander Duyck 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
217943561d3SAlexander Duyck 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
218943561d3SAlexander Duyck 			continue;
219dee1ad47SJeff Kirsher 		}
220dee1ad47SJeff Kirsher 
221943561d3SAlexander Duyck 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
222943561d3SAlexander Duyck 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
223dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
224dee1ad47SJeff Kirsher 	}
225dee1ad47SJeff Kirsher 
226943561d3SAlexander Duyck 	/* Configure pause time */
227943561d3SAlexander Duyck 	reg = hw->fc.pause_time * 0x00010001;
228943561d3SAlexander Duyck 	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
229943561d3SAlexander Duyck 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
230943561d3SAlexander Duyck 
231943561d3SAlexander Duyck 	/* Configure flow control refresh threshold value */
232943561d3SAlexander Duyck 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
233943561d3SAlexander Duyck 
234943561d3SAlexander Duyck 
235dee1ad47SJeff Kirsher 	return 0;
236dee1ad47SJeff Kirsher }
237dee1ad47SJeff Kirsher 
238dee1ad47SJeff Kirsher /**
239dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
240dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
241dee1ad47SJeff Kirsher  *
242dee1ad47SJeff Kirsher  * Configure queue statistics registers, all queues belonging to same traffic
243dee1ad47SJeff Kirsher  * class uses a single set of queue statistics counters.
244dee1ad47SJeff Kirsher  */
245dee1ad47SJeff Kirsher static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
246dee1ad47SJeff Kirsher {
247dee1ad47SJeff Kirsher 	u32 reg = 0;
248dee1ad47SJeff Kirsher 	u8  i   = 0;
249dee1ad47SJeff Kirsher 	u8  j   = 0;
250dee1ad47SJeff Kirsher 
251dee1ad47SJeff Kirsher 	/* Receive Queues stats setting -  8 queues per statistics reg */
252dee1ad47SJeff Kirsher 	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
253dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
254dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * j);
255dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
256dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
257dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * j);
258dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
259dee1ad47SJeff Kirsher 	}
260dee1ad47SJeff Kirsher 	/* Transmit Queues stats setting -  4 queues per statistics reg */
261dee1ad47SJeff Kirsher 	for (i = 0; i < 8; i++) {
262dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
263dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * i);
264dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
265dee1ad47SJeff Kirsher 	}
266dee1ad47SJeff Kirsher 
267dee1ad47SJeff Kirsher 	return 0;
268dee1ad47SJeff Kirsher }
269dee1ad47SJeff Kirsher 
270dee1ad47SJeff Kirsher /**
271dee1ad47SJeff Kirsher  * ixgbe_dcb_hw_config_82598 - Config and enable DCB
272dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
273dee1ad47SJeff Kirsher  * @dcb_config: pointer to ixgbe_dcb_config structure
274dee1ad47SJeff Kirsher  *
275dee1ad47SJeff Kirsher  * Configure dcb settings and enable dcb mode.
276dee1ad47SJeff Kirsher  */
277dee1ad47SJeff Kirsher s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill,
278dee1ad47SJeff Kirsher 			      u16 *max, u8 *bwg_id, u8 *prio_type)
279dee1ad47SJeff Kirsher {
280dee1ad47SJeff Kirsher 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type);
281dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
282dee1ad47SJeff Kirsher 					       bwg_id, prio_type);
283dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
284dee1ad47SJeff Kirsher 					       bwg_id, prio_type);
285dee1ad47SJeff Kirsher 	ixgbe_dcb_config_pfc_82598(hw, pfc_en);
286dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tc_stats_82598(hw);
287dee1ad47SJeff Kirsher 
288dee1ad47SJeff Kirsher 	return 0;
289dee1ad47SJeff Kirsher }
290