PageRenderTime 91ms CodeModel.GetById 75ms app.highlight 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/kernel/drivers/net/ixgbe/ixgbe_dcb_82598.c

https://github.com/ccampos784/sch-i500-gingerbread
C | 401 lines | 214 code | 59 blank | 128 comment | 37 complexity | 7967d927587b2838bfe58a42a196a386 MD5 | raw file
  1/*******************************************************************************
  2
  3  Intel 10 Gigabit PCI Express Linux driver
  4  Copyright(c) 1999 - 2010 Intel Corporation.
  5
  6  This program is free software; you can redistribute it and/or modify it
  7  under the terms and conditions of the GNU General Public License,
  8  version 2, as published by the Free Software Foundation.
  9
 10  This program is distributed in the hope it will be useful, but WITHOUT
 11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 13  more details.
 14
 15  You should have received a copy of the GNU General Public License along with
 16  this program; if not, write to the Free Software Foundation, Inc.,
 17  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 18
 19  The full GNU General Public License is included in this distribution in
 20  the file called "COPYING".
 21
 22  Contact Information:
 23  Linux NICS <linux.nics@intel.com>
 24  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 25  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 26
 27*******************************************************************************/
 28
 29#include "ixgbe.h"
 30#include "ixgbe_type.h"
 31#include "ixgbe_dcb.h"
 32#include "ixgbe_dcb_82598.h"
 33
 34/**
 35 * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class
 36 * @hw: pointer to hardware structure
 37 * @stats: pointer to statistics structure
 38 * @tc_count:  Number of elements in bwg_array.
 39 *
 40 * This function returns the status data for each of the Traffic Classes in use.
 41 */
 42s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw,
 43                                 struct ixgbe_hw_stats *stats,
 44                                 u8 tc_count)
 45{
 46	int tc;
 47
 48	if (tc_count > MAX_TRAFFIC_CLASS)
 49		return DCB_ERR_PARAM;
 50
 51	/* Statistics pertaining to each traffic class */
 52	for (tc = 0; tc < tc_count; tc++) {
 53		/* Transmitted Packets */
 54		stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
 55		/* Transmitted Bytes */
 56		stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
 57		/* Received Packets */
 58		stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
 59		/* Received Bytes */
 60		stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
 61	}
 62
 63	return 0;
 64}
 65
 66/**
 67 * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
 68 * @hw: pointer to hardware structure
 69 * @stats: pointer to statistics structure
 70 * @tc_count:  Number of elements in bwg_array.
 71 *
 72 * This function returns the CBFC status data for each of the Traffic Classes.
 73 */
 74s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
 75                                  struct ixgbe_hw_stats *stats,
 76                                  u8 tc_count)
 77{
 78	int tc;
 79
 80	if (tc_count > MAX_TRAFFIC_CLASS)
 81		return DCB_ERR_PARAM;
 82
 83	for (tc = 0; tc < tc_count; tc++) {
 84		/* Priority XOFF Transmitted */
 85		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
 86		/* Priority XOFF Received */
 87		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
 88	}
 89
 90	return 0;
 91}
 92
 93/**
 94 * ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers
 95 * @hw: pointer to hardware structure
 96 * @dcb_config: pointer to ixgbe_dcb_config structure
 97 *
 98 * Configure packet buffers for DCB mode.
 99 */
