1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0 2dee1ad47SJeff Kirsher /******************************************************************************* 3dee1ad47SJeff Kirsher 4dee1ad47SJeff Kirsher Intel 10 Gigabit PCI Express Linux driver 5434c5e39SDon Skidmore Copyright(c) 1999 - 2013 Intel Corporation. 6dee1ad47SJeff Kirsher 7dee1ad47SJeff Kirsher This program is free software; you can redistribute it and/or modify it 8dee1ad47SJeff Kirsher under the terms and conditions of the GNU General Public License, 9dee1ad47SJeff Kirsher version 2, as published by the Free Software Foundation. 10dee1ad47SJeff Kirsher 11dee1ad47SJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 12dee1ad47SJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13dee1ad47SJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14dee1ad47SJeff Kirsher more details. 15dee1ad47SJeff Kirsher 16dee1ad47SJeff Kirsher You should have received a copy of the GNU General Public License along with 17dee1ad47SJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 18dee1ad47SJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 19dee1ad47SJeff Kirsher 20dee1ad47SJeff Kirsher The full GNU General Public License is included in this distribution in 21dee1ad47SJeff Kirsher the file called "COPYING". 22dee1ad47SJeff Kirsher 23dee1ad47SJeff Kirsher Contact Information: 24dee1ad47SJeff Kirsher Linux NICS <linux.nics@intel.com> 25dee1ad47SJeff Kirsher e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 26dee1ad47SJeff Kirsher Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27dee1ad47SJeff Kirsher 28dee1ad47SJeff Kirsher *******************************************************************************/ 29dee1ad47SJeff Kirsher 30dee1ad47SJeff Kirsher #include "ixgbe.h" 31dee1ad47SJeff Kirsher #include "ixgbe_type.h" 32dee1ad47SJeff Kirsher #include "ixgbe_dcb.h" 33dee1ad47SJeff Kirsher #include "ixgbe_dcb_82598.h" 34dee1ad47SJeff Kirsher 35dee1ad47SJeff Kirsher /** 36dee1ad47SJeff Kirsher * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter 37dee1ad47SJeff Kirsher * @hw: pointer to hardware structure 385ba643c6STony Nguyen * @refill: refill credits index by traffic class 395ba643c6STony Nguyen * @max: max credits index by traffic class 405ba643c6STony Nguyen * @prio_type: priority type indexed by traffic class 41dee1ad47SJeff Kirsher * 42dee1ad47SJeff Kirsher * Configure Rx Data Arbiter and credits for each traffic class. 43dee1ad47SJeff Kirsher */ 44dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, 45dee1ad47SJeff Kirsher u16 *refill, 46dee1ad47SJeff Kirsher u16 *max, 47dee1ad47SJeff Kirsher u8 *prio_type) 48dee1ad47SJeff Kirsher { 49dee1ad47SJeff Kirsher u32 reg = 0; 50dee1ad47SJeff Kirsher u32 credit_refill = 0; 51dee1ad47SJeff Kirsher u32 credit_max = 0; 52dee1ad47SJeff Kirsher u8 i = 0; 53dee1ad47SJeff Kirsher 54dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA; 55dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg); 56dee1ad47SJeff Kirsher 57dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RMCS); 58dee1ad47SJeff Kirsher /* Enable Arbiter */ 59dee1ad47SJeff Kirsher reg &= ~IXGBE_RMCS_ARBDIS; 60dee1ad47SJeff Kirsher /* Enable Receive Recycle within the BWG */ 61dee1ad47SJeff Kirsher reg |= IXGBE_RMCS_RRM; 62dee1ad47SJeff Kirsher /* Enable Deficit Fixed Priority arbitration*/ 63dee1ad47SJeff Kirsher reg |= IXGBE_RMCS_DFP; 64dee1ad47SJeff Kirsher 65dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); 66dee1ad47SJeff Kirsher 67dee1ad47SJeff Kirsher /* Configure traffic class credits and priority */ 68dee1ad47SJeff Kirsher for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 69dee1ad47SJeff Kirsher credit_refill = refill[i]; 70dee1ad47SJeff Kirsher credit_max = max[i]; 71dee1ad47SJeff Kirsher 72dee1ad47SJeff Kirsher reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); 73dee1ad47SJeff Kirsher 74dee1ad47SJeff Kirsher if (prio_type[i] == prio_link) 75dee1ad47SJeff Kirsher reg |= IXGBE_RT2CR_LSP; 76dee1ad47SJeff Kirsher 77dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); 78dee1ad47SJeff Kirsher } 79dee1ad47SJeff Kirsher 80dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); 81dee1ad47SJeff Kirsher reg |= IXGBE_RDRXCTL_RDMTS_1_2; 82dee1ad47SJeff Kirsher reg |= IXGBE_RDRXCTL_MPBEN; 83dee1ad47SJeff Kirsher reg |= IXGBE_RDRXCTL_MCEN; 84dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); 85dee1ad47SJeff Kirsher 86dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 87dee1ad47SJeff Kirsher /* Make sure there is enough descriptors before arbitration */ 88dee1ad47SJeff Kirsher reg &= ~IXGBE_RXCTRL_DMBYPS; 89dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg); 90dee1ad47SJeff Kirsher 91dee1ad47SJeff Kirsher return 0; 92dee1ad47SJeff Kirsher } 93dee1ad47SJeff Kirsher 94dee1ad47SJeff Kirsher /** 95dee1ad47SJeff Kirsher * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter 96dee1ad47SJeff Kirsher * @hw: pointer to hardware structure 975ba643c6STony Nguyen * @refill: refill credits index by traffic class 985ba643c6STony Nguyen * @max: max credits index by traffic class 995ba643c6STony Nguyen * @bwg_id: bandwidth grouping indexed by traffic class 1005ba643c6STony Nguyen * @prio_type: priority type indexed by traffic class 101dee1ad47SJeff Kirsher * 102dee1ad47SJeff Kirsher * Configure Tx Descriptor Arbiter and credits for each traffic class. 103dee1ad47SJeff Kirsher */ 104dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, 105dee1ad47SJeff Kirsher u16 *refill, 106dee1ad47SJeff Kirsher u16 *max, 107dee1ad47SJeff Kirsher u8 *bwg_id, 108dee1ad47SJeff Kirsher u8 *prio_type) 109dee1ad47SJeff Kirsher { 110dee1ad47SJeff Kirsher u32 reg, max_credits; 111dee1ad47SJeff Kirsher u8 i; 112dee1ad47SJeff Kirsher 113dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_DPMCS); 114dee1ad47SJeff Kirsher 115dee1ad47SJeff Kirsher /* Enable arbiter */ 116dee1ad47SJeff Kirsher reg &= ~IXGBE_DPMCS_ARBDIS; 117dee1ad47SJeff Kirsher reg |= IXGBE_DPMCS_TSOEF; 1181eb9ac14SJacob Keller 119dee1ad47SJeff Kirsher /* Configure Max TSO packet size 34KB including payload and headers */ 120dee1ad47SJeff Kirsher reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); 121dee1ad47SJeff Kirsher 122dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg); 123dee1ad47SJeff Kirsher 124dee1ad47SJeff Kirsher /* Configure traffic class credits and priority */ 125dee1ad47SJeff Kirsher for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 126dee1ad47SJeff Kirsher max_credits = max[i]; 127dee1ad47SJeff Kirsher reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; 128dee1ad47SJeff Kirsher reg |= refill[i]; 129dee1ad47SJeff Kirsher reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; 130dee1ad47SJeff Kirsher 131dee1ad47SJeff Kirsher if (prio_type[i] == prio_group) 132dee1ad47SJeff Kirsher reg |= IXGBE_TDTQ2TCCR_GSP; 133dee1ad47SJeff Kirsher 134dee1ad47SJeff Kirsher if (prio_type[i] == prio_link) 135dee1ad47SJeff Kirsher reg |= IXGBE_TDTQ2TCCR_LSP; 136dee1ad47SJeff Kirsher 137dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); 138dee1ad47SJeff Kirsher } 139dee1ad47SJeff Kirsher 140dee1ad47SJeff Kirsher return 0; 141dee1ad47SJeff Kirsher } 142dee1ad47SJeff Kirsher 143dee1ad47SJeff Kirsher /** 144dee1ad47SJeff Kirsher * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter 145dee1ad47SJeff Kirsher * @hw: pointer to hardware structure 1465ba643c6STony Nguyen * @refill: refill credits index by traffic class 1475ba643c6STony Nguyen * @max: max credits index by traffic class 1485ba643c6STony Nguyen * @bwg_id: bandwidth grouping indexed by traffic class 1495ba643c6STony Nguyen * @prio_type: priority type indexed by traffic class 150dee1ad47SJeff Kirsher * 151dee1ad47SJeff Kirsher * Configure Tx Data Arbiter and credits for each traffic class. 152dee1ad47SJeff Kirsher */ 153dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, 154dee1ad47SJeff Kirsher u16 *refill, 155dee1ad47SJeff Kirsher u16 *max, 156dee1ad47SJeff Kirsher u8 *bwg_id, 157dee1ad47SJeff Kirsher u8 *prio_type) 158dee1ad47SJeff Kirsher { 159dee1ad47SJeff Kirsher u32 reg; 160dee1ad47SJeff Kirsher u8 i; 161dee1ad47SJeff Kirsher 162dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS); 163dee1ad47SJeff Kirsher /* Enable Data Plane Arbiter */ 164dee1ad47SJeff Kirsher reg &= ~IXGBE_PDPMCS_ARBDIS; 165dee1ad47SJeff Kirsher /* Enable DFP and Transmit Recycle Mode */ 166dee1ad47SJeff Kirsher reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM); 167dee1ad47SJeff Kirsher 168dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg); 169dee1ad47SJeff Kirsher 170dee1ad47SJeff Kirsher /* Configure traffic class credits and priority */ 171dee1ad47SJeff Kirsher for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 172dee1ad47SJeff Kirsher reg = refill[i]; 173dee1ad47SJeff Kirsher reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; 174dee1ad47SJeff Kirsher reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; 175dee1ad47SJeff Kirsher 176dee1ad47SJeff Kirsher if (prio_type[i] == prio_group) 177dee1ad47SJeff Kirsher reg |= IXGBE_TDPT2TCCR_GSP; 178dee1ad47SJeff Kirsher 179dee1ad47SJeff Kirsher if (prio_type[i] == prio_link) 180dee1ad47SJeff Kirsher reg |= IXGBE_TDPT2TCCR_LSP; 181dee1ad47SJeff Kirsher 182dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); 183dee1ad47SJeff Kirsher } 184dee1ad47SJeff Kirsher 185dee1ad47SJeff Kirsher /* Enable Tx packet buffer division */ 186dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL); 187dee1ad47SJeff Kirsher reg |= IXGBE_DTXCTL_ENDBUBD; 188dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg); 189dee1ad47SJeff Kirsher 190dee1ad47SJeff Kirsher return 0; 191dee1ad47SJeff Kirsher } 192dee1ad47SJeff Kirsher 193dee1ad47SJeff Kirsher /** 194dee1ad47SJeff Kirsher * ixgbe_dcb_config_pfc_82598 - Config priority flow control 195dee1ad47SJeff Kirsher * @hw: pointer to hardware structure 1965ba643c6STony Nguyen * @pfc_en: enabled pfc bitmask 197dee1ad47SJeff Kirsher * 198dee1ad47SJeff Kirsher * Configure Priority Flow Control for each traffic class. 199dee1ad47SJeff Kirsher */ 200dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) 201dee1ad47SJeff Kirsher { 202943561d3SAlexander Duyck u32 fcrtl, reg; 203dee1ad47SJeff Kirsher u8 i; 204dee1ad47SJeff Kirsher 205dee1ad47SJeff Kirsher /* Enable Transmit Priority Flow Control */ 206dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RMCS); 207dee1ad47SJeff Kirsher reg &= ~IXGBE_RMCS_TFCE_802_3X; 208dee1ad47SJeff Kirsher reg |= IXGBE_RMCS_TFCE_PRIORITY; 209dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); 210dee1ad47SJeff Kirsher 211dee1ad47SJeff Kirsher /* Enable Receive Priority Flow Control */ 212dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); 213943561d3SAlexander Duyck reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); 214943561d3SAlexander Duyck 215943561d3SAlexander Duyck if (pfc_en) 216dee1ad47SJeff Kirsher reg |= IXGBE_FCTRL_RPFCE; 217943561d3SAlexander Duyck 218dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); 219dee1ad47SJeff Kirsher 220943561d3SAlexander Duyck /* Configure PFC Tx thresholds per TC */ 221943561d3SAlexander Duyck for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 222b4f47a48SJacob Keller if (!(pfc_en & BIT(i))) { 223943561d3SAlexander Duyck IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); 224943561d3SAlexander Duyck IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); 225943561d3SAlexander Duyck continue; 226dee1ad47SJeff Kirsher } 227dee1ad47SJeff Kirsher 228e5776620SJacob Keller fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; 229943561d3SAlexander Duyck reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; 230943561d3SAlexander Duyck IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); 231dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); 232dee1ad47SJeff Kirsher } 233dee1ad47SJeff Kirsher 234943561d3SAlexander Duyck /* Configure pause time */ 235943561d3SAlexander Duyck reg = hw->fc.pause_time * 0x00010001; 236943561d3SAlexander Duyck for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) 237943561d3SAlexander Duyck IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); 238943561d3SAlexander Duyck 239943561d3SAlexander Duyck /* Configure flow control refresh threshold value */ 240943561d3SAlexander Duyck IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); 241943561d3SAlexander Duyck 242943561d3SAlexander Duyck 243dee1ad47SJeff Kirsher return 0; 244dee1ad47SJeff Kirsher } 245dee1ad47SJeff Kirsher 246dee1ad47SJeff Kirsher /** 247dee1ad47SJeff Kirsher * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics 248dee1ad47SJeff Kirsher * @hw: pointer to hardware structure 249dee1ad47SJeff Kirsher * 250dee1ad47SJeff Kirsher * Configure queue statistics registers, all queues belonging to same traffic 251dee1ad47SJeff Kirsher * class uses a single set of queue statistics counters. 252dee1ad47SJeff Kirsher */ 253dee1ad47SJeff Kirsher static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) 254dee1ad47SJeff Kirsher { 255dee1ad47SJeff Kirsher u32 reg = 0; 256dee1ad47SJeff Kirsher u8 i = 0; 257dee1ad47SJeff Kirsher u8 j = 0; 258dee1ad47SJeff Kirsher 259dee1ad47SJeff Kirsher /* Receive Queues stats setting - 8 queues per statistics reg */ 260dee1ad47SJeff Kirsher for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) { 261dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i)); 262dee1ad47SJeff Kirsher reg |= ((0x1010101) * j); 263dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); 264dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1)); 265dee1ad47SJeff Kirsher reg |= ((0x1010101) * j); 266dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg); 267dee1ad47SJeff Kirsher } 268dee1ad47SJeff Kirsher /* Transmit Queues stats setting - 4 queues per statistics reg */ 269dee1ad47SJeff Kirsher for (i = 0; i < 8; i++) { 270dee1ad47SJeff Kirsher reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i)); 271dee1ad47SJeff Kirsher reg |= ((0x1010101) * i); 272dee1ad47SJeff Kirsher IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg); 273dee1ad47SJeff Kirsher } 274dee1ad47SJeff Kirsher 275dee1ad47SJeff Kirsher return 0; 276dee1ad47SJeff Kirsher } 277dee1ad47SJeff Kirsher 278dee1ad47SJeff Kirsher /** 279dee1ad47SJeff Kirsher * ixgbe_dcb_hw_config_82598 - Config and enable DCB 280dee1ad47SJeff Kirsher * @hw: pointer to hardware structure 2815ba643c6STony Nguyen * @pfc_en: enabled pfc bitmask 2825ba643c6STony Nguyen * @refill: refill credits index by traffic class 2835ba643c6STony Nguyen * @max: max credits index by traffic class 2845ba643c6STony Nguyen * @bwg_id: bandwidth grouping indexed by traffic class 2855ba643c6STony Nguyen * @prio_type: priority type indexed by traffic class 286dee1ad47SJeff Kirsher * 287dee1ad47SJeff Kirsher * Configure dcb settings and enable dcb mode. 288dee1ad47SJeff Kirsher */ 289dee1ad47SJeff Kirsher s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, 290dee1ad47SJeff Kirsher u16 *max, u8 *bwg_id, u8 *prio_type) 291dee1ad47SJeff Kirsher { 292dee1ad47SJeff Kirsher ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); 293dee1ad47SJeff Kirsher ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, 294dee1ad47SJeff Kirsher bwg_id, prio_type); 295dee1ad47SJeff Kirsher ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, 296dee1ad47SJeff Kirsher bwg_id, prio_type); 297dee1ad47SJeff Kirsher ixgbe_dcb_config_pfc_82598(hw, pfc_en); 298dee1ad47SJeff Kirsher ixgbe_dcb_config_tc_stats_82598(hw); 299dee1ad47SJeff Kirsher 300dee1ad47SJeff Kirsher return 0; 301dee1ad47SJeff Kirsher } 302