Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 1999 - 2018 Intel Corporation. */
0003 
0004 #include "ixgbe.h"
0005 #include "ixgbe_type.h"
0006 #include "ixgbe_dcb.h"
0007 #include "ixgbe_dcb_82599.h"
0008 
0009 /**
0010  * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
0011  * @hw: pointer to hardware structure
0012  * @refill: refill credits index by traffic class
0013  * @max: max credits index by traffic class
0014  * @bwg_id: bandwidth grouping indexed by traffic class
0015  * @prio_type: priority type indexed by traffic class
0016  * @prio_tc: priority to tc assignments indexed by priority
0017  *
0018  * Configure Rx Packet Arbiter and credits for each traffic class.
0019  */
0020 s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
0021                       u16 *refill,
0022                       u16 *max,
0023                       u8 *bwg_id,
0024                       u8 *prio_type,
0025                       u8 *prio_tc)
0026 {
0027     u32    reg           = 0;
0028     u32    credit_refill = 0;
0029     u32    credit_max    = 0;
0030     u8     i             = 0;
0031 
0032     /*
0033      * Disable the arbiter before changing parameters
0034      * (always enable recycle mode; WSP)
0035      */
0036     reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC | IXGBE_RTRPCS_ARBDIS;
0037     IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
0038 
0039     /* Map all traffic classes to their UP */
0040     reg = 0;
0041     for (i = 0; i < MAX_USER_PRIORITY; i++)
0042         reg |= (prio_tc[i] << (i * IXGBE_RTRUP2TC_UP_SHIFT));
0043     IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
0044 
0045     /* Configure traffic class credits and priority */
0046     for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
0047         credit_refill = refill[i];
0048         credit_max    = max[i];
0049         reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
0050 
0051         reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT;
0052 
0053         if (prio_type[i] == prio_link)
0054             reg |= IXGBE_RTRPT4C_LSP;
0055 
0056         IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
0057     }
0058 
0059     /*
0060      * Configure Rx packet plane (recycle mode; WSP) and
0061      * enable arbiter
0062      */
0063     reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
0064     IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
0065 
0066     return 0;
0067 }
0068 
0069 /**
0070  * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
0071  * @hw: pointer to hardware structure
0072  * @refill: refill credits index by traffic class
0073  * @max: max credits index by traffic class
0074  * @bwg_id: bandwidth grouping indexed by traffic class
0075  * @prio_type: priority type indexed by traffic class
0076  *
0077  * Configure Tx Descriptor Arbiter and credits for each traffic class.
0078  */
0079 s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
0080                        u16 *refill,
0081                        u16 *max,
0082                        u8 *bwg_id,
0083                        u8 *prio_type)
0084 {
0085     u32    reg, max_credits;
0086     u8     i;
0087 
0088     /* Clear the per-Tx queue credits; we use per-TC instead */
0089     for (i = 0; i < 128; i++) {
0090         IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
0091         IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
0092     }
0093 
0094     /* Configure traffic class credits and priority */
0095     for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
0096         max_credits = max[i];
0097         reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
0098         reg |= refill[i];
0099         reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT;
0100 
0101         if (prio_type[i] == prio_group)
0102             reg |= IXGBE_RTTDT2C_GSP;
0103 
0104         if (prio_type[i] == prio_link)
0105             reg |= IXGBE_RTTDT2C_LSP;
0106 
0107         IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
0108     }
0109 
0110     /*
0111      * Configure Tx descriptor plane (recycle mode; WSP) and
0112      * enable arbiter
0113      */
0114     reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
0115     IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
0116 
0117     return 0;
0118 }
0119 
0120 /**
0121  * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
0122  * @hw: pointer to hardware structure
0123  * @refill: refill credits index by traffic class
0124  * @max: max credits index by traffic class
0125  * @bwg_id: bandwidth grouping indexed by traffic class
0126  * @prio_type: priority type indexed by traffic class
0127  * @prio_tc: priority to tc assignments indexed by priority
0128  *
0129  * Configure Tx Packet Arbiter and credits for each traffic class.
0130  */
0131 s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
0132                        u16 *refill,
0133                        u16 *max,
0134                        u8 *bwg_id,
0135                        u8 *prio_type,
0136                        u8 *prio_tc)
0137 {
0138     u32 reg;
0139     u8 i;
0140 
0141     /*
0142      * Disable the arbiter before changing parameters
0143      * (always enable recycle mode; SP; arb delay)
0144      */
0145     reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
0146           (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT) |
0147           IXGBE_RTTPCS_ARBDIS;
0148     IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
0149 
0150     /* Map all traffic classes to their UP */
0151     reg = 0;
0152     for (i = 0; i < MAX_USER_PRIORITY; i++)
0153         reg |= (prio_tc[i] << (i * IXGBE_RTTUP2TC_UP_SHIFT));
0154     IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
0155 
0156     /* Configure traffic class credits and priority */
0157     for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
0158         reg = refill[i];
0159         reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT;
0160         reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT;
0161 
0162         if (prio_type[i] == prio_group)
0163             reg |= IXGBE_RTTPT2C_GSP;
0164 
0165         if (prio_type[i] == prio_link)
0166             reg |= IXGBE_RTTPT2C_LSP;
0167 
0168         IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
0169     }
0170 
0171     /*
0172      * Configure Tx packet plane (recycle mode; SP; arb delay) and
0173      * enable arbiter
0174      */
0175     reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
0176           (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
0177     IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
0178 
0179     return 0;
0180 }
0181 
0182 /**
0183  * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
0184  * @hw: pointer to hardware structure
0185  * @pfc_en: enabled pfc bitmask
0186  * @prio_tc: priority to tc assignments indexed by priority
0187  *
0188  * Configure Priority Flow Control (PFC) for each traffic class.
0189  */
0190 s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
0191 {
0192     u32 i, j, fcrtl, reg;
0193     u8 max_tc = 0;
0194 
0195     /* Enable Transmit Priority Flow Control */
0196     IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY);
0197 
0198     /* Enable Receive Priority Flow Control */
0199     reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
0200     reg |= IXGBE_MFLCN_DPF;
0201 
0202     /*
0203      * X540 & X550 supports per TC Rx priority flow control.
0204      * So clear all TCs and only enable those that should be
0205      * enabled.
0206      */
0207     reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
0208 
0209     if (hw->mac.type >= ixgbe_mac_X540)
0210         reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
0211 
0212     if (pfc_en)
0213         reg |= IXGBE_MFLCN_RPFCE;
0214 
0215     IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
0216 
0217     for (i = 0; i < MAX_USER_PRIORITY; i++) {
0218         if (prio_tc[i] > max_tc)
0219             max_tc = prio_tc[i];
0220     }
0221 
0222 
0223     /* Configure PFC Tx thresholds per TC */
0224     for (i = 0; i <= max_tc; i++) {
0225         int enabled = 0;
0226 
0227         for (j = 0; j < MAX_USER_PRIORITY; j++) {
0228             if ((prio_tc[j] == i) && (pfc_en & BIT(j))) {
0229                 enabled = 1;
0230                 break;
0231             }
0232         }
0233 
0234         if (enabled) {
0235             reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
0236             fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
0237             IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
0238         } else {
0239             /* In order to prevent Tx hangs when the internal Tx
0240              * switch is enabled we must set the high water mark
0241              * to the Rx packet buffer size - 24KB.  This allows
0242              * the Tx switch to function even under heavy Rx
0243              * workloads.
0244              */
0245             reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
0246             IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
0247         }
0248 
0249         IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
0250     }
0251 
0252     for (; i < MAX_TRAFFIC_CLASS; i++) {
0253         IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
0254         IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
0255     }
0256 
0257     /* Configure pause time (2 TCs per register) */
0258     reg = hw->fc.pause_time * 0x00010001;
0259     for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
0260         IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
0261 
0262     /* Configure flow control refresh threshold value */
0263     IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
0264 
0265     return 0;
0266 }
0267 
0268 /**
0269  * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
0270  * @hw: pointer to hardware structure
0271  *
0272  * Configure queue statistics registers, all queues belonging to same traffic
0273  * class uses a single set of queue statistics counters.
0274  */
0275 static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
0276 {
0277     u32 reg = 0;
0278     u8  i   = 0;
0279 
0280     /*
0281      * Receive Queues stats setting
0282      * 32 RQSMR registers, each configuring 4 queues.
0283      * Set all 16 queues of each TC to the same stat
0284      * with TC 'n' going to stat 'n'.
0285      */
0286     for (i = 0; i < 32; i++) {
0287         reg = 0x01010101 * (i / 4);
0288         IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
0289     }
0290     /*
0291      * Transmit Queues stats setting
0292      * 32 TQSM registers, each controlling 4 queues.
0293      * Set all queues of each TC to the same stat
0294      * with TC 'n' going to stat 'n'.
0295      * Tx queues are allocated non-uniformly to TCs:
0296      * 32, 32, 16, 16, 8, 8, 8, 8.
0297      */
0298     for (i = 0; i < 32; i++) {
0299         if (i < 8)
0300             reg = 0x00000000;
0301         else if (i < 16)
0302             reg = 0x01010101;
0303         else if (i < 20)
0304             reg = 0x02020202;
0305         else if (i < 24)
0306             reg = 0x03030303;
0307         else if (i < 26)
0308             reg = 0x04040404;
0309         else if (i < 28)
0310             reg = 0x05050505;
0311         else if (i < 30)
0312             reg = 0x06060606;
0313         else
0314             reg = 0x07070707;
0315         IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
0316     }
0317 
0318     return 0;
0319 }
0320 
0321 /**
0322  * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
0323  * @hw: pointer to hardware structure
0324  * @pfc_en: enabled pfc bitmask
0325  * @refill: refill credits index by traffic class
0326  * @max: max credits index by traffic class
0327  * @bwg_id: bandwidth grouping indexed by traffic class
0328  * @prio_type: priority type indexed by traffic class
0329  * @prio_tc: priority to tc assignments indexed by priority
0330  *
0331  * Configure dcb settings and enable dcb mode.
0332  */
0333 s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill,
0334                   u16 *max, u8 *bwg_id, u8 *prio_type, u8 *prio_tc)
0335 {
0336     ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
0337                       prio_type, prio_tc);
0338     ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
0339                            bwg_id, prio_type);
0340     ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
0341                            bwg_id, prio_type, prio_tc);
0342     ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
0343     ixgbe_dcb_config_tc_stats_82599(hw);
0344 
0345     return 0;
0346 }
0347