root/drivers/net/ethernet/altera/altera_msgdma.c

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

DEFINITIONS

This source file includes following definitions.
  1. msgdma_initialize
  2. msgdma_uninitialize
  3. msgdma_start_rxdma
  4. msgdma_reset
  5. msgdma_disable_rxirq
  6. msgdma_enable_rxirq
  7. msgdma_disable_txirq
  8. msgdma_enable_txirq
  9. msgdma_clear_rxirq
  10. msgdma_clear_txirq
  11. msgdma_tx_buffer
  12. msgdma_tx_completions
  13. msgdma_add_rx_desc
  14. msgdma_rx_status

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Altera TSE SGDMA and MSGDMA Linux driver
   3  * Copyright (C) 2014 Altera Corporation. All rights reserved
   4  */
   5 
   6 #include <linux/netdevice.h>
   7 #include "altera_utils.h"
   8 #include "altera_tse.h"
   9 #include "altera_msgdmahw.h"
  10 #include "altera_msgdma.h"
  11 
  12 /* No initialization work to do for MSGDMA */
  13 int msgdma_initialize(struct altera_tse_private *priv)
  14 {
  15         return 0;
  16 }
  17 
  18 void msgdma_uninitialize(struct altera_tse_private *priv)
  19 {
  20 }
  21 
  22 void msgdma_start_rxdma(struct altera_tse_private *priv)
  23 {
  24 }
  25 
  26 void msgdma_reset(struct altera_tse_private *priv)
  27 {
  28         int counter;
  29 
  30         /* Reset Rx mSGDMA */
  31         csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr,
  32                 msgdma_csroffs(status));
  33         csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr,
  34                 msgdma_csroffs(control));
  35 
  36         counter = 0;
  37         while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
  38                 if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status),
  39                                      MSGDMA_CSR_STAT_RESETTING))
  40                         break;
  41                 udelay(1);
  42         }
  43 
  44         if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
  45                 netif_warn(priv, drv, priv->dev,
  46                            "TSE Rx mSGDMA resetting bit never cleared!\n");
  47 
  48         /* clear all status bits */
  49         csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status));
  50 
  51         /* Reset Tx mSGDMA */
  52         csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr,
  53                 msgdma_csroffs(status));
  54 
  55         csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr,
  56                 msgdma_csroffs(control));
  57 
  58         counter = 0;
  59         while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
  60                 if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status),
  61                                      MSGDMA_CSR_STAT_RESETTING))
  62                         break;
  63                 udelay(1);
  64         }
  65 
  66         if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
  67                 netif_warn(priv, drv, priv->dev,
  68                            "TSE Tx mSGDMA resetting bit never cleared!\n");
  69 
  70         /* clear all status bits */
  71         csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status));
  72 }
  73 
  74 void msgdma_disable_rxirq(struct altera_tse_private *priv)
  75 {
  76         tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control),
  77                       MSGDMA_CSR_CTL_GLOBAL_INTR);
  78 }
  79 
  80 void msgdma_enable_rxirq(struct altera_tse_private *priv)
  81 {
  82         tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control),
  83                     MSGDMA_CSR_CTL_GLOBAL_INTR);
  84 }
  85 
  86 void msgdma_disable_txirq(struct altera_tse_private *priv)
  87 {
  88         tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control),
  89                       MSGDMA_CSR_CTL_GLOBAL_INTR);
  90 }
  91 
  92 void msgdma_enable_txirq(struct altera_tse_private *priv)
  93 {
  94         tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control),
  95                     MSGDMA_CSR_CTL_GLOBAL_INTR);
  96 }
  97 
  98 void msgdma_clear_rxirq(struct altera_tse_private *priv)
  99 {
 100         csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status));
 101 }
 102 
 103 void msgdma_clear_txirq(struct altera_tse_private *priv)
 104 {
 105         csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(status));
 106 }
 107 
 108 /* return 0 to indicate transmit is pending */
 109 int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 110 {
 111         csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc,
 112                 msgdma_descroffs(read_addr_lo));
 113         csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc,
 114                 msgdma_descroffs(read_addr_hi));
 115         csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo));
 116         csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi));
 117         csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len));
 118         csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num));
 119         csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc,
 120                 msgdma_descroffs(stride));
 121         csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc,
 122                 msgdma_descroffs(control));
 123         return 0;
 124 }
 125 
 126 u32 msgdma_tx_completions(struct altera_tse_private *priv)
 127 {
 128         u32 ready = 0;
 129         u32 inuse;
 130         u32 status;
 131 
 132         /* Get number of sent descriptors */
 133         inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level))
 134                         & 0xffff;
 135 
 136         if (inuse) { /* Tx FIFO is not empty */
 137                 ready = max_t(int,
 138                               priv->tx_prod - priv->tx_cons - inuse - 1, 0);
 139         } else {
 140                 /* Check for buffered last packet */
 141                 status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status));
 142                 if (status & MSGDMA_CSR_STAT_BUSY)
 143                         ready = priv->tx_prod - priv->tx_cons - 1;
 144                 else
 145                         ready = priv->tx_prod - priv->tx_cons;
 146         }
 147         return ready;
 148 }
 149 
 150 /* Put buffer to the mSGDMA RX FIFO
 151  */
 152 void msgdma_add_rx_desc(struct altera_tse_private *priv,
 153                         struct tse_buffer *rxbuffer)
 154 {
 155         u32 len = priv->rx_dma_buf_sz;
 156         dma_addr_t dma_addr = rxbuffer->dma_addr;
 157         u32 control = (MSGDMA_DESC_CTL_END_ON_EOP
 158                         | MSGDMA_DESC_CTL_END_ON_LEN
 159                         | MSGDMA_DESC_CTL_TR_COMP_IRQ
 160                         | MSGDMA_DESC_CTL_EARLY_IRQ
 161                         | MSGDMA_DESC_CTL_TR_ERR_IRQ
 162                         | MSGDMA_DESC_CTL_GO);
 163 
 164         csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo));
 165         csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi));
 166         csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc,
 167                 msgdma_descroffs(write_addr_lo));
 168         csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc,
 169                 msgdma_descroffs(write_addr_hi));
 170         csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len));
 171         csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num));
 172         csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride));
 173         csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control));
 174 }
 175 
 176 /* status is returned on upper 16 bits,
 177  * length is returned in lower 16 bits
 178  */
 179 u32 msgdma_rx_status(struct altera_tse_private *priv)
 180 {
 181         u32 rxstatus = 0;
 182         u32 pktlength;
 183         u32 pktstatus;
 184 
 185         if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level))
 186             & 0xffff) {
 187                 pktlength = csrrd32(priv->rx_dma_resp,
 188                                     msgdma_respoffs(bytes_transferred));
 189                 pktstatus = csrrd32(priv->rx_dma_resp,
 190                                     msgdma_respoffs(status));
 191                 rxstatus = pktstatus;
 192                 rxstatus = rxstatus << 16;
 193                 rxstatus |= (pktlength & 0xffff);
 194         }
 195         return rxstatus;
 196 }

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