root/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dwmac1000_dma_axi
  2. dwmac1000_dma_init
  3. dwmac1000_dma_init_rx
  4. dwmac1000_dma_init_tx
  5. dwmac1000_configure_fc
  6. dwmac1000_dma_operation_mode_rx
  7. dwmac1000_dma_operation_mode_tx
  8. dwmac1000_dump_dma_regs
  9. dwmac1000_get_hw_feature
  10. dwmac1000_rx_watchdog

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*******************************************************************************
   3   This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
   4   DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
   5   developing this code.
   6 
   7   This contains the functions to handle the dma.
   8 
   9   Copyright (C) 2007-2009  STMicroelectronics Ltd
  10 
  11 
  12   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
  13 *******************************************************************************/
  14 
  15 #include <asm/io.h>
  16 #include "dwmac1000.h"
  17 #include "dwmac_dma.h"
  18 
  19 static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
  20 {
  21         u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
  22         int i;
  23 
  24         pr_info("dwmac1000: Master AXI performs %s burst length\n",
  25                 !(value & DMA_AXI_UNDEF) ? "fixed" : "any");
  26 
  27         if (axi->axi_lpi_en)
  28                 value |= DMA_AXI_EN_LPI;
  29         if (axi->axi_xit_frm)
  30                 value |= DMA_AXI_LPI_XIT_FRM;
  31 
  32         value &= ~DMA_AXI_WR_OSR_LMT;
  33         value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
  34                  DMA_AXI_WR_OSR_LMT_SHIFT;
  35 
  36         value &= ~DMA_AXI_RD_OSR_LMT;
  37         value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
  38                  DMA_AXI_RD_OSR_LMT_SHIFT;
  39 
  40         /* Depending on the UNDEF bit the Master AXI will perform any burst
  41          * length according to the BLEN programmed (by default all BLEN are
  42          * set).
  43          */
  44         for (i = 0; i < AXI_BLEN; i++) {
  45                 switch (axi->axi_blen[i]) {
  46                 case 256:
  47                         value |= DMA_AXI_BLEN256;
  48                         break;
  49                 case 128:
  50                         value |= DMA_AXI_BLEN128;
  51                         break;
  52                 case 64:
  53                         value |= DMA_AXI_BLEN64;
  54                         break;
  55                 case 32:
  56                         value |= DMA_AXI_BLEN32;
  57                         break;
  58                 case 16:
  59                         value |= DMA_AXI_BLEN16;
  60                         break;
  61                 case 8:
  62                         value |= DMA_AXI_BLEN8;
  63                         break;
  64                 case 4:
  65                         value |= DMA_AXI_BLEN4;
  66                         break;
  67                 }
  68         }
  69 
  70         writel(value, ioaddr + DMA_AXI_BUS_MODE);
  71 }
  72 
  73 static void dwmac1000_dma_init(void __iomem *ioaddr,
  74                                struct stmmac_dma_cfg *dma_cfg, int atds)
  75 {
  76         u32 value = readl(ioaddr + DMA_BUS_MODE);
  77         int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
  78         int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
  79 
  80         /*
  81          * Set the DMA PBL (Programmable Burst Length) mode.
  82          *
  83          * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
  84          * post 3.5 mode bit acts as 8*PBL.
  85          */
  86         if (dma_cfg->pblx8)
  87                 value |= DMA_BUS_MODE_MAXPBL;
  88         value |= DMA_BUS_MODE_USP;
  89         value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
  90         value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
  91         value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
  92 
  93         /* Set the Fixed burst mode */
  94         if (dma_cfg->fixed_burst)
  95                 value |= DMA_BUS_MODE_FB;
  96 
  97         /* Mixed Burst has no effect when fb is set */
  98         if (dma_cfg->mixed_burst)
  99                 value |= DMA_BUS_MODE_MB;
 100 
 101         if (atds)
 102                 value |= DMA_BUS_MODE_ATDS;
 103 
 104         if (dma_cfg->aal)
 105                 value |= DMA_BUS_MODE_AAL;
 106 
 107         writel(value, ioaddr + DMA_BUS_MODE);
 108 
 109         /* Mask interrupts by writing to CSR7 */
 110         writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
 111 }
 112 
 113 static void dwmac1000_dma_init_rx(void __iomem *ioaddr,
 114                                   struct stmmac_dma_cfg *dma_cfg,
 115                                   dma_addr_t dma_rx_phy, u32 chan)
 116 {
 117         /* RX descriptor base address list must be written into DMA CSR3 */
 118         writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR);
 119 }
 120 
 121 static void dwmac1000_dma_init_tx(void __iomem *ioaddr,
 122                                   struct stmmac_dma_cfg *dma_cfg,
 123                                   dma_addr_t dma_tx_phy, u32 chan)
 124 {
 125         /* TX descriptor base address list must be written into DMA CSR4 */
 126         writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR);
 127 }
 128 
 129 static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
 130 {
 131         csr6 &= ~DMA_CONTROL_RFA_MASK;
 132         csr6 &= ~DMA_CONTROL_RFD_MASK;
 133 
 134         /* Leave flow control disabled if receive fifo size is less than
 135          * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
 136          * and send XON when 2K less than full.
 137          */
 138         if (rxfifosz < 4096) {
 139                 csr6 &= ~DMA_CONTROL_EFC;
 140                 pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
 141                          rxfifosz);
 142         } else {
 143                 csr6 |= DMA_CONTROL_EFC;
 144                 csr6 |= RFA_FULL_MINUS_1K;
 145                 csr6 |= RFD_FULL_MINUS_2K;
 146         }
 147         return csr6;
 148 }
 149 
 150 static void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
 151                                             u32 channel, int fifosz, u8 qmode)
 152 {
 153         u32 csr6 = readl(ioaddr + DMA_CONTROL);
 154 
 155         if (mode == SF_DMA_MODE) {
 156                 pr_debug("GMAC: enable RX store and forward mode\n");
 157                 csr6 |= DMA_CONTROL_RSF;
 158         } else {
 159                 pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
 160                 csr6 &= ~DMA_CONTROL_RSF;
 161                 csr6 &= DMA_CONTROL_TC_RX_MASK;
 162                 if (mode <= 32)
 163                         csr6 |= DMA_CONTROL_RTC_32;
 164                 else if (mode <= 64)
 165                         csr6 |= DMA_CONTROL_RTC_64;
 166                 else if (mode <= 96)
 167                         csr6 |= DMA_CONTROL_RTC_96;
 168                 else
 169                         csr6 |= DMA_CONTROL_RTC_128;
 170         }
 171 
 172         /* Configure flow control based on rx fifo size */
 173         csr6 = dwmac1000_configure_fc(csr6, fifosz);
 174 
 175         writel(csr6, ioaddr + DMA_CONTROL);
 176 }
 177 
 178 static void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
 179                                             u32 channel, int fifosz, u8 qmode)
 180 {
 181         u32 csr6 = readl(ioaddr + DMA_CONTROL);
 182 
 183         if (mode == SF_DMA_MODE) {
 184                 pr_debug("GMAC: enable TX store and forward mode\n");
 185                 /* Transmit COE type 2 cannot be done in cut-through mode. */
 186                 csr6 |= DMA_CONTROL_TSF;
 187                 /* Operating on second frame increase the performance
 188                  * especially when transmit store-and-forward is used.
 189                  */
 190                 csr6 |= DMA_CONTROL_OSF;
 191         } else {
 192                 pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode);
 193                 csr6 &= ~DMA_CONTROL_TSF;
 194                 csr6 &= DMA_CONTROL_TC_TX_MASK;
 195                 /* Set the transmit threshold */
 196                 if (mode <= 32)
 197                         csr6 |= DMA_CONTROL_TTC_32;
 198                 else if (mode <= 64)
 199                         csr6 |= DMA_CONTROL_TTC_64;
 200                 else if (mode <= 128)
 201                         csr6 |= DMA_CONTROL_TTC_128;
 202                 else if (mode <= 192)
 203                         csr6 |= DMA_CONTROL_TTC_192;
 204                 else
 205                         csr6 |= DMA_CONTROL_TTC_256;
 206         }
 207 
 208         writel(csr6, ioaddr + DMA_CONTROL);
 209 }
 210 
 211 static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
 212 {
 213         int i;
 214 
 215         for (i = 0; i < NUM_DWMAC1000_DMA_REGS; i++)
 216                 if ((i < 12) || (i > 17))
 217                         reg_space[DMA_BUS_MODE / 4 + i] =
 218                                 readl(ioaddr + DMA_BUS_MODE + i * 4);
 219 }
 220 
 221 static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
 222                                      struct dma_features *dma_cap)
 223 {
 224         u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
 225 
 226         dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
 227         dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
 228         dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
 229         dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
 230         dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5;
 231         dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
 232         dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
 233         dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
 234         dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
 235         /* MMC */
 236         dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
 237         /* IEEE 1588-2002 */
 238         dma_cap->time_stamp =
 239             (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
 240         /* IEEE 1588-2008 */
 241         dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
 242         /* 802.3az - Energy-Efficient Ethernet (EEE) */
 243         dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
 244         dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
 245         /* TX and RX csum */
 246         dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
 247         dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
 248         dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
 249         dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
 250         /* TX and RX number of channels */
 251         dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
 252         dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
 253         /* Alternate (enhanced) DESC mode */
 254         dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
 255 }
 256 
 257 static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
 258                                   u32 number_chan)
 259 {
 260         writel(riwt, ioaddr + DMA_RX_WATCHDOG);
 261 }
 262 
 263 const struct stmmac_dma_ops dwmac1000_dma_ops = {
 264         .reset = dwmac_dma_reset,
 265         .init = dwmac1000_dma_init,
 266         .init_rx_chan = dwmac1000_dma_init_rx,
 267         .init_tx_chan = dwmac1000_dma_init_tx,
 268         .axi = dwmac1000_dma_axi,
 269         .dump_regs = dwmac1000_dump_dma_regs,
 270         .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
 271         .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
 272         .enable_dma_transmission = dwmac_enable_dma_transmission,
 273         .enable_dma_irq = dwmac_enable_dma_irq,
 274         .disable_dma_irq = dwmac_disable_dma_irq,
 275         .start_tx = dwmac_dma_start_tx,
 276         .stop_tx = dwmac_dma_stop_tx,
 277         .start_rx = dwmac_dma_start_rx,
 278         .stop_rx = dwmac_dma_stop_rx,
 279         .dma_interrupt = dwmac_dma_interrupt,
 280         .get_hw_feature = dwmac1000_get_hw_feature,
 281         .rx_watchdog = dwmac1000_rx_watchdog,
 282 };

/* [<][>][^][v][top][bottom][index][help] */