197 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Altera TSE SGDMA and MSGDMA Linux driver3 * Copyright (C) 2014 Altera Corporation. All rights reserved4 */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 */13int msgdma_initialize(struct altera_tse_private *priv)14{15 return 0;16}17 18void msgdma_uninitialize(struct altera_tse_private *priv)19{20}21 22void msgdma_start_rxdma(struct altera_tse_private *priv)23{24}25 26void 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 74void 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 80void 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 86void 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 92void 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 98void msgdma_clear_rxirq(struct altera_tse_private *priv)99{100 csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status));101}102 103void 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 */109int 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 126u32 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 else145 ready = priv->tx_prod - priv->tx_cons;146 }147 return ready;148}149 150/* Put buffer to the mSGDMA RX FIFO151 */152void 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_EOP158 | MSGDMA_DESC_CTL_END_ON_LEN159 | MSGDMA_DESC_CTL_TR_COMP_IRQ160 | MSGDMA_DESC_CTL_EARLY_IRQ161 | MSGDMA_DESC_CTL_TR_ERR_IRQ162 | 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 bits178 */179u32 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}197