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