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