1 /******************************************************************************
   2 
   3   Copyright (c) 2001-2015, 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         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 }