linux/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* 10G controller driver for Samsung SoCs
   3 *
   4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
   5 *              http://www.samsung.com
   6 *
   7 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
   8 */
   9
  10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11
  12#include <linux/io.h>
  13#include <linux/errno.h>
  14#include <linux/export.h>
  15#include <linux/jiffies.h>
  16
  17#include "sxgbe_mtl.h"
  18#include "sxgbe_reg.h"
  19
  20static void sxgbe_mtl_init(void __iomem *ioaddr, unsigned int etsalg,
  21                           unsigned int raa)
  22{
  23        u32 reg_val;
  24
  25        reg_val = readl(ioaddr + SXGBE_MTL_OP_MODE_REG);
  26        reg_val &= ETS_RST;
  27
  28        /* ETS Algorith */
  29        switch (etsalg & SXGBE_MTL_OPMODE_ESTMASK) {
  30        case ETS_WRR:
  31                reg_val &= ETS_WRR;
  32                break;
  33        case ETS_WFQ:
  34                reg_val |= ETS_WFQ;
  35                break;
  36        case ETS_DWRR:
  37                reg_val |= ETS_DWRR;
  38                break;
  39        }
  40        writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
  41
  42        switch (raa & SXGBE_MTL_OPMODE_RAAMASK) {
  43        case RAA_SP:
  44                reg_val &= RAA_SP;
  45                break;
  46        case RAA_WSP:
  47                reg_val |= RAA_WSP;
  48                break;
  49        }
  50        writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
  51}
  52
  53/* For Dynamic DMA channel mapping for Rx queue */
  54static void sxgbe_mtl_dma_dm_rxqueue(void __iomem *ioaddr)
  55{
  56        writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP0_REG);
  57        writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP1_REG);
  58        writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP2_REG);
  59}
  60
  61static void sxgbe_mtl_set_txfifosize(void __iomem *ioaddr, int queue_num,
  62                                     int queue_fifo)
  63{
  64        u32 fifo_bits, reg_val;
  65
  66        /* 0 means 256 bytes */
  67        fifo_bits = (queue_fifo / SXGBE_MTL_TX_FIFO_DIV) - 1;
  68        reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
  69        reg_val |= (fifo_bits << SXGBE_MTL_FIFO_LSHIFT);
  70        writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
  71}
  72
  73static void sxgbe_mtl_set_rxfifosize(void __iomem *ioaddr, int queue_num,
  74                                     int queue_fifo)
  75{
  76        u32 fifo_bits, reg_val;
  77
  78        /* 0 means 256 bytes */
  79        fifo_bits = (queue_fifo / SXGBE_MTL_RX_FIFO_DIV)-1;
  80        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
  81        reg_val |= (fifo_bits << SXGBE_MTL_FIFO_LSHIFT);
  82        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
  83}
  84
  85static void sxgbe_mtl_enable_txqueue(void __iomem *ioaddr, int queue_num)
  86{
  87        u32 reg_val;
  88
  89        reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
  90        reg_val |= SXGBE_MTL_ENABLE_QUEUE;
  91        writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
  92}
  93
  94static void sxgbe_mtl_disable_txqueue(void __iomem *ioaddr, int queue_num)
  95{
  96        u32 reg_val;
  97
  98        reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
  99        reg_val &= ~SXGBE_MTL_ENABLE_QUEUE;
 100        writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
 101}
 102
 103static void sxgbe_mtl_fc_active(void __iomem *ioaddr, int queue_num,
 104                                int threshold)
 105{
 106        u32 reg_val;
 107
 108        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 109        reg_val &= ~(SXGBE_MTL_FCMASK << RX_FC_ACTIVE);
 110        reg_val |= (threshold << RX_FC_ACTIVE);
 111
 112        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 113}
 114
 115static void sxgbe_mtl_fc_enable(void __iomem *ioaddr, int queue_num)
 116{
 117        u32 reg_val;
 118
 119        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 120        reg_val |= SXGBE_MTL_ENABLE_FC;
 121        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 122}
 123
 124static void sxgbe_mtl_fc_deactive(void __iomem *ioaddr, int queue_num,
 125                                  int threshold)
 126{
 127        u32 reg_val;
 128
 129        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 130        reg_val &= ~(SXGBE_MTL_FCMASK << RX_FC_DEACTIVE);
 131        reg_val |= (threshold << RX_FC_DEACTIVE);
 132
 133        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 134}
 135
 136static void sxgbe_mtl_fep_enable(void __iomem *ioaddr, int queue_num)
 137{
 138        u32 reg_val;
 139
 140        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 141        reg_val |= SXGBE_MTL_RXQ_OP_FEP;
 142
 143        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 144}
 145
 146static void sxgbe_mtl_fep_disable(void __iomem *ioaddr, int queue_num)
 147{
 148        u32 reg_val;
 149
 150        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 151        reg_val &= ~(SXGBE_MTL_RXQ_OP_FEP);
 152
 153        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 154}
 155
 156static void sxgbe_mtl_fup_enable(void __iomem *ioaddr, int queue_num)
 157{
 158        u32 reg_val;
 159
 160        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 161        reg_val |= SXGBE_MTL_RXQ_OP_FUP;
 162
 163        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 164}
 165
 166static void sxgbe_mtl_fup_disable(void __iomem *ioaddr, int queue_num)
 167{
 168        u32 reg_val;
 169
 170        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 171        reg_val &= ~(SXGBE_MTL_RXQ_OP_FUP);
 172
 173        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 174}
 175
 176
 177static void sxgbe_set_tx_mtl_mode(void __iomem *ioaddr, int queue_num,
 178                                  int tx_mode)
 179{
 180        u32 reg_val;
 181
 182        reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
 183        /* TX specific MTL mode settings */
 184        if (tx_mode == SXGBE_MTL_SFMODE) {
 185                reg_val |= SXGBE_MTL_SFMODE;
 186        } else {
 187                /* set the TTC values */
 188                if (tx_mode <= 64)
 189                        reg_val |= MTL_CONTROL_TTC_64;
 190                else if (tx_mode <= 96)
 191                        reg_val |= MTL_CONTROL_TTC_96;
 192                else if (tx_mode <= 128)
 193                        reg_val |= MTL_CONTROL_TTC_128;
 194                else if (tx_mode <= 192)
 195                        reg_val |= MTL_CONTROL_TTC_192;
 196                else if (tx_mode <= 256)
 197                        reg_val |= MTL_CONTROL_TTC_256;
 198                else if (tx_mode <= 384)
 199                        reg_val |= MTL_CONTROL_TTC_384;
 200                else
 201                        reg_val |= MTL_CONTROL_TTC_512;
 202        }
 203
 204        /* write into TXQ operation register */
 205        writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
 206}
 207
 208static void sxgbe_set_rx_mtl_mode(void __iomem *ioaddr, int queue_num,
 209                                  int rx_mode)
 210{
 211        u32 reg_val;
 212
 213        reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 214        /* RX specific MTL mode settings */
 215        if (rx_mode == SXGBE_RX_MTL_SFMODE) {
 216                reg_val |= SXGBE_RX_MTL_SFMODE;
 217        } else {
 218                if (rx_mode <= 64)
 219                        reg_val |= MTL_CONTROL_RTC_64;
 220                else if (rx_mode <= 96)
 221                        reg_val |= MTL_CONTROL_RTC_96;
 222                else if (rx_mode <= 128)
 223                        reg_val |= MTL_CONTROL_RTC_128;
 224        }
 225
 226        /* write into RXQ operation register */
 227        writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
 228}
 229
 230static const struct sxgbe_mtl_ops mtl_ops = {
 231        .mtl_set_txfifosize             = sxgbe_mtl_set_txfifosize,
 232        .mtl_set_rxfifosize             = sxgbe_mtl_set_rxfifosize,
 233        .mtl_enable_txqueue             = sxgbe_mtl_enable_txqueue,
 234        .mtl_disable_txqueue            = sxgbe_mtl_disable_txqueue,
 235        .mtl_dynamic_dma_rxqueue        = sxgbe_mtl_dma_dm_rxqueue,
 236        .set_tx_mtl_mode                = sxgbe_set_tx_mtl_mode,
 237        .set_rx_mtl_mode                = sxgbe_set_rx_mtl_mode,
 238        .mtl_init                       = sxgbe_mtl_init,
 239        .mtl_fc_active                  = sxgbe_mtl_fc_active,
 240        .mtl_fc_deactive                = sxgbe_mtl_fc_deactive,
 241        .mtl_fc_enable                  = sxgbe_mtl_fc_enable,
 242        .mtl_fep_enable                 = sxgbe_mtl_fep_enable,
 243        .mtl_fep_disable                = sxgbe_mtl_fep_disable,
 244        .mtl_fup_enable                 = sxgbe_mtl_fup_enable,
 245        .mtl_fup_disable                = sxgbe_mtl_fup_disable
 246};
 247
 248const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void)
 249{
 250        return &mtl_ops;
 251}
 252