1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 1999 - 2018 Intel Corporation. */ 3 4 #include "ixgbe.h" 5 #include "ixgbe_type.h" 6 #include "ixgbe_dcb.h" 7 #include "ixgbe_dcb_82598.h" 8 9 /** 10 * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter 11 * @hw: pointer to hardware structure 12 * @refill: refill credits index by traffic class 13 * @max: max credits index by traffic class 14 * @prio_type: priority type indexed by traffic class 15 * 16 * Configure Rx Data Arbiter and credits for each traffic class. 17 */ 18 s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, 19 u16 *refill, 20 u16 *max, 21 u8 *prio_type) 22 { 23 u32 reg = 0; 24 u32 credit_refill = 0; 25 u32 credit_max = 0; 26 u8 i = 0; 27 28 reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA; 29 IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg); 30 31 reg = IXGBE_READ_REG(hw, IXGBE_RMCS); 32 /* Enable Arbiter */ 33 reg &= ~IXGBE_RMCS_ARBDIS; 34 /* Enable Receive Recycle within the BWG */ 35 reg |= IXGBE_RMCS_RRM; 36 /* Enable Deficit Fixed Priority arbitration*/ 37 reg |= IXGBE_RMCS_DFP; 38 39 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); 40 41 /* Configure traffic class credits and priority */ 42 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 43 credit_refill = refill[i]; 44 credit_max = max[i]; 45 46 reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); 47 48 if (prio_type[i] == prio_link) 49 reg |= IXGBE_RT2CR_LSP; 50 51 IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); 52 } 53 54 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); 55 reg |= IXGBE_RDRXCTL_RDMTS_1_2; 56 reg |= IXGBE_RDRXCTL_MPBEN; 57 reg |= IXGBE_RDRXCTL_MCEN; 58 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); 59 60 reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 61 /* Make sure there is enough descriptors before arbitration */ 62 reg &= ~IXGBE_RXCTRL_DMBYPS; 63 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg); 64 65 return 0; 66 } 67 68 /** 69 * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter 70 * @hw: pointer to hardware structure 71 * @refill: refill credits index by traffic class 72 * @max: max credits index by traffic class 73 * @bwg_id: bandwidth grouping indexed by traffic class 74 * @prio_type: priority type indexed by traffic class 75 * 76 * Configure Tx Descriptor Arbiter and credits for each traffic class. 77 */ 78 s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, 79 u16 *refill, 80 u16 *max, 81 u8 *bwg_id, 82 u8 *prio_type) 83 { 84 u32 reg, max_credits; 85 u8 i; 86 87 reg = IXGBE_READ_REG(hw, IXGBE_DPMCS); 88 89 /* Enable arbiter */ 90 reg &= ~IXGBE_DPMCS_ARBDIS; 91 reg |= IXGBE_DPMCS_TSOEF; 92 93 /* Configure Max TSO packet size 34KB including payload and headers */ 94 reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); 95 96 IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg); 97 98 /* Configure traffic class credits and priority */ 99 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 100 max_credits = max[i]; 101 reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; 102 reg |= refill[i]; 103 reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; 104 105 if (prio_type[i] == prio_group) 106 reg |= IXGBE_TDTQ2TCCR_GSP; 107 108 if (prio_type[i] == prio_link) 109 reg |= IXGBE_TDTQ2TCCR_LSP; 110 111 IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); 112 } 113 114 return 0; 115 } 116 117 /** 118 * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter 119 * @hw: pointer to hardware structure 120 * @refill: refill credits index by traffic class 121 * @max: max credits index by traffic class 122 * @bwg_id: bandwidth grouping indexed by traffic class 123 * @prio_type: priority type indexed by traffic class 124 * 125 * Configure Tx Data Arbiter and credits for each traffic class. 126 */ 127 s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, 128 u16 *refill, 129 u16 *max, 130 u8 *bwg_id, 131 u8 *prio_type) 132 { 133 u32 reg; 134 u8 i; 135 136 reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS); 137 /* Enable Data Plane Arbiter */ 138 reg &= ~IXGBE_PDPMCS_ARBDIS; 139 /* Enable DFP and Transmit Recycle Mode */ 140 reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM); 141 142 IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg); 143 144 /* Configure traffic class credits and priority */ 145 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 146 reg = refill[i]; 147 reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; 148 reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; 149 150 if (prio_type[i] == prio_group) 151 reg |= IXGBE_TDPT2TCCR_GSP; 152 153 if (prio_type[i] == prio_link) 154 reg |= IXGBE_TDPT2TCCR_LSP; 155 156 IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); 157 } 158 159 /* Enable Tx packet buffer division */ 160 reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL); 161 reg |= IXGBE_DTXCTL_ENDBUBD; 162 IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg); 163 164 return 0; 165 } 166 167 /** 168 * ixgbe_dcb_config_pfc_82598 - Config priority flow control 169 * @hw: pointer to hardware structure 170 * @pfc_en: enabled pfc bitmask 171 * 172 * Configure Priority Flow Control for each traffic class. 173 */ 174 s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) 175 { 176 u32 fcrtl, reg; 177 u8 i; 178 179 /* Enable Transmit Priority Flow Control */ 180 reg = IXGBE_READ_REG(hw, IXGBE_RMCS); 181 reg &= ~IXGBE_RMCS_TFCE_802_3X; 182 reg |= IXGBE_RMCS_TFCE_PRIORITY; 183 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); 184 185 /* Enable Receive Priority Flow Control */ 186 reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); 187 reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); 188 189 if (pfc_en) 190 reg |= IXGBE_FCTRL_RPFCE; 191 192 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); 193 194 /* Configure PFC Tx thresholds per TC */ 195 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 196 if (!(pfc_en & BIT(i))) { 197 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); 198 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); 199 continue; 200 } 201 202 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; 203 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; 204 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); 205 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); 206 } 207 208 /* Configure pause time */ 209 reg = hw->fc.pause_time * 0x00010001; 210 for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) 211 IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); 212 213 /* Configure flow control refresh threshold value */ 214 IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); 215 216 217 return 0; 218 } 219 220 /** 221 * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics 222 * @hw: pointer to hardware structure 223 * 224 * Configure queue statistics registers, all queues belonging to same traffic 225 * class uses a single set of queue statistics counters. 226 */ 227 static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) 228 { 229 u32 reg = 0; 230 u8 i = 0; 231 u8 j = 0; 232 233 /* Receive Queues stats setting - 8 queues per statistics reg */ 234 for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) { 235 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i)); 236 reg |= ((0x1010101) * j); 237 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); 238 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1)); 239 reg |= ((0x1010101) * j); 240 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg); 241 } 242 /* Transmit Queues stats setting - 4 queues per statistics reg */ 243 for (i = 0; i < 8; i++) { 244 reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i)); 245 reg |= ((0x1010101) * i); 246 IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg); 247 } 248 249 return 0; 250 } 251 252 /** 253 * ixgbe_dcb_hw_config_82598 - Config and enable DCB 254 * @hw: pointer to hardware structure 255 * @pfc_en: enabled pfc bitmask 256 * @refill: refill credits index by traffic class 257 * @max: max credits index by traffic class 258 * @bwg_id: bandwidth grouping indexed by traffic class 259 * @prio_type: priority type indexed by traffic class 260 * 261 * Configure dcb settings and enable dcb mode. 262 */ 263 s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, 264 u16 *max, u8 *bwg_id, u8 *prio_type) 265 { 266 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); 267 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, 268 bwg_id, prio_type); 269 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, 270 bwg_id, prio_type); 271 ixgbe_dcb_config_pfc_82598(hw, pfc_en); 272 ixgbe_dcb_config_tc_stats_82598(hw); 273 274 return 0; 275 } 276