100static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw,
101						 struct ixgbe_dcb_config *dcb_config)
102{
103	s32 ret_val = 0;
104	u32 value = IXGBE_RXPBSIZE_64KB;
105	u8  i = 0;
106
107	/* Setup Rx packet buffer sizes */
108	switch (dcb_config->rx_pba_cfg) {
109	case pba_80_48:
110		/* Setup the first four at 80KB */
111		value = IXGBE_RXPBSIZE_80KB;
112		for (; i < 4; i++)
113			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
114		/* Setup the last four at 48KB...don't re-init i */
115		value = IXGBE_RXPBSIZE_48KB;
116		/* Fall Through */
117	case pba_equal:
118	default:
119		for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
120			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
121
122		/* Setup Tx packet buffer sizes */
123		for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
124			IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
125					IXGBE_TXPBSIZE_40KB);
126		}
127		break;
128	}
129
130	return ret_val;
131}
132
133/**
134 * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
135 * @hw: pointer to hardware structure
136 * @dcb_config: pointer to ixgbe_dcb_config structure
137 *
138 * Configure Rx Data Arbiter and credits for each traffic class.
139 */
140s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
141                                      struct ixgbe_dcb_config *dcb_config)
142{
143	struct tc_bw_alloc    *p;
144	u32    reg           = 0;
145	u32    credit_refill = 0;
146	u32    credit_max    = 0;
147	u8     i             = 0;
148
149	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
150	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
151
152	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
153	/* Enable Arbiter */
154	reg &= ~IXGBE_RMCS_ARBDIS;
155	/* Enable Receive Recycle within the BWG */
156	reg |= IXGBE_RMCS_RRM;
157	/* Enable Deficit Fixed Priority arbitration*/
158	reg |= IXGBE_RMCS_DFP;
159
160	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
161
162	/* Configure traffic class credits and priority */
163	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
164		p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
165		credit_refill = p->data_credits_refill;
166		credit_max    = p->data_credits_max;
167
168		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
169
170		if (p->prio_type == prio_link)
171			reg |= IXGBE_RT2CR_LSP;
172
173		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
174	}
175
176	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
177	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
178	reg |= IXGBE_RDRXCTL_MPBEN;
179	reg |= IXGBE_RDRXCTL_MCEN;
180	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
181
182	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
183	/* Make sure there is enough descriptors before arbitration */
184	reg &= ~IXGBE_RXCTRL_DMBYPS;
185	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
186
187	return 0;
188}
189
190/**
191 * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
192 * @hw: pointer to hardware structure
193 * @dcb_config: pointer to ixgbe_dcb_config structure
194 *
195 * Configure Tx Descriptor Arbiter and credits for each traffic class.
196 */
197s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
198                                           struct ixgbe_dcb_config *dcb_config)
199{
200	struct tc_bw_alloc *p;
201	u32    reg, max_credits;
202	u8     i;
203
204	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
205
206	/* Enable arbiter */
207	reg &= ~IXGBE_DPMCS_ARBDIS;
208	if (!(dcb_config->round_robin_enable)) {
209		/* Enable DFP and Recycle mode */
210		reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM);
211	}
212	reg |= IXGBE_DPMCS_TSOEF;
213	/* Configure Max TSO packet size 34KB including payload and headers */
214	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
215
216	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
217
218	/* Configure traffic class credits and priority */
219	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
220		p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
221		max_credits = dcb_config->tc_config[i].desc_credits_max;
222		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
223		reg |= p->data_credits_refill;
224		reg |= (u32)(p->bwg_id) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
225
226		if (p->prio_type == prio_group)
227			reg |= IXGBE_TDTQ2TCCR_GSP;
228
229		if (p->prio_type == prio_link)
230			reg |= IXGBE_TDTQ2TCCR_LSP;
231
232		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
233	}
234
235	return 0;
236}
237
238/**
239 * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
240 * @hw: pointer to hardware structure
241 * @dcb_config: pointer to ixgbe_dcb_config structure
242 *
243 * Configure Tx Data Arbiter and credits for each traffic class.
244 */
245s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
246                                           struct ixgbe_dcb_config *dcb_config)
247{
248	struct tc_bw_alloc *p;
249	u32 reg;
250	u8 i;
251
252	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
253	/* Enable Data Plane Arbiter */
254	reg &= ~IXGBE_PDPMCS_ARBDIS;
255	/* Enable DFP and Transmit Recycle Mode */
256	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
257
258	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
259
260	/* Configure traffic class credits and priority */
261	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
262		p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
263		reg = p->data_credits_refill;
264		reg |= (u32)(p->data_credits_max) << IXGBE_TDPT2TCCR_MCL_SHIFT;
265		reg |= (u32)(p->bwg_id) << IXGBE_TDPT2TCCR_BWG_SHIFT;
266
267		if (p->prio_type == prio_group)
268			reg |= IXGBE_TDPT2TCCR_GSP;
269
270		if (p->prio_type == prio_link)
271			reg |= IXGBE_TDPT2TCCR_LSP;
272
273		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
274	}
275
276	/* Enable Tx packet buffer division */
277	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
278	reg |= IXGBE_DTXCTL_ENDBUBD;
279	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
280
281	return 0;
282}
283
284/**
285 * ixgbe_dcb_config_pfc_82598 - Config priority flow control
286 * @hw: pointer to hardware structure
287 * @dcb_config: pointer to ixgbe_dcb_config structure
288 *
289 * Configure Priority Flow Control for each traffic class.
290 */
291s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
292                               struct ixgbe_dcb_config *dcb_config)
293{
294	u32 reg, rx_pba_size;
295	u8  i;
296
297	if (!dcb_config->pfc_mode_enable)
298		goto out;
299
300	/* Enable Transmit Priority Flow Control */
301	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
302	reg &= ~IXGBE_RMCS_TFCE_802_3X;
303	/* correct the reporting of our flow control status */
304	reg |= IXGBE_RMCS_TFCE_PRIORITY;
305	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
306
307	/* Enable Receive Priority Flow Control */
308	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
309	reg &= ~IXGBE_FCTRL_RFCE;
310	reg |= IXGBE_FCTRL_RPFCE;
311	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
312
313	/*
314	 * Configure flow control thresholds and enable priority flow control
315	 * for each traffic class.
316	 */
317	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
318		if (dcb_config->rx_pba_cfg == pba_equal) {
319			rx_pba_size = IXGBE_RXPBSIZE_64KB;
320		} else {
321			rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
322					      : IXGBE_RXPBSIZE_48KB;
323		}
324
325		reg = ((rx_pba_size >> 5) &  0xFFF0);
326		if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
327		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
328			reg |= IXGBE_FCRTL_XONE;
329
330		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
331
332		reg = ((rx_pba_size >> 2) & 0xFFF0);
333		if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
334		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
335			reg |= IXGBE_FCRTH_FCEN;
336
337		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
338	}
339
340	/* Configure pause time */
341	for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++)
342		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800);
343
344	/* Configure flow control refresh threshold value */
345	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
346
347out:
348	return 0;
349}
350
351/**
352 * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
353 * @hw: pointer to hardware structure
354 *
355 * Configure queue statistics registers, all queues belonging to same traffic
356 * class uses a single set of queue statistics counters.
357 */
358s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
359{
360	u32 reg = 0;
361	u8  i   = 0;
362	u8  j   = 0;
363
364	/* Receive Queues stats setting -  8 queues per statistics reg */
365	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
366		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
367		reg |= ((0x1010101) * j);
368		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
369		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
370		reg |= ((0x1010101) * j);
371		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
372	}
373	/* Transmit Queues stats setting -  4 queues per statistics reg */
374	for (i = 0; i < 8; i++) {
375		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
376		reg |= ((0x1010101) * i);
377		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
378	}
379
380	return 0;
381}
382
383/**
384 * ixgbe_dcb_hw_config_82598 - Config and enable DCB
385 * @hw: pointer to hardware structure
386 * @dcb_config: pointer to ixgbe_dcb_config structure
387 *
388 * Configure dcb settings and enable dcb mode.
389 */
390s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw,
391                              struct ixgbe_dcb_config *dcb_config)
392{
393	ixgbe_dcb_config_packet_buffers_82598(hw, dcb_config);
394	ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
395	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
396	ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
397	ixgbe_dcb_config_pfc_82598(hw, dcb_config);
398	ixgbe_dcb_config_tc_stats_82598(hw);
399
400	return 0;
401}