1 /****************************************************************************** 2 3 Copyright (c) 2001-2013, 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$*/ 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 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa); 351 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id, 352 tsa); 353 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id, 354 tsa); 355 ixgbe_dcb_config_tc_stats_82598(hw); 356 357 358 return IXGBE_SUCCESS; 359 } 360